extends SceneTree

var failures: Array[String] = []


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


func _run() -> void:
	var test_directory := "user://save_slot_test_%s" % Time.get_ticks_usec()
	var store := SaveSlotStore.new(test_directory)
	var manager: Node = load("res://simulation/SimulationManager.gd").new()
	manager.debug_logs = false
	root.add_child(manager)
	manager.set_process(false)

	for step in 8:
		manager.simulate_tick()
	var saved_checksum: String = manager.get_state_checksum()
	_check(store.save(manager), "A valid simulation should save atomically")
	_check(store.has_slot(), "The validated quicksave should be discoverable")

	for step in 5:
		manager.simulate_tick()
	_check(
		manager.get_state_checksum() != saved_checksum,
		"The scenario should change after the save point"
	)
	_check(store.load_into(manager), "A valid quicksave should load")
	_check(
		manager.get_state_checksum() == saved_checksum,
		"Loading should restore the exact saved simulation"
	)

	var final_path := store.get_slot_path()
	var backup_path := final_path + ".bak"
	_check(
		DirAccess.rename_absolute(final_path, backup_path) == OK,
		"Test should reproduce the atomic replacement recovery window"
	)
	_check(
		store.load_into(manager),
		"A preserved previous save should recover an interrupted replacement"
	)
	_check(
		DirAccess.rename_absolute(backup_path, final_path) == OK,
		"Test should restore the primary save path"
	)

	var unchanged_checksum: String = manager.get_state_checksum()
	var file := FileAccess.open(final_path, FileAccess.WRITE)
	file.store_string('{"schema":"broken"}')
	file.close()
	_check(not store.load_into(manager), "Invalid save data should be rejected")
	_check(
		manager.get_state_checksum() == unchanged_checksum,
		"A rejected save must not partially mutate the simulation"
	)
	_check(not store.save(manager, "../escape"), "Slot names must not escape the save directory")

	store.delete_slot()
	DirAccess.remove_absolute(ProjectSettings.globalize_path(test_directory))
	if failures.is_empty():
		print("[TEST] Save-slot persistence 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)
