use mcptest_core::eval::EqualFunctionSet;
/// Offline integration coverage for the orchestration diagnostics (MCP-Atlas).
///
/// These tests drive the public `mcptest_core` surface with a recorded trace
/// envelope and assert the five deterministic sub-scores. No model is called.
use mcptest_core::eval::{fold_trace, OrchestrationCall};
use serde_json::json;

/// The declared capability classes for the recorded scenario.
///
/// WHY inline and not a fixture file: keeps the recorded envelope and its
/// expected classes obvious to a reader in one place.
fn classes() -> Vec<EqualFunctionSet> {
    vec![
        EqualFunctionSet {
            name: "search".to_string(),
            members: vec!["search".to_string(), "web_search".to_string()],
        },
        EqualFunctionSet {
            name: "fetch".to_string(),
            members: vec!["fetch".to_string(), "get".to_string()],
        },
    ]
}

/// A recorded clean run: one well-parameterized call per expected class.
fn clean_trace() -> Vec<OrchestrationCall> {
    vec![
        OrchestrationCall {
            tool: "web_search".to_string(),
            args: json!({"q": "weather in paris"}),
            is_error: false,
        },
        OrchestrationCall {
            tool: "get".to_string(),
            args: json!({"id": 42}),
            is_error: false,
        },
    ]
}

#[test]
fn clean_recorded_run_scores_every_axis_at_100() {
    let universe = classes();
    let diagnostics = fold_trace(&clean_trace(), &universe, &universe);
    assert_eq!(diagnostics.discovery, 100);
    assert_eq!(diagnostics.parameterization, 100);
    assert_eq!(diagnostics.syntax, 100);
    assert_eq!(diagnostics.error_recovery, 100);
    assert_eq!(diagnostics.efficiency, 100);
    assert!(!diagnostics.judged);
}

#[test]
fn recorded_run_with_recovered_error_keeps_recovery_high_but_lowers_efficiency() {
    let universe = classes();
    let trace = vec![
        OrchestrationCall {
            tool: "search".to_string(),
            args: json!({"q": "x"}),
            is_error: true,
        },
        OrchestrationCall {
            tool: "web_search".to_string(),
            args: json!({"q": "x"}),
            is_error: false,
        },
        OrchestrationCall {
            tool: "fetch".to_string(),
            args: json!({"id": 1}),
            is_error: false,
        },
    ];
    let diagnostics = fold_trace(&trace, &universe, &universe);
    assert_eq!(diagnostics.discovery, 100);
    assert_eq!(diagnostics.error_recovery, 100);
    // Two classes optimal over three observed calls rounds to 67 percent.
    assert_eq!(diagnostics.efficiency, 67);
}

#[test]
fn recorded_run_with_unrecovered_error_and_empty_args_drops_those_axes() {
    let universe = classes();
    let trace = vec![OrchestrationCall {
        tool: "search".to_string(),
        args: json!({}),
        is_error: true,
    }];
    let diagnostics = fold_trace(&trace, &universe, &universe);
    assert_eq!(diagnostics.parameterization, 0);
    assert_eq!(diagnostics.error_recovery, 0);
    assert_eq!(diagnostics.discovery, 50);
}
