extends Node

@onready var app_name = ProjectSettings.get_setting("application/config/name")

func show_help():
	print(
		"Usage:\n\n",
		"./Pigment <command> <args...>\n\n",
		"Commands:\n\n",
		" help\n\n",
		"  | Shows this help text.\n\n",
		" apply --shader PATH --input PATH --output PATH\n\n",
		"  | Applies a shader file.\n\n",
		"    --shader PATH  The path to the shader\n",
		"    --input  PATH  The path to the image\n",
		"                   Passing a folder activates batch mode\n",
		"    --output PATH  Where to write the resulting image to\n",
		"                   In batch mode, this must be a folder\n")

func parse_custom_cmdline(args: PackedStringArray):
	var kwargs: Dictionary = {"--shader": null, "--output": null, "--input": null}
	var args_len = args.size()
	var i = 0
	while i < args_len:
		var a = args[i]
		if a in kwargs && args_len > i+1:
			i += 1
			kwargs[a] = args[i]
		i += 1
	return kwargs

func cli_handle_errors(errors: Array) -> int:
	# returns number of errors
	var n_errors = errors.size()
	if n_errors > 0:
		print("One or more errors occurred.")
		for e in errors:
			printerr(e)
	return n_errors

func cli(args: PackedStringArray):
	print(
		"~ Pigment CLI ~\n",
		"-=============-\n")
	if "help" in args:
		show_help()
		get_tree().quit(1)
		return
	var kwargs: Dictionary = parse_custom_cmdline(args)
	if kwargs["--shader"] == null or kwargs["--output"] == null or kwargs["--input"] == null:
		show_help()
		get_tree().quit(1)
		return
	var batch_mode = false
	var load_image_dir: DirAccess
	load_image_dir = DirAccess.open(kwargs["--input"])
	if load_image_dir != null:
		# batch mode
		if DirAccess.open(kwargs["--output"]) == null:
			printerr("If --input is a directory, --output has to be one too.\n")
			show_help()
			get_tree().quit(1)
			return
		else:
			batch_mode = true
	#
	Filesystem.shader_path = kwargs["--shader"]
	#
	if batch_mode:
		var in_dir_path = load_image_dir.get_current_dir()
		var out_dir_path: String = kwargs["--output"].rstrip("/")
		for f in load_image_dir.get_files():
			var supported = false
			for e in Filesystem.SUPPORTED_INPUT_EXT:
				if f.ends_with(e):
					supported = true
					break
			if supported:
				f = in_dir_path + "/" + f
				print(f)
				var errors = await $Compositor.update(f)
				if cli_handle_errors(errors) == 0:
					var filename = out_dir_path + "/" + f.substr(f.rfind("/"), -1)
					Filesystem.save_result(filename)
				else:
					get_tree().quit(1)
					return
		get_tree().quit(0)
	else:
		var errors = []
		Filesystem.input_image_path = kwargs["--input"]
		errors = await $Compositor.update()
		if cli_handle_errors(errors) == 0:
			Filesystem.save_result(kwargs["--output"])
			get_tree().quit(0)
		else:
			get_tree().quit(1)

func prepare_gui():
	update_title()

func _ready():
	var args = OS.get_cmdline_args()
	if len(args) > 0 and args[0] in ["apply", "help"]:
		# use the commandline interface
		cli(args)
	else:
		prepare_gui()

func update_title(current_file: String = ""):
	if current_file == "":
		get_window().title = app_name + " - Viewer"
	else:
		get_window().title = current_file + " - " + app_name + " - Viewer"
