// Copyright Marcus Del Favero 2025
// Licensed under the GNU AGPLv3 with an exception, see `README.md` for details
use std::process::{Command, Stdio};

use png::ColorType;

use super::image::Image;

fn run(args: &[&str]) {
	let success = Command::new("inkscape")
		.args(args)
		.stderr(Stdio::null())
		.status()
		.expect("Failed to execute Inkscape")
		.success();

	assert!(success, "Execution of Inkscape failed");
}

pub fn gen_image(input: &str, output: &str, width: usize, height: usize, format: ColorType) {
	let args = [
		input, "-o", output,
		"-w", &width.to_string(), "-h", &height.to_string(),
		&format!("--export-png-color-mode={}_8", match format {
			ColorType::Rgba => "RGBA",
			ColorType::Rgb => "RGB",
			_ => panic!("Invalid format"),
		}),
		"-y", "0",
		"--actions=select-all: layers; selection-unhide", // Unhides all top-level layers
	];

	run(&args);
}

fn gen_layer_grey(input: &str, output: &str, layer: &str, width: usize, height: usize) {
	let args = [
		"-i", layer, "-jC", input,
		"-o", output,
		"-w", &width.to_string(), "-h", &height.to_string(), "--export-png-color-mode=Gray_8", "-b", "#000000", // Sets the size, 8-bit greyscale and uses a black background rather than an alpha channel
		"--actions=select-all: layers; selection-unhide", // Unhides all top-level layers so I can have the alpha layer hidden and the image still exported. For whatever reason (to my advantage), not everything is shown so I can hide some stuff I don't want to see in the output (for testing) but the alpha channel will always be visible.
	];

	run(&args);
}

pub fn gen_grey_layers(name: &str, input: &str, layers: &[&str], width: usize, height: usize) -> Image {
	let layers = layers.iter().map(|layer| {
		let path = format!("/tmp/{name}_{layer}.png");
		gen_layer_grey(input, &path, layer, width, height);

		let image = Image::load(&path, ColorType::Grayscale);
		assert!(width == image.width && height == image.height, "Output image isn't the expected dimensions");
		image
	}).collect::<Vec<_>>();

	let channels = layers.len();
	let mut output = Image::new(width, height, channels);
	for i in 0..width * height {
		for (j, layer) in layers.iter().enumerate() {
			output.pixels[i * channels + j] = layer.pixels[i];
		}
	}
	output
}
