use std::{path::PathBuf, process::ExitCode};

fn main() -> ExitCode {
    let mut args = std::env::args().skip(1);
    let Some(input) = args.next().map(PathBuf::from) else {
        eprintln!("Usage: track-export <input.track> [output.wav|output.mp3]");
        return ExitCode::FAILURE;
    };
    let output = args
        .next()
        .map_or_else(|| input.with_extension("wav"), PathBuf::from);

    let format = match output.extension().and_then(|extension| extension.to_str()) {
        Some("wav") => "wav",
        Some("mp3") => "mp3",
        Some(_) => {
            eprintln!("Unsupported output format; use .wav or .mp3");
            return ExitCode::FAILURE;
        }
        None => {
            eprintln!("Output file must have an extension (.wav or .mp3)");
            return ExitCode::FAILURE;
        }
    };

    let source = match std::fs::read_to_string(&input) {
        Ok(source) => source,
        Err(error) => {
            eprintln!("Reading {input}: {error}", input = input.display());
            return ExitCode::FAILURE;
        }
    };
    let mut song = match game_audio::track::parse(&source) {
        Ok(song) => song,
        Err(error) => {
            eprintln!("Parsing {input}: {error}", input = input.display());
            return ExitCode::FAILURE;
        }
    };
    if let Err(error) = game_audio::track::resolve_imports(
        &mut song,
        input.parent(),
        game_audio::track::Refresh::Cached,
    ) {
        eprintln!(
            "Resolving imports for {input}: {error}",
            input = input.display()
        );
        return ExitCode::FAILURE;
    }

    let result = match format {
        "wav" => game_audio::track::export_wav(&song, input.parent(), &output),
        "mp3" => game_audio::track::export_mp3(&song, input.parent(), &output),
        _ => unreachable!(),
    };
    match result {
        Ok(()) => {
            eprintln!(
                "Exported {input} → {output}",
                input = input.display(),
                output = output.display()
            );
            ExitCode::SUCCESS
        }
        Err(error) => {
            eprintln!("Exporting {output}: {error}", output = output.display());
            ExitCode::FAILURE
        }
    }
}
