#!/usr/bin/env python3

from __future__ import annotations

import argparse
import re
import sys
from dataclasses import dataclass
from pathlib import Path


@dataclass(frozen=True)
class StepSummary:
    step_id: str
    status: str | None
    decision: str | None
    detail: str


_STEP_ID_RE = re.compile(r"^\s*-\s*id:\s*(\S+)\s*$")
_STATUS_RE = re.compile(r"^\s*status:\s*(\S+)\s*$")


def _decision_from_text(text: str) -> str | None:
    # Evidence is sometimes stored as a single-quoted YAML string containing literal "\n".
    # Use a whole-text regex to avoid depending on YAML parsing.
    m = re.search(r"(?i)\b(final\s+decision|decision|review\s+outcome)\s*:\s*([a-zA-Z_]+)", text)
    if not m:
        return None
    return m.group(2).strip().lower() or None


def _first_problem_detail(text: str) -> str:
    for raw in text.splitlines():
        line = raw.strip()
        if not line:
            continue
        if any(k in line.lower() for k in ("mismatch", "conflict", "gap", "ambig", "insufficient")):
            return line
    for raw in text.splitlines():
        line = raw.strip()
        if line:
            return line
    return "missing evidence"


def _extract_gate_deps(plan_text: str, gate_id: str) -> list[str] | None:
    lines = plan_text.splitlines()
    in_gate = False
    in_deps = False
    deps: list[str] = []

    for line in lines:
        m = _STEP_ID_RE.match(line)
        if m:
            in_gate = (m.group(1) == gate_id)
            in_deps = False
            continue

        if not in_gate:
            continue

        if line.strip() == "depends_on:":
            in_deps = True
            continue

        if in_deps:
            # deps are simple list items like: "- meta.review.spec"
            dep = line.strip()
            if not dep.startswith("-"):
                break
            dep_id = dep[1:].strip()
            if dep_id:
                deps.append(dep_id)

    return deps or None


def _extract_step_block(plan_text: str, step_id: str) -> str | None:
    lines = plan_text.splitlines()
    capture: list[str] = []
    in_block = False

    for line in lines:
        m = _STEP_ID_RE.match(line)
        if m:
            if in_block:
                break
            in_block = (m.group(1) == step_id)
            if in_block:
                capture.append(line)
            continue
        if in_block:
            capture.append(line)

    return "\n".join(capture) if capture else None


def _summarize_step(plan_text: str, step_id: str) -> StepSummary:
    block = _extract_step_block(plan_text, step_id)
    if block is None:
        return StepSummary(step_id, None, None, "missing step in plan")

    status = None
    for raw in block.splitlines():
        m = _STATUS_RE.match(raw)
        if m:
            status = m.group(1)
            break

    evidence_text = ""
    in_evidence = False
    for raw in block.splitlines():
        if not in_evidence and raw.strip().startswith("evidence:"):
            in_evidence = True
        if in_evidence:
            evidence_text += raw + "\n"

    decision = _decision_from_text(evidence_text)
    detail = _first_problem_detail(evidence_text)
    return StepSummary(step_id, status, decision, detail)


def main(argv: list[str] | None = None) -> int:
    parser = argparse.ArgumentParser(description="Audit readiness of meta.review.meta-review-gate")
    parser.add_argument("--plan", default="plan.yaml", help="Path to plan.yaml")
    args = parser.parse_args(argv)

    plan_path = Path(args.plan)
    if not plan_path.exists():
        print(f"ERROR: plan not found: {plan_path}", file=sys.stderr)
        return 2

    plan_text = plan_path.read_text(encoding="utf-8")
    deps = _extract_gate_deps(plan_text, "meta.review.meta-review-gate")
    if deps is None:
        print("ERROR: gate step not found or has no depends_on: meta.review.meta-review-gate", file=sys.stderr)
        return 2

    findings: list[StepSummary] = []
    for dep_id in deps:
        s = _summarize_step(plan_text, dep_id)
        if s.status != "done":
            findings.append(StepSummary(dep_id, s.status, s.decision, "status is not done"))
            continue
        if dep_id == "meta.review.final":
            if s.decision != "ready":
                findings.append(s)
        else:
            if s.decision != "accept":
                findings.append(s)

    if findings:
        print("FAIL: meta.review.meta-review-gate is NOT ready")
        for f in findings:
            print(f"- {f.step_id}: status={f.status!s} decision={f.decision!s} detail={f.detail}")
        return 1

    print("PASS: meta.review.meta-review-gate is ready")
    for dep_id in deps:
        print(f"- {dep_id}: ok")
    return 0


if __name__ == "__main__":
    raise SystemExit(main())
