//! Integration test for the OpenInference trace export (WOR-1419).
//!
//! `mcptest report <run.json> --format openinference` projects a saved run into
//! OpenInference/OTLP-compatible JSONL spans. This test writes a temp run
//! report, exports it, and asserts the span shape (one run span, one test span
//! per test, deterministic ids, schema version), so it needs no server.

use std::io::Write;

use assert_cmd::Command;

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

fn report_json() -> String {
    r#"{
  "schema_version": "0.1",
  "mcptest_version": "1.0.0",
  "generated_at": "2026-06-21T00:00:00Z",
  "run_id": "01J0EXPORT",
  "summary": { "total": 2, "passed": 1, "failed": 1, "skipped": 0, "duration_ms": 8 },
  "tests": [
    { "name": "first passes", "status": "pass", "duration_ms": 3, "cache_hit": false },
    { "name": "second fails", "status": "fail", "duration_ms": 5, "cache_hit": false }
  ],
  "metadata": { "run_id": "01J0EXPORT", "mcptest_version": "1.0.0", "runner_environment": "local", "os": "linux", "arch": "x86_64", "servers": [] }
}"#
    .to_string()
}

#[test]
fn openinference_export_emits_run_and_test_spans() {
    let mut f = tempfile::NamedTempFile::new().unwrap();
    f.write_all(report_json().as_bytes()).unwrap();

    let out = mcptest()
        .args(["report"])
        .arg(f.path())
        .args(["--format", "openinference"])
        .assert()
        .success()
        .get_output()
        .stdout
        .clone();

    let spans: Vec<serde_json::Value> = String::from_utf8(out)
        .unwrap()
        .lines()
        .map(|l| serde_json::from_str(l).expect("each line is JSON"))
        .collect();

    // One run span + one span per test (no jury verdicts in this fixture).
    assert_eq!(spans.len(), 3);
    assert_eq!(spans[0]["name"], "mcptest.run");
    assert_eq!(spans[0]["parent_span_id"], serde_json::Value::Null);
    assert_eq!(spans[0]["status_code"], "ERROR"); // a failing test is present

    let run_span_id = spans[0]["span_id"].clone();
    let test_spans: Vec<&serde_json::Value> = spans
        .iter()
        .filter(|s| s["name"] == "mcptest.test")
        .collect();
    assert_eq!(test_spans.len(), 2);
    for span in &test_spans {
        assert_eq!(span["parent_span_id"], run_span_id);
        assert_eq!(span["schema_version"], "mcptest.dev/openinference/v1");
        assert_eq!(span["trace_id"].as_str().unwrap().len(), 32);
        assert_eq!(span["span_id"].as_str().unwrap().len(), 16);
    }
    // The failing test maps to an ERROR span.
    assert!(test_spans.iter().any(|s| s["status_code"] == "ERROR"));
}
