"""Tests for gate report structure and schema."""

import json
from milco.core.run_context import RunContext
from milco.core.artifacts import write_artifact
from milco.gate.gates import run_gates


def _make_ctx(tmp_path, apply=False, confirm=False):
    contract = tmp_path / "TASK_CONTRACT.md"
    text = (
        "# Task Contract\n\n"
        "## Goal\n\nTest.\n\n"
        "## Scope\n\nTest.\n\n"
        "## Out of scope\n\nNone.\n\n"
        "## Success Criteria\n\nPass.\n\n"
        "## Constraints\n\nNone.\n\n"
        "## Approvals required\n\n"
    )
    if confirm:
        text += "CONFIRM APPLY\n\n"
    else:
        text += "None.\n\n"
    text += "## Notes\n\nNone.\n"
    contract.write_text(text, encoding="utf-8")
    return RunContext(
        repo_root=tmp_path,
        run_id="test-gate",
        apply_mode=apply,
        contract_path=str(contract),
    )


def _gate_by_name(report, name):
    """Lookup a gate entry by name from the gates list."""
    return next(g for g in report["gates"] if g["name"] == name)


def test_gate_report_has_required_keys(tmp_path):
    ctx = _make_ctx(tmp_path)
    ctx.ensure_run_dir()
    write_artifact(ctx, "evidence.md", "# Evidence\n\nData.\n")
    write_artifact(
        ctx, "patches.diff", "--- a/map.json\n+++ b/map.json\n@@ -0,0 +1 @@\n+{}\n"
    )
    write_artifact(
        ctx,
        "summary.md",
        "# Summary\n\n## Plan\n\n### Step 1: Scan\n\n- tool: scan\n",
    )

    report = run_gates(ctx)

    assert "run_id" in report
    assert "gates" in report
    assert "overall_status" in report
    gate_names = {g["name"] for g in report["gates"]}
    assert "pytest" in gate_names
    assert "repo_sanity" in gate_names
    assert "policy" in gate_names


def test_gate_report_json_written(tmp_path):
    ctx = _make_ctx(tmp_path)
    ctx.ensure_run_dir()
    write_artifact(ctx, "evidence.md", "# Evidence\n\nData.\n")
    write_artifact(ctx, "patches.diff", "")
    write_artifact(ctx, "summary.md", "")

    run_gates(ctx)

    report_path = ctx.artifact_path("gate_report.json")
    assert report_path.exists()
    data = json.loads(report_path.read_text(encoding="utf-8"))
    assert "gates" in data


def test_gate_each_has_status(tmp_path):
    ctx = _make_ctx(tmp_path)
    ctx.ensure_run_dir()
    write_artifact(ctx, "evidence.md", "# Evidence\n\nData.\n")
    write_artifact(ctx, "patches.diff", "--- a/x\n+++ b/x\n@@ -1 +1 @@\n-a\n+b\n")
    write_artifact(
        ctx,
        "summary.md",
        "# Summary\n\n## Plan\n\n### Step 1: Scan\n\n- tool: scan\n",
    )

    report = run_gates(ctx)
    for g in report["gates"]:
        assert "name" in g
        assert "status" in g, f"Gate '{g['name']}' missing 'status' key"
        assert g["status"] in ("PASS", "FAIL", "SKIP")


def test_dry_run_pytest_skipped(tmp_path):
    ctx = _make_ctx(tmp_path, apply=False)
    ctx.ensure_run_dir()
    write_artifact(ctx, "evidence.md", "# E\n\nData.\n")
    write_artifact(ctx, "patches.diff", "")
    write_artifact(ctx, "summary.md", "")

    report = run_gates(ctx)
    pytest_gate = _gate_by_name(report, "pytest")
    assert pytest_gate["status"] == "SKIP"
