//! L4b wiring proof for the published `nornir-testmatrix` crate.
//!
//! INJECT-AND-ASSERT test (project LAW): it feeds canned `TestResultRow`s —
//! varied status / aspect / metric — through the real `JsonFileSink`
//! round-trip and the `summarize_runs` + `render_matrix` renderers, then
//! asserts on the REAL output (counts, surviving fields, the red marker in the
//! grid). Runs fast and fully offline: NO cargo subprocess, no network. Proves
//! knut can build against the crate AND that the crate's core data path works
//! from this repo.

use nornir_testmatrix::{
    render_matrix, status, summarize_runs, JsonFileSink, TestResultRow, TestSink,
};

/// A fixed run's worth of canned rows spanning several aspects, statuses and
/// metric values. `ts_micros` is shared (one run); `run_id` groups them.
fn canned_rows() -> Vec<TestResultRow> {
    let run_id = "run-L4b-knut-0001";
    let repo = "knut";
    let ts = 1_700_000_000_000_000_i64;
    let mk = |suite: &str, name: &str, st: &str, aspect: &str, metric: f64, msg: &str| {
        let mut r = TestResultRow::unit(run_id, repo, suite, name, st, 15.0, ts, msg);
        r.aspect = aspect.to_string();
        r.metric = metric;
        r
    };
    vec![
        mk("bifrost", "lifecycle_file_to_graph", status::PASS, "unit", 0.0, ""),
        mk("build", "build", status::PASS, "build", 0.0, ""),
        // a genuinely red case — this MUST surface as ✗ in the matrix.
        mk("audit", "audit", status::FAIL, "audit", 2.0, "2 advisories"),
        mk("falkordb", "integration_skip", status::IGNORED, "unit", 0.0, "needs falkordb container"),
        mk("coverage", "coverage", status::PASS, "coverage", 58.0, ""),
    ]
}

#[test]
fn testmatrix_roundtrip_and_render_inject_assert() {
    let rows = canned_rows();

    // ── 1. JsonFileSink round-trip: aspect + metric must survive serde. ─────
    let dir = tempfile::tempdir().expect("tempdir");
    let path = dir.path().join("quality-matrix.jsonl");
    let sink = JsonFileSink::new(&path);
    sink.append(&rows).expect("append rows");

    let read_back = sink.read_all().expect("read_all");
    assert_eq!(read_back.len(), rows.len(), "row count must round-trip");
    assert_eq!(read_back, rows, "rows must round-trip exactly (incl. aspect+metric)");

    let audit = read_back
        .iter()
        .find(|r| r.aspect == "audit")
        .expect("audit row survives");
    assert_eq!(audit.metric, 2.0, "audit advisory count must survive");
    assert!(status::is_red(&audit.status));

    let coverage = read_back
        .iter()
        .find(|r| r.aspect == "coverage")
        .expect("coverage row survives");
    assert_eq!(coverage.metric, 58.0, "coverage metric must survive");
    assert!(status::is_green(&coverage.status));

    // ── 2. summarize_runs: exact tallies for the single run. ────────────────
    let summaries = summarize_runs(&read_back);
    assert_eq!(summaries.len(), 1, "exactly one run id");
    let s = &summaries[0];
    assert_eq!(s.passed, 3, "3 pass (unit + build + coverage)");
    assert_eq!(s.failed, 1, "1 fail (audit)");
    assert_eq!(s.ignored, 1, "1 ignored (integration_skip)");
    assert_eq!(s.total(), 5);
    assert!(!s.green(), "a failed run is not green");

    // ── 3. render_matrix: the human grid carries the red marker + the case. ─
    let grid = render_matrix(&read_back);
    assert!(grid.contains('✗'), "rendered grid must show a red marker:\n{grid}");
    assert!(grid.contains("knut"), "grid names the repo:\n{grid}");
    assert!(
        grid.contains("[audit]") && grid.contains("audit::audit"),
        "grid surfaces the failing audit case with its aspect:\n{grid}"
    );
    assert!(
        grid.contains("2 advisories"),
        "grid carries the failure message:\n{grid}"
    );

    // Feed this suite's own real result back into the matrix (feature-gated so
    // release strips it; the no-op stub keeps the call here unconditional).
    let wiring_ok = read_back == rows
        && s.passed == 3
        && s.failed == 1
        && grid.contains('✗')
        && grid.contains("2 advisories");
    emit_status(
        "testmatrix_roundtrip_and_render_inject_assert",
        wiring_ok,
        "JsonFileSink round-trip + summarize_runs(3p/1f/1i) + render_matrix red marker",
    );
}

/// Emit a functional-status row for this suite's real result. Feature ON →
/// recorded into the matrix buffer; OFF → inlined no-op.
#[cfg(feature = "testmatrix")]
fn emit_status(check: &str, ok: bool, detail: &str) {
    nornir_testmatrix::functional_status("knut-bifrost-testmatrix-wiring", check, ok, detail);
}
#[cfg(not(feature = "testmatrix"))]
fn emit_status(_check: &str, _ok: bool, _detail: &str) {}
