//! Validate mcp-server.toml parses, passes SDK validation, has the right tool
//! count, declares the domain critical, and gates every control write.

use adk_mcp_sdk::manifest::ServerManifest;
use std::path::Path;

fn manifest() -> ServerManifest {
    let path = Path::new(env!("CARGO_MANIFEST_DIR")).join("mcp-server.toml");
    ServerManifest::from_file(&path).expect("manifest should parse")
}

#[test]
fn manifest_parses_and_validates() {
    let m = manifest();
    assert!(m.validate().is_empty(), "validation errors: {:?}", m.validate());
    assert_eq!(m.server_id, "mcp_scada");
    assert_eq!(m.domain, "energy-utilities");
    assert_eq!(m.tools.len(), 27, "expected 27 declared tools");
}

#[test]
fn control_writes_are_gated_external() {
    use adk_mcp_sdk::risk::RiskClass;
    let m = manifest();
    for name in ["issue_command", "set_lockout", "set_asset_state"] {
        let t = m.tools.iter().find(|t| t.name == name).unwrap_or_else(|| panic!("{name} present"));
        assert!(t.requires_approval, "{name} must require approval");
        assert_eq!(t.risk_class, RiskClass::ExternalWrite, "{name} must be external_write");
    }
}

#[test]
fn check_interlocks_is_read_only() {
    use adk_mcp_sdk::risk::RiskClass;
    let m = manifest();
    // The dry-run must never be a write.
    let t = m.tools.iter().find(|t| t.name == "check_interlocks").unwrap();
    assert_eq!(t.risk_class, RiskClass::ReadOnly);
    assert!(!t.requires_approval);
}

#[test]
fn telemetry_reads_are_read_only() {
    use adk_mcp_sdk::risk::RiskClass;
    let m = manifest();
    for name in ["list_assets", "get_tag", "list_tags", "tag_history", "tag_trend", "list_alarms", "command_history", "outage_queue", "audit_log"] {
        let t = m.tools.iter().find(|t| t.name == name).unwrap();
        assert_eq!(t.risk_class, RiskClass::ReadOnly, "{name} should be read_only");
    }
}
