extern crate faf_replay_parser;
extern crate rayon;
extern crate regex;
extern crate structopt;

mod commands;
mod info;
mod unpack;

use commands::{print_commands, CommandsArgs};
use info::{print_info, InfoArgs};
use unpack::{unpack_fafreplay, UnpackArgs};

use std::fs::File;
use std::io::{BufReader, Read};
use std::path::Path;
use structopt::StructOpt;

use faf_replay_parser::faf::extract_scfa;
use faf_replay_parser::scfa::Replay;
use faf_replay_parser::{ReplayReadError, ReplayResult};

const FACTION: [&str; 4] = ["UEF", "Aeon", "Cybran", "Seraphim"];
const MISSING: &str = "[MISSING]";

#[derive(StructOpt)]
#[structopt(
    name = "FAF Replay Parser",
    about = "Parses Supreme Commander Forged Alliance replay files"
)]
struct CliArgs {
    #[structopt(subcommand)]
    cmd: Command,
}

#[derive(StructOpt)]
enum Command {
    /// Shows an overview of the replay contents
    #[structopt(name = "info")]
    Info(InfoArgs),
    /// Displays the parsed command data directly.
    ///
    /// By default this only shows the most common commands.
    #[structopt(name = "commands")]
    Commands(CommandsArgs),
    /// Converts a .fafreplay into a .scfareplay
    #[structopt(name = "unpack")]
    Unpack(UnpackArgs),
}

fn main() {
    let args = CliArgs::from_args();

    use Command::*;
    if let Err(e) = match args.cmd {
        Info(args) => print_info(&args),
        Commands(args) => print_commands(&args),
        Unpack(args) => unpack_fafreplay(&args),
    } {
        println!("Error parsing replay: {:?}", e);
        std::process::exit(2);
    }
}

fn load_replay(path: &Path) -> ReplayResult<Vec<u8>> {
    println!("processing replay: {}", path.to_string_lossy());

    let mut reader = BufReader::new(File::open(path)?);
    // TODO: Determine file type from first byte.
    let file_type = path.extension().and_then(|s| s.to_str()).unwrap_or("");
    match file_type {
        "scfareplay" => {
            let mut result = Vec::new();
            reader.read_to_end(&mut result)?;
            Ok(result)
        }
        "fafreplay" => {
            let mut result = Vec::new();
            reader.read_to_end(&mut result)?;
            let mut extracted = Vec::with_capacity(result.len());
            extract_scfa(&mut result.as_slice(), &mut extracted)?;
            Ok(extracted)
        }
        _ => Err(ReplayReadError::IO(std::io::Error::new(
            std::io::ErrorKind::InvalidData,
            "unknown file type",
        ))),
    }
}

fn print_replay_version(replay: &Replay) {
    println!(
        "{} {}",
        replay.header.scfa_version, replay.header.replay_version
    );
}
