fn run_dmidecode(type_num: u8) -> String {
    std::process::Command::new("dmidecode")
        .args(["-t", &type_num.to_string()])
        .output()
        .map(|o| String::from_utf8_lossy(&o.stdout).into_owned())
        .unwrap_or_default()
}

fn extract_field(text: &str, key: &str) -> Option<String> {
    for line in text.lines() {
        let t = line.trim();
        if t.starts_with(key) {
            let val = t[key.len()..].trim().trim_start_matches(':').trim();
            if !val.is_empty() && val != "Not Specified" && val != "Unknown"
                && val != "To Be Filled By O.E.M." {
                return Some(val.to_string());
            }
        }
    }
    None
}

pub fn is_available() -> bool {
    std::process::Command::new("which")
        .arg("dmidecode")
        .output()
        .map(|o| o.status.success())
        .unwrap_or(false)
}

pub fn collect() -> Option<crate::payload::HardwareInfo> {
    if !is_available() { return None; }

    let board = run_dmidecode(2); // Baseboard
    let cpu   = run_dmidecode(4); // Processor
    let mem   = run_dmidecode(17); // Memory Device

    let mut slots_total: i64 = 0;
    let mut slots_used: i64  = 0;
    let mut ram_type: Option<String>  = None;
    let mut ram_speed: Option<i64>    = None;

    for block in mem.split("\n\n") {
        if !block.contains("Memory Device") { continue; }
        slots_total += 1;
        if let Some(size) = extract_field(block, "Size") {
            if !size.contains("No Module") && size != "0" {
                slots_used += 1;
            }
        }
        if ram_type.is_none() {
            ram_type = extract_field(block, "Type")
                .filter(|t| t != "Unknown" && t != "Other");
        }
        if ram_speed.is_none() {
            if let Some(spd) = extract_field(block, "Speed") {
                ram_speed = spd.split_whitespace().next()
                    .and_then(|s| s.parse().ok());
            }
        }
    }

    Some(crate::payload::HardwareInfo {
        motherboard_vendor: extract_field(&board, "Manufacturer"),
        motherboard_model:  extract_field(&board, "Product Name"),
        cpu_model:          extract_field(&cpu, "Version").or_else(|| extract_field(&cpu, "Family")),
        ram_type,
        ram_speed_mhz: ram_speed,
        ram_slots_used:  if slots_total > 0 { Some(slots_used) } else { None },
        ram_slots_total: if slots_total > 0 { Some(slots_total) } else { None },
    })
}
