chdlady 0.1.0

High-level facade API for reading and creating CHD files
use std::fs::File;
use std::path::{Path, PathBuf};
use std::time::Instant;

use chdlady::core::ChdFile;
use chdlady::disc::{extract_cd, extract_raw};

fn get_ref_dir() -> PathBuf {
    std::env::var("CHDLADY_TEST_REF_DIR")
        .map(PathBuf::from)
        .unwrap_or_else(|_| PathBuf::from("reference_chds"))
}

fn main() {
    println!("=== CHDLADY SPEED AND INTEGRITY COMPARISON ===");
    let ref_dir = get_ref_dir();

    // 1. HD ZLIB (64 MB)
    let zlib_path = ref_dir.join("hd_zlib.chd");
    if zlib_path.exists() {
        let f = File::open(&zlib_path).unwrap();
        let mut chd = ChdFile::open(f).unwrap();
        let mut out = File::create("/tmp/bench_chdlady_zlib.raw").unwrap();
        let start = Instant::now();
        let bytes = extract_raw(&mut chd, &mut out, None, None, None, None).unwrap();
        let elapsed = start.elapsed();
        let mb = (bytes as f64) / (1024.0 * 1024.0);
        let mbs = mb / elapsed.as_secs_f64();
        println!(
            "HD ZLIB extract_raw: {:.2} MB in {:.3}s ({:.2} MB/s)",
            mb,
            elapsed.as_secs_f64(),
            mbs
        );
    }

    // 2. HD NONE (64 MB uncompressed with zero hunks)
    let none_path = ref_dir.join("hd_none.chd");
    if none_path.exists() {
        let f = File::open(&none_path).unwrap();
        let mut chd = ChdFile::open(f).unwrap();
        let mut out = File::create("/tmp/bench_chdlady_none.raw").unwrap();
        let start = Instant::now();
        let bytes = extract_raw(&mut chd, &mut out, None, None, None, None).unwrap();
        let elapsed = start.elapsed();
        let mb = (bytes as f64) / (1024.0 * 1024.0);
        let mbs = mb / elapsed.as_secs_f64();
        println!(
            "HD NONE extract_raw: {:.2} MB in {:.3}s ({:.2} MB/s)",
            mb,
            elapsed.as_secs_f64(),
            mbs
        );
    }

    // 3. Audio CD (Xeno Crisis - 20 tracks CDFL, 260 MB)
    let xeno_path = ref_dir.join("xeno_crisis_cdfl.chd");
    if xeno_path.exists() {
        let f = File::open(&xeno_path).unwrap();
        let mut chd = ChdFile::open(f).unwrap();
        let start = Instant::now();
        extract_cd(
            &mut chd,
            Path::new("/tmp/bench_chdlady_xeno.cue"),
            Some(Path::new("/tmp/bench_chdlady_xeno.bin")),
            false,
        )
        .unwrap();
        let elapsed = start.elapsed();
        let bin_len = std::fs::metadata("/tmp/bench_chdlady_xeno.bin")
            .unwrap()
            .len();
        let mb = (bin_len as f64) / (1024.0 * 1024.0);
        let mbs = mb / elapsed.as_secs_f64();
        println!(
            "CD CDFL extract_cd (audio): {:.2} MB in {:.3}s ({:.2} MB/s)",
            mb,
            elapsed.as_secs_f64(),
            mbs
        );
    }

    // 4. Data CD (R4 - Ridge Racer Type 4 CDZL, 593 MB)
    let r4_path = ref_dir.join("r4_cdzl.chd");
    if r4_path.exists() {
        let f = File::open(&r4_path).unwrap();
        let mut chd = ChdFile::open(f).unwrap();
        let start = Instant::now();
        extract_cd(
            &mut chd,
            Path::new("/tmp/bench_chdlady_r4.cue"),
            Some(Path::new("/tmp/bench_chdlady_r4.bin")),
            false,
        )
        .unwrap();
        let elapsed = start.elapsed();
        let bin_len = std::fs::metadata("/tmp/bench_chdlady_r4.bin")
            .unwrap()
            .len();
        let mb = (bin_len as f64) / (1024.0 * 1024.0);
        let mbs = mb / elapsed.as_secs_f64();
        println!(
            "CD CDZL extract_cd (data + ECC): {:.2} MB in {:.3}s ({:.2} MB/s)",
            mb,
            elapsed.as_secs_f64(),
            mbs
        );
    }

    // 5. GD-ROM GDI (4x4 Evo, 11 tracks)
    let gdrom_path = ref_dir.join("4x4evo_gdrom.chd");
    if gdrom_path.exists() {
        std::fs::create_dir_all("/tmp/test_gdrom_chdlady").unwrap();
        let f = File::open(&gdrom_path).unwrap();
        let mut chd = ChdFile::open(f).unwrap();
        let start = Instant::now();
        extract_cd(
            &mut chd,
            Path::new("/tmp/test_gdrom_chdlady/disc.gdi"),
            None,
            true,
        )
        .unwrap();
        let elapsed = start.elapsed();
        println!(
            "GD-ROM extract_cd (11 tracks): finished in {:.3}s",
            elapsed.as_secs_f64()
        );
    }

    // 6. Mixed-Mode CD (WipEout - 9 tracks: 1 Data + 8 Audio)
    let wipeout_path = ref_dir.join("wipeout_default.chd");
    if wipeout_path.exists() {
        std::fs::create_dir_all("/tmp/test_wipeout_chdlady").unwrap();
        let f = File::open(&wipeout_path).unwrap();
        let mut chd = ChdFile::open(f).unwrap();
        let start = Instant::now();
        extract_cd(
            &mut chd,
            Path::new("/tmp/test_wipeout_chdlady/disc.cue"),
            Some(Path::new("/tmp/test_wipeout_chdlady/disc.bin")),
            false,
        )
        .unwrap();
        let elapsed = start.elapsed();
        let bin_len = std::fs::metadata("/tmp/test_wipeout_chdlady/disc.bin")
            .unwrap()
            .len();
        let mb = (bin_len as f64) / (1024.0 * 1024.0);
        let mbs = mb / elapsed.as_secs_f64();
        println!(
            "Mixed-mode CD extract_cd (WipEout single-bin): {:.2} MB in {:.3}s ({:.2} MB/s)",
            mb,
            elapsed.as_secs_f64(),
            mbs
        );
    }
}