//! Integration tests for `mcptest posture` (WOR-1432).
//!
//! Offline: the command reads a deployment manifest (or synthesizes one for a
//! bare stdio launch) and scores it. These drive the built binary against the
//! committed `examples/posture` fixtures.

use std::path::PathBuf;

use assert_cmd::Command;
use predicates::prelude::*;

fn mcptest() -> Command {
    Command::cargo_bin("mcptest").expect("binary builds")
}

fn fixture(name: &str) -> PathBuf {
    PathBuf::from(env!("CARGO_MANIFEST_DIR"))
        .join("../../examples/posture")
        .join(name)
}

#[test]
fn bare_stdio_launch_fails_isolation() {
    mcptest()
        .args(["posture", "--stdio-command", "npx -y some-mcp-server"])
        .assert()
        .success()
        .stdout(predicate::str::contains("FAIL").and(predicate::str::contains("isolation")));
}

#[test]
fn hardened_toolhive_manifest_passes_every_dimension() {
    mcptest()
        .arg("posture")
        .arg("--manifest")
        .arg(fixture("toolhive-hardened.json"))
        .assert()
        .success()
        .stdout(predicate::str::contains("9 pass, 0 warn, 0 fail"));
}

#[test]
fn kubernetes_pod_spec_is_recognized() {
    mcptest()
        .arg("posture")
        .arg("--manifest")
        .arg(fixture("k8s-pod.yaml"))
        .args(["--format", "json"])
        .assert()
        .success()
        .stdout(predicate::str::contains(
            "\"deployment_kind\": \"kubernetes\"",
        ));
}

#[test]
fn threshold_gate_fails_an_unsafe_deployment() {
    mcptest()
        .args(["posture", "--stdio-command", "x", "--threshold", "50"])
        .assert()
        .code(6);
}

#[test]
fn no_target_is_a_usage_error() {
    mcptest().arg("posture").assert().code(2);
}

#[test]
fn posture_report_folds_into_an_evidence_pack() {
    let dir = tempfile::tempdir().unwrap();
    let posture = dir.path().join("posture.json");
    let posture_json = mcptest()
        .arg("posture")
        .arg("--manifest")
        .arg(fixture("toolhive-hardened.json"))
        .args(["--format", "json"])
        .output()
        .unwrap();
    std::fs::write(&posture, &posture_json.stdout).unwrap();

    // A minimal run report the evidence pack can wrap.
    let report = dir.path().join("report.json");
    std::fs::write(
        &report,
        r#"{"schema_version":"0.1","mcptest_version":"1.0.0","generated_at":"2026-01-01T00:00:00Z","run_id":"01J","summary":{"total":1,"passed":1,"failed":0,"skipped":0,"duration_ms":1},"tests":[],"metadata":{"run_id":"01J","mcptest_version":"1.0.0","runner_environment":"local","os":"linux","arch":"x86_64"}}"#,
    )
    .unwrap();

    let pack = dir.path().join("pack.json");
    mcptest()
        .args(["evidence", "pack"])
        .arg(&report)
        .arg("--posture")
        .arg(&posture)
        .arg("--output")
        .arg(&pack)
        .assert()
        .success();
    let body = std::fs::read_to_string(&pack).unwrap();
    assert!(
        body.contains("mcptest.sh/posture/v1"),
        "posture section present"
    );
}
