use codspeed_criterion_compat::{BenchmarkId, Criterion, criterion_group, criterion_main};
use std::hint::black_box;

use sqpack_rs::Platform;
use sqpack_rs::route::ArchiveTriple;
use sqpack_rs::write::SqPackRepacker;

mod common;

fn exd_triple() -> ArchiveTriple {
    ArchiveTriple::from_game_path("exd/probe.exh").expect("exd/* should route")
}

fn bench_repack(c: &mut Criterion) {
    let mut group = c.benchmark_group("repack");
    let cases: &[(&str, usize, usize)] = &[
        ("tiny_1_file_64B", 1, 64),
        ("medium_10_files_16KiB", 10, 16 * 1024),
        ("large_100_files_100KiB", 100, 100 * 1024),
    ];
    for &(label, file_count, size) in cases {
        let total_bytes = (file_count * size) as u64;
        let payloads: Vec<Vec<u8>> = (0..file_count)
            .map(|_| common::build_compressible_payload(size))
            .collect();
        group.throughput(codspeed_criterion_compat::Throughput::Bytes(total_bytes));
        group.bench_with_input(
            BenchmarkId::from_parameter(label),
            &payloads,
            |b, payloads| {
                b.iter(|| {
                    let mut r = SqPackRepacker::new(exd_triple(), Platform::Win32)
                        .with_index_v1()
                        .with_index_v2();
                    for (i, payload) in payloads.iter().enumerate() {
                        let name = format!("exd/bench{i:04}.exd");
                        r.add_file(name, black_box(payload.clone())).expect("add");
                    }
                    let archive = r.build().expect("build");
                    black_box(archive);
                });
            },
        );
    }
    group.finish();
}

criterion_group!(repack_benches, bench_repack);
criterion_main!(repack_benches);
