extends SceneTree

const DEFAULT_EXTRACTED_DIR := "res://data/extracted"
const DEFAULT_MAP := "Azeroth"


func _initialize() -> void:
	var args := OS.get_cmdline_user_args()
	var extracted_dir := _arg(args, "--extracted", DEFAULT_EXTRACTED_DIR)
	var map_name := _arg(args, "--map", DEFAULT_MAP)
	var kind := _arg(args, "--kind", "wmo").to_lower()
	var path_contains := _arg(args, "--path-contains", "").to_lower()
	var limit := int(_arg(args, "--limit", "25"))

	if not ClassDB.class_exists("ADTLoader"):
		push_error("ADTLoader is not registered. Rebuild the native GDExtension first.")
		quit(1)
		return

	var map_dir := ProjectSettings.globalize_path(
		extracted_dir.path_join("World/Maps").path_join(map_name)
	)
	var dir := DirAccess.open(map_dir)
	if dir == null:
		push_error("Cannot open map directory: %s" % map_dir)
		quit(1)
		return

	var loader = ClassDB.instantiate("ADTLoader")
	var files := dir.get_files()
	files.sort()
	var printed := 0
	for file_name in files:
		if printed >= limit:
			break
		if not file_name.to_lower().ends_with(".adt"):
			continue
		if not file_name.begins_with("%s_" % map_name):
			continue
		var data: Dictionary = loader.call("load_adt", map_dir.path_join(file_name))
		var names: PackedStringArray = data.get("%s_names" % kind, PackedStringArray())
		var placements: Array = data.get("%s_placements" % kind, [])
		for placement_variant in placements:
			if printed >= limit:
				break
			if not (placement_variant is Dictionary):
				continue
			var placement: Dictionary = placement_variant
			var name_id := int(placement.get("name_id", -1))
			if name_id < 0 or name_id >= names.size():
				continue
			var rel_path := String(names[name_id]).replace("\\", "/")
			if not path_contains.is_empty() and not rel_path.to_lower().contains(path_contains):
				continue
			var rot: Vector3 = placement.get("rot", Vector3.ZERO)
			print("ADT_%s tile=%s uid=%d path=%s pos=%s rot_deg=%s scale=%.3f" % [
				kind.to_upper(),
				_tile_from_adt_filename(file_name),
				int(placement.get("unique_id", -1)),
				rel_path,
				placement.get("pos", Vector3.ZERO),
				Vector3(rad_to_deg(rot.x), rad_to_deg(rot.y), rad_to_deg(rot.z)),
				float(placement.get("scale", 1.0)),
			])
			printed += 1
	quit(0)


func _tile_from_adt_filename(file_name: String) -> Vector2i:
	var parts := file_name.get_basename().split("_")
	if parts.size() < 3:
		return Vector2i(-1, -1)
	return Vector2i(int(parts[parts.size() - 2]), int(parts[parts.size() - 1]))


func _arg(args: PackedStringArray, name: String, default_value: String) -> String:
	var idx := args.find(name)
	if idx >= 0 and idx + 1 < args.size():
		return args[idx + 1]
	return default_value
