use faf_replay_parser::faf::extract_scfa;
use faf_replay_parser::ReplayResult;

use std::fs::File;
use std::io::{self, BufReader};
use std::path::PathBuf;
use structopt::StructOpt;

#[derive(StructOpt)]
pub struct UnpackArgs {
    /// Path to the replay
    #[structopt(parse(from_os_str))]
    replay: PathBuf,
    /// Name of unpacked replay file
    #[structopt(parse(from_os_str), short = "o", long = "output")]
    output: Option<PathBuf>,
    /// Overwrite the output file if it already exists
    #[structopt(short = "f", long = "force")]
    force: bool,
}

pub fn unpack_fafreplay(args: &UnpackArgs) -> ReplayResult<()> {
    let output = args.output.as_ref().map(|o| o.clone()).unwrap_or_else(|| {
        let mut output = args.replay.clone();
        output.set_extension("scfareplay");
        output
    });

    if !args.force && args.replay.extension().and_then(|s| s.to_str()) == Some("scfareplay") {
        println!(
            "\nError: {} is already an unpacked file!",
            args.replay.to_string_lossy()
        );
        return Ok(());
    }

    let mut reader = match File::open(&args.replay) {
        Ok(f) => BufReader::new(f),
        Err(e) => {
            println!("Error opening file: {}", e);
            std::process::exit(1);
        }
    };

    if !args.force && output.exists() {
        println!("\nError: {} already exists!", output.to_string_lossy());
        return Ok(());
    }

    println!("Extracting to {}", output.display());
    let mut buf = Vec::new();
    extract_scfa(&mut reader, &mut buf)?;

    let mut out = File::create(&output)?;
    let n = io::copy(&mut buf.as_slice(), &mut out)?;

    out.sync_all()?;

    println!("Wrote {} bytes", n);

    Ok(())
}
