use std::{path::PathBuf, time::Instant};

use nes_emu::{Break, NES};
use tracing_subscriber::EnvFilter;
use clap::Parser;

extern crate nes_emu;

#[derive(Parser)]
#[command(version, about)]
struct Args {
    file: PathBuf,
    #[arg(short, long)]
    frames: Option<usize>,
}

fn main() -> Result<(), anyhow::Error> {
    tracing_subscriber::fmt()
        .with_env_filter(EnvFilter::from_default_env())
        .init();
    let args = Args::parse();

    if let Some(frames) = args.frames {
        println!("Running {frames} frames of {} as fast as possible", args.file.display());
    } else {
        println!("Running {} as fast as possible", args.file.display());
    }
    let mut n = NES::load_nes_file(args.file).unwrap();
    n.reset();

    let start = Instant::now();
    let mut cur = 0;
    loop {
        while !n.halted() && !n.run_one_clock_cycle(&Break::default()).ppu_frame {
        }
        n.apu_mut().reset_frame_samples();
        cur += 1;
        if args.frames.is_some_and(|f| f < cur) {
            let time = start.elapsed();
            println!("Completed {} in {}s", cur, time.as_secs_f64());
            println!("~= {} fps", cur as f64 / time.as_secs_f64());
            break Ok(());
        }
        // TODO: update currently held button in controller
    }
    // Ok(())
}
