#!/usr/bin/env python3
"""Contract test for local imported-test bake, repair, rerun, and activation."""

from __future__ import annotations

import json
import subprocess
import tempfile
from pathlib import Path


PLUGIN = Path(__file__).resolve().parents[1]
INTENT = PLUGIN / "runtime" / "carbon" / "scripts" / "carbon_intent.py"
BAKE = PLUGIN / "runtime" / "carbon" / "scripts" / "carbon_bake.py"


def run(script: Path, *args: str, ok: bool = True) -> dict:
    result = subprocess.run(["python3", str(script), *args], capture_output=True, text=True)
    if ok and result.returncode:
        raise AssertionError(result.stderr or result.stdout)
    if not ok:
        if result.returncode == 0: raise AssertionError("Command unexpectedly succeeded")
        return {"error": result.stderr}
    return json.loads(result.stdout)


with tempfile.TemporaryDirectory(prefix="carbon-bake-") as temporary:
    root = Path(temporary)
    source = root / "testrail-export.csv"
    original = (
        "Case ID,Title,Preconditions,Steps,Expected Result\n"
        "C1,Reconnect saves once,Signed-in editor,Reconnect and save,Exactly one save completes\n"
        "C2,Expired card is declined,Synthetic shopper,Submit expired card,No order is created\n"
        "C3,Invoice event arrives,Synthetic invoice,Wait for event,One invoice event is recorded\n"
    )
    source.write_text(original, encoding="utf-8")
    imported = run(INTENT, "import", "--root", str(root), "--source", str(source), "--target", "http://localhost:3000", "--max-repairs", "2")
    bake_id = imported["bakeRun"]["id"]
    ids = [row["id"] for row in imported["drafts"]]

    first = run(BAKE, "next", "--root", str(root), "--run-id", bake_id)
    assert first["test"]["id"] == ids[0] and first["attempt"] == 1
    rejected_pass = run(BAKE, "result", "--root", str(root), "--run-id", bake_id, "--test-id", ids[0], "--status", "passed", "--actual", "save visible", ok=False)
    assert "evidence handle" in rejected_pass["error"]
    failed_definition = run(
        BAKE, "result", "--root", str(root), "--run-id", bake_id, "--test-id", ids[0],
        "--status", "failed", "--classification", "test-definition", "--actual", "Target route was ambiguous",
        "--failure", "Converted scope omitted /editor/1", "--evidence", "trace://attempt-1",
    )
    assert failed_definition["repairEligible"] is True
    rejected_repair = run(
        BAKE, "repair", "--root", str(root), "--run-id", bake_id, "--test-id", ids[0],
        "--patch-json", '{"status":"active"}', ok=False,
    )
    assert "may change only" in rejected_repair["error"]
    repaired = run(
        BAKE, "repair", "--root", str(root), "--run-id", bake_id, "--test-id", ids[0],
        "--patch-json", '{"scope":"http://localhost:3000/editor/1","setup":["Signed-in synthetic editor"],"oracles":["Exactly one durable save completes"]}',
        "--reason", "Use the observed editor route and objective durable-state oracle",
    )
    assert repaired["test"]["revision"] == 2 and repaired["repair"]["number"] == 1
    rerun = run(BAKE, "next", "--root", str(root), "--run-id", bake_id)
    assert rerun["test"]["id"] == ids[0] and rerun["attempt"] == 2
    passed = run(
        BAKE, "result", "--root", str(root), "--run-id", bake_id, "--test-id", ids[0],
        "--status", "passed", "--classification", "none", "--actual", "One save request and one durable record observed",
        "--evidence", "screenshot://editor-saved", "--evidence", "network://save-request-1",
    )
    assert passed["status"] == "passed"

    second = run(BAKE, "next", "--root", str(root), "--run-id", bake_id)
    run(
        BAKE, "result", "--root", str(root), "--run-id", bake_id, "--test-id", second["test"]["id"],
        "--status", "failed", "--classification", "product-defect", "--actual", "Order was created after decline",
        "--failure", "Product violates the imported intent", "--evidence", "trace://expired-card-order",
    )
    third = run(BAKE, "next", "--root", str(root), "--run-id", bake_id)
    run(
        BAKE, "result", "--root", str(root), "--run-id", bake_id, "--test-id", third["test"]["id"],
        "--status", "blocked", "--classification", "infrastructure", "--actual", "Webhook sandbox unavailable",
        "--failure", "No authorized event fixture", "--evidence", "log://sandbox-unavailable",
    )
    assert run(BAKE, "next", "--root", str(root), "--run-id", bake_id)["done"] is True
    completed = run(BAKE, "complete", "--root", str(root), "--run-id", bake_id)
    assert completed["summary"]["passed"] == 1
    assert completed["summary"]["failed"] == 1
    assert completed["summary"]["blocked"] == 1
    assert completed["summary"]["repairs"] == 1
    assert completed["qualityConfidence"]["confidenceInQuality"]["band"] == "low"
    assert completed["qualityConfidence"]["remainingRisk"]["level"] == "high"
    report = Path(completed["report"])
    report_text = report.read_text(encoding="utf-8")
    assert report.exists() and "Local import bake" in report_text and "@media(max-width:640px)" in report_text
    assert "Confidence in quality" in report_text and "Coverage missing" in report_text and "What changes confidence" in report_text
    bake_summary = json.loads((report.parent / "summary.json").read_text(encoding="utf-8"))
    assert bake_summary["qualityConfidence"]["remainingRisk"]["level"] == "high"

    library = json.loads((root / ".carbon" / "tests" / "intent-tests.json").read_text(encoding="utf-8"))
    by_id = {test["id"]: test for test in library["tests"]}
    assert by_id[ids[0]]["status"] == "active" and by_id[ids[0]]["lifecycle"] == "observed"
    assert by_id[ids[1]]["status"] == "draft" and by_id[ids[1]]["lifecycle"] == "candidate"
    assert by_id[ids[2]]["status"] == "draft" and by_id[ids[2]]["lifecycle"] == "candidate"
    assert source.read_text(encoding="utf-8") == original

    by_id[ids[0]]["safety"]["public"] = True
    library["tests"] = list(by_id.values())
    (root / ".carbon" / "tests" / "intent-tests.json").write_text(json.dumps(library), encoding="utf-8")
    gated = run(BAKE, "prepare", "--root", str(root), "--test-id", ids[0])
    assert gated["summary"]["blocked"] == 1
    assert gated["tests"][0]["requiresApproval"] == ["public"]

print("PASS: local imported-test bake, bounded definition repair, rerun, evidence activation, and failure classification verified")
