//! This binary generates a Rust source file containing a match switch for decoding all 6502 opcodes.
//!
//! When built with the `decode_logic` feature, it iterates over all possible opcodes (0x00 to 0xFF),
//! decodes each using the `cpu6502::decode` function, and writes the resulting match arms to
//! `src/instr/opcodes/decode_switch.rs`. The generated file is formatted with `rustfmt`.

use cpu6502::decode;

const COMMENT_HEADER: &str = "// THIS FILE HAS BEEN GENERATED BY gen_decode_switch";

/// Generates the opcode decode switch file for all 6502 opcodes.
///
/// This function creates the output directory if needed, writes the generated
/// match arms to `src/instr/opcodes/decode_switch.rs`, and formats the file.
///
/// Note: Requires the `decode_logic` feature to be enabled for proper operation.
pub fn main() {
    use std::fs;
    use std::io::Write;

    let mut switch_options = String::new();

    // Iterate over all possible opcodes (0x00 to 0xFF)
    for opcode in 0..=u8::MAX {
        let decoded = decode(opcode);

        // Format each match arm as `0x?? => DecodedInstruction,`
        switch_options.push_str(&format!("{opcode:#04X} => {decoded:?},\n"));
    }

    // Ensure the output directory exists
    fs::create_dir_all("src/instr/opcodes").expect("Could not create directory");

    // Create and write the generated file
    let mut code_file =
        fs::File::create("src/instr/opcodes/decode_switch.rs").expect("Could not create file");
    write!(
        code_file,
        include_str!("decode_switch.rs.txt"),
        COMMENT_HEADER, switch_options
    )
    .expect("Could not write file");

    // Format the generated file using rustfmt
    std::process::Command::new("rustfmt")
        .arg("src/instr/opcodes/decode_switch.rs")
        .output()
        .expect("Failed to execute rustfmt");
}
