"""Tests for versioned gate_report.json schema (v1.0)."""

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


def _make_ctx(tmp_path):
    contract = tmp_path / "TASK_CONTRACT.md"
    contract.write_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\nNone.\n\n"
        "## Notes\n\nNone.\n",
        encoding="utf-8",
    )
    return RunContext(
        repo_root=tmp_path,
        run_id="test-schema",
        apply_mode=False,
        contract_path=str(contract),
    )


def test_schema_version_present(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", "")

    report = run_gates(ctx)

    assert report["schema_version"] == "1.0"
    assert report["schema_version"] == GATE_SCHEMA_VERSION


def test_all_required_keys_present(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", "")

    report = run_gates(ctx)

    required = [
        "schema_version",
        "run_id",
        "mode",
        "timestamp",
        "gates",
        "overall_status",
        "exit_code",
        "errors",
    ]
    for key in required:
        assert key in report, f"Missing required key: {key}"


def test_gate_entries_have_name_status_details(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)

    assert isinstance(report["gates"], list)
    for g in report["gates"]:
        assert "name" in g
        assert "status" in g
        assert g["status"] in ("PASS", "FAIL", "SKIP")
        assert "details" in g


def test_mode_is_dry_run(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", "")

    report = run_gates(ctx)

    assert report["mode"] == "dry_run"


def test_errors_list_type(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", "")

    report = run_gates(ctx)

    assert isinstance(report["errors"], list)


def test_json_file_matches_schema(tmp_path):
    """The JSON file on disk must match the in-memory report."""
    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", "")

    report = run_gates(ctx)

    on_disk = json.loads(
        ctx.artifact_path("gate_report.json").read_text(encoding="utf-8")
    )
    assert on_disk["schema_version"] == report["schema_version"]
    assert on_disk["overall_status"] == report["overall_status"]
    assert on_disk["exit_code"] == report["exit_code"]
