use std::env;
use std::error::Error;
use std::path::PathBuf;

use walkdir::WalkDir;
use wow_mpq::{ArchiveBuilder, FormatVersion, ListfileOption};
use wow_mpq::compression::flags;

fn main() -> Result<(), Box<dyn Error>> {
    // Read arguments
    let args: Vec<String> = env::args().collect();

    if args.len() != 3 {
        eprintln!("Usage: mpq-builder <input_dir> <output.mpq>");
        std::process::exit(1);
    }

    let input_dir = PathBuf::from(&args[1]);
    let output_file = &args[2];

    if !input_dir.exists() {
        return Err("Input directory does not exist".into());
    }

    // Normalize base path (IMPORTANT for Windows)
    let base = input_dir.canonicalize()?;

    println!("Input directory: {}", base.display());
    println!("Output file: {}", output_file);

    // Configure MPQ builder
    let mut builder = ArchiveBuilder::new()
        .version(FormatVersion::V2)
        .block_size(7) // 64KB sectors
        .default_compression(flags::ZLIB)
        .listfile_option(ListfileOption::Generate);

    // Walk directory
    for entry in WalkDir::new(&base)
        .into_iter()
        .filter_map(|e| e.ok())
        .filter(|e| e.file_type().is_file())
    {
        // Canonicalize each file path (fixes StripPrefixError)
        let full_path = entry.path().canonicalize()?;

        // Safely compute relative path
        let rel_path = match full_path.strip_prefix(&base) {
            Ok(p) => p,
            Err(_) => {
                eprintln!("Skipping (prefix mismatch): {}", full_path.display());
                continue;
            }
        };

        // Convert to MPQ-style path (forward slashes!)
        let archive_path = rel_path
            .to_string_lossy()
            .replace("\\", "/");

        println!("Adding: {}", archive_path);

        builder = builder.add_file(&full_path, &archive_path);
    }

    // Build archive
    builder.build(output_file)?;

    println!("✅ MPQ archive created: {}", output_file);

    Ok(())
}