use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use std::time::Instant;

use anyhow::ensure;
use clap::Parser;

use enemize::{asar, rom::RomData};

/// Randomizes enemy placements in The Legend of Zelda: A Link to the Past for the Super Nintendo
/// Entertainment System
#[derive(Debug, Parser)]
#[clap(author, version, about)]
struct Args {
    /// path to the base rom file
    rom: PathBuf,
    /// seed number
    #[clap(short, long)]
    seed: Option<u32>,
    /// path to the enemizerOptions.json
    #[clap(short, long)]
    enemizer: PathBuf,
    /// path to the intended output file
    output: PathBuf,
    /// operate in binary mode (takes already randomized SFC and applies enemizer directly to ROM)
    #[clap(long)]
    binary: bool,
}

fn main() -> anyhow::Result<()> {
    let args = Args::parse();

    let stopwatch = Instant::now();

    let options = serde_json::from_reader(File::open(args.enemizer)?)?;
    let symbols = load_symbols(&args.rom)?;

    let mut raw_data = vec![];
    let mut rom_file = File::open(args.rom)?;
    rom_file.read_to_end(&mut raw_data)?;

    raw_data.resize(2 * 1024 * 1024, 0);

    let mut rom_data = RomData::new(symbols, raw_data);
    ensure!(!rom_data.is_enemizer(), "It appears that the provided base ROM is already enemized. Please ensure you are using an original game ROM.");

    let seed = args.seed.unwrap_or_else(|| rand::random());

    //let randomized_rom = randomize_rom(seed, raw_data, options);

    if args.binary {

    } else {

    }

    println!("Seed generated in: {}ms", stopwatch.elapsed().as_millis());

    Ok(())
}

fn load_symbols(rom: &Path) -> anyhow::Result<asar::Symbols> {
    let sym_path = rom.with_extension("sym");

    if let Err(_) = std::fs::metadata(&sym_path) {
        let status = std::process::Command::new("asar")
        .arg("--no-title-check")
        .arg("--fix-checksum=off")
        .arg("--symbols=wla")
        .arg("-Iassembly/src")
        .arg("assembly/src/main.asm")
        .arg(rom)
        .status()?;

        ensure!(status.success(), "could not generate symbols");
    }

    asar::load_symbols(sym_path.as_path())
}