"""Precise validation-status vocabulary for reviewer final reports (#406)."""

from __future__ import annotations

import re
from typing import Any

from reviewer_merge_simulation import assess_merge_simulation_report

STATUS_PASSED = "passed"
STATUS_FAILED = "failed"
STATUS_BASELINE_EQUIVALENT = "baseline-equivalent failure accepted"
STATUS_MERGE_SIM_RESOLVED = "raw-head failure resolved by merge simulation"
STATUS_TRANSIENT_PASS = "passed after transient failure investigation"

ALLOWED_VALIDATION_STATUSES = frozenset({
    STATUS_PASSED,
    STATUS_FAILED,
    STATUS_BASELINE_EQUIVALENT,
    STATUS_MERGE_SIM_RESOLVED,
    STATUS_TRANSIENT_PASS,
})

_STATUS_FIELD_RE = re.compile(
    r"^\s*[-*]?\s*(?:validation status|pr-head validation status|"
    r"official validation status)\s*:\s*(.+?)\s*$",
    re.IGNORECASE | re.MULTILINE,
)
_RAW_HEAD_RESULT_RE = re.compile(
    r"^\s*[-*]?\s*raw pr-head validation result\s*:\s*(.+?)\s*$",
    re.IGNORECASE | re.MULTILINE,
)
_MERGE_SIM_RESULT_RE = re.compile(
    r"^\s*[-*]?\s*merge simulation result\s*:\s*(.+?)\s*$",
    re.IGNORECASE | re.MULTILINE,
)
_BASELINE_WORKTREE_USED_RE = re.compile(
    r"^\s*[-*]?\s*baseline (?:validation )?worktree(?: used)?\s*:\s*(.+?)\s*$",
    re.IGNORECASE | re.MULTILINE,
)
_BASELINE_TARGET_SHA_RE = re.compile(
    r"^\s*[-*]?\s*baseline target sha\s*:\s*([0-9a-f]{7,40})\s*$",
    re.IGNORECASE | re.MULTILINE,
)
_FAILURE_SIGNATURE_RE = re.compile(
    r"failure signatures match\s*:\s*(true|yes)",
    re.IGNORECASE,
)
_BASELINE_FAILURES_RE = re.compile(
    r"baseline failures\s*:",
    re.IGNORECASE,
)
_TRANSIENT_HISTORY_RE = re.compile(
    r"(?:transient validation failure|earlier validation failure|"
    r"prior failure|failure history|failed then passed)",
    re.IGNORECASE,
)
_FULL_SHA = re.compile(r"^[0-9a-f]{40}$", re.IGNORECASE)


def _first_match(pattern: re.Pattern[str], text: str) -> str:
    match = pattern.search(text or "")
    return (match.group(1).strip() if match else "")


def _normalize_status_label(raw: str) -> str:
    text = (raw or "").strip().lower()
    for status in ALLOWED_VALIDATION_STATUSES:
        if text == status.lower():
            return status
    return raw.strip()


def _baseline_proof_complete(text: str, baseline_proof: dict | None) -> bool:
    proof = baseline_proof or {}
    worktree = (
        (proof.get("worktree_path") or "").strip()
        or _first_match(_BASELINE_WORKTREE_USED_RE, text)
    ).lower()
    if not worktree or worktree in {"none", "n/a", "not used", "not applicable"}:
        return False
    if "branches/" not in worktree and not worktree.startswith("branches/"):
        return False
    target_sha = (proof.get("baseline_target_sha") or "").strip()
    if not target_sha:
        target_sha = _first_match(_BASELINE_TARGET_SHA_RE, text)
    if not _FULL_SHA.match(target_sha or ""):
        return False
    if proof.get("failure_signatures_match") is True:
        return True
    if _FAILURE_SIGNATURE_RE.search(text) and _BASELINE_FAILURES_RE.search(text):
        return True
    return False


