use std::{
    fmt::Arguments,
    io::Read,
    process::{Command, Stdio},
};

fn run(name: Arguments, cmd: &mut Command) {
    let mut proc = cmd
        .current_dir("src/test_roms")
        .stdout(Stdio::piped())
        .stderr(Stdio::piped())
        .spawn()
        .expect("Failed to start process");
    let rc = proc.wait();
    if rc.is_err() || rc.is_ok_and(|s| !s.success()) {
        let mut stdout = String::new();
        proc.stdout
            .unwrap()
            .read_to_string(&mut stdout)
            .expect("Failed to read stdout");
        let mut stderr = String::new();
        proc.stderr
            .unwrap()
            .read_to_string(&mut stderr)
            .expect("Failed to read stderr");
        panic!("Failed to run {name}\n=== STDOUT ===\n{stdout}\n=== STDERR ===\n{stderr}");
    }
}

fn main() {
    println!("cargo::rerun-if-changed=src/test_roms/");
    println!("cargo::rerun-if-changed=build.rs");

    let name = format!(
        "{}/test-roms",
        std::env::var("OUT_DIR").expect("Need OUT_DIR env var")
    );
    std::fs::create_dir_all(&name).expect("Failed to create rom output dir");
    println!("cargo::rustc-env=ROM_DIR={name}");

    for file in std::fs::read_dir("./src/test_roms").expect("Failed to read directory") {
        let file = file.expect("test");
        let file_name = file.file_name();
        let file_name = file_name.to_str().unwrap();
        // if let Some(file_name) = file_name.strip_suffix(".asm") {
        //     run(
        //         format_args!("asm6f {file_name}"),
        //         Command::new("./asm6f")
        //             .arg(file.file_name())
        //             .arg(format!("{name}/{file_name}.nes")),
        //     );
        // } else
        if let Some(file_name) = file_name.strip_suffix(".s") {
            run(
                format_args!("ca65 {file_name}"),
                Command::new("../../cc65/bin/ca65")
                    .arg("-I")
                    .arg("common")
                    .arg("-o")
                    .arg(format!("{name}/{file_name}.o"))
                    .arg(file.file_name()),
            );
            run(
                format_args!("ld65 {file_name}"),
                Command::new("../../cc65/bin/ld65")
                    .arg("-C")
                    .arg("nes.cfg")
                    .arg("-o")
                    .arg(format!("{name}/{file_name}.nes"))
                    .arg(format!("{name}/{file_name}.o"))
            );
        }
    }
}
