//! Which XBG7 resources never decode, and how big is that population?
//!
//! Coverage has been reported as "resources decoded" without a denominator. This
//! prints both, per container and in total, and names the misses so the gate
//! attribution (`why_rejected`) has a work list.
use sylpheed_formats::mesh::{debug_resource_params, xbg7_resource_names, Xbg7Model};
use std::collections::HashSet;

fn main() {
    let dir = std::env::args().nth(1).expect("resource3d dir");
    let show = std::env::args().nth(2).is_some();
    let mut files: Vec<_> = std::fs::read_dir(&dir)
        .unwrap()
        .flatten()
        .map(|e| e.path())
        .filter(|p| p.extension().and_then(|s| s.to_str()) == Some("xpr"))
        .collect();
    files.sort();

    let (mut total, mut decoded, mut no_decl) = (0usize, 0usize, 0usize);
    let mut misses: Vec<String> = Vec::new();
    for f in &files {
        let Ok(bytes) = std::fs::read(f) else { continue };
        let names = xbg7_resource_names(&bytes);
        if names.is_empty() {
            continue;
        }
        let got: HashSet<String> = Xbg7Model::anchor_models_cancellable(&bytes, 0.0, &|| false)
            .into_iter()
            .map(|m| m.name)
            .collect();
        for n in &names {
            total += 1;
            if got.contains(n) {
                decoded += 1;
            } else if debug_resource_params(&bytes, n).is_none() {
                // No vertex declaration / no index markers: the anchor scan
                // never even considers these, so they are a different question
                // from "searched and not found".
                no_decl += 1;
            } else {
                misses.push(format!("{}|{n}", f.file_name().unwrap().to_string_lossy()));
            }
        }
    }
    println!(
        "XBG7 resources: {total} total, {decoded} decoded ({:.1}%), {no_decl} without a usable descriptor, {} searched-and-missed",
        100.0 * decoded as f64 / total as f64,
        misses.len()
    );
    if show {
        for m in &misses {
            println!("{m}");
        }
    }
}
