//! Scratch analysis: for one IDXD key, list every object that DECLARES it and
//! whether it carries a value on disc or is left at the title-code default.
//!
//! Run: cargo run -p sylpheed-formats --example default_owners -- <KEY> [KEY...]

use sylpheed_formats::idxd::IdxdObject;
use sylpheed_formats::pak::PakArchive;

fn is_number(s: &str) -> bool {
    let s = s.strip_suffix(['f', 'F']).unwrap_or(s);
    let t = s.strip_prefix(['-', '+']).unwrap_or(s);
    !t.is_empty() && t.chars().all(|c| c.is_ascii_digit() || c == '.')
}
fn is_key(s: &str) -> bool {
    !s.is_empty()
        && s.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-')
        && s.chars().next().is_some_and(|c| c.is_ascii_alphabetic() || c == '_')
        && !is_number(s)
}
fn is_value(s: &str) -> bool {
    is_number(s) || !is_key(s)
}

fn main() {
    let root = std::env::var("SYLPHEED_DISC")
        .unwrap_or_else(|_| "/home/fabi/RE - Project Sylpheed/sylph_extract".into());
    let wanted: Vec<String> = std::env::args().skip(1).collect();
    let arc = PakArchive::open(std::path::Path::new(&root).join("dat/GP_MAIN_GAME_E.pak")).unwrap();

    for e in arc.entries() {
        let Ok(bytes) = arc.read(e) else { continue };
        let Ok(obj) = IdxdObject::parse(&bytes) else { continue };
        let toks = obj.tokens().to_vec();
        let mut hits: Vec<String> = vec![];
        for (i, t) in toks.iter().enumerate() {
            if !wanted.iter().any(|w| w == t) {
                continue;
            }
            let valued = i > 0 && is_value(&toks[i - 1]);
            hits.push(if valued {
                format!("{t}={}", toks[i - 1])
            } else {
                format!("{t}=<DEFAULT>")
            });
        }
        if !hits.is_empty() {
            println!("0x{:08x} {:<44} {}", obj.schema_hash, obj.identity(), hits.join("  "));
        }
    }
}