def _merge_simulation_passed(text: str, command_log: list | None) -> bool:
    merge_result = _first_match(_MERGE_SIM_RESULT_RE, text).lower()
    if merge_result in {"passed", "pass", "clean", "succeeded", "success"}:
        sim = assess_merge_simulation_report(text, command_log=command_log)
        return sim.get("proven") and not sim.get("block")
    if "pass" in merge_result and "fail" not in merge_result:
        sim = assess_merge_simulation_report(text, command_log=command_log)
        return sim.get("proven") and not sim.get("block")
    return False


def _raw_head_failed(text: str) -> bool:
    raw = _first_match(_RAW_HEAD_RESULT_RE, text).lower()
    if raw in {"failed", "fail", "failure"}:
        return True
    if "fail" in raw and "pass" not in raw:
        return True
    return bool(re.search(r"\bfailed\b.*pr-head validation", text, re.IGNORECASE))


def _raw_head_passed(text: str) -> bool:
    raw = _first_match(_RAW_HEAD_RESULT_RE, text).lower()
    return raw in {"passed", "pass", "success"}


def assess_validation_status_vocabulary(
    report_text: str,
    *,
    command_log: list | None = None,
    baseline_proof: dict | None = None,
) -> dict[str, Any]:
    """Bind validation-status labels to the proof path that actually ran (#406)."""
    text = report_text or ""
    reasons: list[str] = []
    status_raw = _first_match(_STATUS_FIELD_RE, text)
    status = _normalize_status_label(status_raw) if status_raw else ""

    if status_raw and status not in ALLOWED_VALIDATION_STATUSES:
        reasons.append(
            f"unknown validation status {status_raw!r}; use one of "
            f"{sorted(ALLOWED_VALIDATION_STATUSES)}"
        )

    if status == STATUS_BASELINE_EQUIVALENT:
        if not _baseline_proof_complete(text, baseline_proof):
            reasons.append(
                "baseline-equivalent failure accepted requires baseline "
                "worktree path, baseline target SHA, and matching failure "
                "signatures (#406)"
            )

    if status == STATUS_MERGE_SIM_RESOLVED:
        if not _raw_head_failed(text):
            reasons.append(
                "raw-head failure resolved by merge simulation requires "
                "raw PR-head validation result: failed (#406)"
            )
        if not _merge_simulation_passed(text, command_log):
            reasons.append(
                "raw-head failure resolved by merge simulation requires "
                "passing merge simulation with worktree/index mutation proof "
                "(#317/#406)"
            )

    if status == STATUS_TRANSIENT_PASS:
        if not _TRANSIENT_HISTORY_RE.search(text):
            reasons.append(
                "passed after transient failure investigation requires "
                "documented earlier validation failure history (#396/#406)"
            )

    if status == STATUS_PASSED and _raw_head_failed(text):
        reasons.append(
            "validation status passed contradicts raw PR-head validation "
            "failure; use a precise status (#406)"
        )

    if status == STATUS_BASELINE_EQUIVALENT and _merge_simulation_passed(
        text, command_log
    ) and not _baseline_proof_complete(text, baseline_proof):
        reasons.append(
            "baseline-equivalent failure accepted is misleading when only "
            "merge simulation resolved the failure; use "
            "'raw-head failure resolved by merge simulation' (#406)"
        )

    if status == STATUS_FAILED and _merge_simulation_passed(text, command_log):
        reasons.append(
            "validation status failed contradicts passing merge simulation; "
            "report the precise resolution status (#406)"
        )

    block = bool(reasons)
    return {
        "block": block,
        "proven": not block,
        "status_claimed": status or None,
        "raw_status_label": status_raw or None,
        "raw_head_failed": _raw_head_failed(text),
        "raw_head_passed": _raw_head_passed(text),
        "merge_simulation_passed": _merge_simulation_passed(text, command_log),
        "baseline_proof_complete": _baseline_proof_complete(text, baseline_proof),
        "reasons": reasons,
        "safe_next_action": (
            "use a validation status that matches the proof path executed "
            "(baseline worktree, merge simulation, or transient history)"
            if reasons
            else "proceed"
        ),
    }