//! Identify which stage + ship a capture log came from: match the capture's
//! draw vertex counts against every resource (incl. LODs) of every Stage_SNN.xpr.
//!   cargo run --release --example capture_match -- <capture.log> <resource3d dir>
use sylpheed_formats::mesh::{xbg7_resource_names, Xbg7Model};
use sylpheed_formats::ship_capture::{parse_capture, parse_drawlog};
use std::collections::{BTreeMap, HashSet};

fn main() {
    let a: Vec<String> = std::env::args().collect();
    let text = std::fs::read_to_string(&a[1]).unwrap();
    let mut draws = parse_capture(&text);
    if draws.is_empty() { draws = parse_drawlog(&text); }
    let caps: HashSet<u32> = draws.iter().map(|d| d.vcount).filter(|v| *v >= 100).collect();
    eprintln!("{} draws, {} distinct vcounts>=100", draws.len(), caps.len());

    let mut entries: Vec<_> = std::fs::read_dir(&a[2]).unwrap().filter_map(|e| e.ok())
        .filter(|e| { let n = e.file_name().to_string_lossy().to_string(); n.starts_with("Stage_") && n.ends_with(".xpr") })
        .map(|e| e.path()).collect();
    entries.sort();
    for path in entries {
        let bytes = std::fs::read(&path).unwrap();
        let names = xbg7_resource_names(&bytes);
        let want: HashSet<String> = names.iter().cloned().collect();
        let models = Xbg7Model::models_named(&bytes, &want, &|| false);
        // resource -> vcount; group hits by ship-id prefix
        let mut hits: BTreeMap<String, Vec<(String, u32)>> = BTreeMap::new();
        for m in &models {
            let vc: usize = m.meshes.iter().map(|s| s.positions.len()).sum();
            if vc >= 100 && caps.contains(&(vc as u32)) {
                let id = m.name.get(..4).unwrap_or("?").to_string();
                hits.entry(id).or_default().push((m.name.clone(), vc as u32));
            }
        }
        let total: usize = hits.values().map(|v| v.len()).sum();
        if total >= 3 {
            println!("== {} : {} matching resources ==", path.file_name().unwrap().to_string_lossy(), total);
            for (id, v) in &hits {
                let s: Vec<String> = v.iter().map(|(n, c)| format!("{n}({c})")).collect();
                println!("   {id}: {}", s.join(" "));
            }
        }
    }
}
