extends SceneTree

var main_scene: Node
var failures: Array[String] = []


func _initialize() -> void:
	call_deferred("_run")


func _run() -> void:
	main_scene = load("res://main.tscn").instantiate()
	root.add_child(main_scene)
	await process_frame
	await physics_frame

	var simulation_manager := main_scene.get_node("SimulationManager")
	var player := main_scene.get_node("Player")
	var bush := (
		main_scene.get_node("JajceWorld/WorldObjects/ResourceNodes/BerryBush_01") as ResourceNode
	)
	var tree := main_scene.get_node("JajceWorld/WorldObjects/ResourceNodes/Tree_01") as ResourceNode
	simulation_manager.set_process(false)

	var bush_state: ResourceStateRecord = simulation_manager.get_resource_state(bush.node_id)
	var tree_state: ResourceStateRecord = simulation_manager.get_resource_state(tree.node_id)
	bush_state.set_amount_remaining(1.0)
	_check(
		simulation_manager.reserve_resource(bush.node_id, 999),
		"Player contention setup should reserve the bush"
	)
	player.global_position = bush.interaction_point.global_position
	var food_before: float = simulation_manager.village.food
	player.try_interact()

	_check(
		is_equal_approx(bush_state.get_amount_remaining(), 0.0),
		"Player should deplete the nearby bush"
	)
	_check(
		is_equal_approx(simulation_manager.village.food, food_before + 1.0),
		"Village should receive exactly the bush's remaining food"
	)
	_check(bush_state.get_reserved_by() == -1, "Depletion should release the NPC reservation")

	player.global_position = tree.interaction_point.global_position
	var wood_before: float = simulation_manager.village.wood
	var tree_before := tree_state.get_amount_remaining()
	player.try_interact()

	_check(
		is_equal_approx(tree_state.get_amount_remaining(), tree_before - tree.yield_per_action),
		"Player should extract the tree's configured yield"
	)
	_check(
		is_equal_approx(simulation_manager.village.wood, wood_before + tree.yield_per_action),
		"Village should receive exactly the extracted wood"
	)

	if failures.is_empty():
		print("[TEST] ResourceNode player parity passed")
		quit(0)
		return

	for failure in failures:
		push_error("[TEST] " + failure)
	quit(1)


func _check(condition: bool, message: String) -> void:
	if not condition:
		failures.append(message)
