"""
AI Agent result capture release verifier owner review packet snapshot.

Loads the latest committed P2-137 owner review packet. This module validates
committed evidence only; it never authorizes owner release, approves
maintenance windows, confirms rollback owners, passes release authorization,
releases live apply, applies writers, writes receipts, writes result captures,
writes learning records, updates PlayBook trust, writes reviewer / Gateway
queues, sends Telegram messages, reads secrets, or performs destructive
operations.
"""

from __future__ import annotations

import json
import re
from pathlib import Path
from typing import Any

from src.services.snapshot_paths import default_evaluations_dir

_DEFAULT_EVALUATIONS_DIR = default_evaluations_dir(Path(__file__))
_SNAPSHOT_PATTERN = "ai_agent_result_capture_release_verifier_owner_review_packet_*.json"
_SCHEMA_VERSION = "ai_agent_result_capture_release_verifier_owner_review_packet_v1"
_RUNTIME_AUTHORITY = "result_capture_release_verifier_owner_review_packet_only_no_live_write"


def load_latest_ai_agent_result_capture_release_verifier_owner_review_packet(
    evaluations_dir: Path | None = None,
) -> dict[str, Any]:
    """Load the newest committed release verifier owner review packet."""
    directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR
    candidates = sorted(directory.glob(_SNAPSHOT_PATTERN))
    if not candidates:
        raise FileNotFoundError(f"no AI Agent result capture release verifier owner review packet snapshots found in {directory}")

    latest = candidates[-1]
    with latest.open(encoding="utf-8") as handle:
        payload = json.load(handle)

    if not isinstance(payload, dict):
        raise ValueError(f"{latest}: expected JSON object")

    label = str(latest)
    _require_schema(payload, label)
    _require_prior(payload, label)
    _require_truth(payload, label)
    _require_owner_review_packets(payload, label)
    _require_verifier_packets(payload, label)
    _require_rollback_owner_packets(payload, label)
    _require_maintenance_holds(payload, label)
    _require_live_apply_holds(payload, label)
    _require_blocked_transitions(payload, label)
    _require_actions(payload, label)
    _require_display_redaction(payload, label)
    _require_no_forbidden_display_terms(payload, label)
    _require_rollup_consistency(payload, label)
    return payload


def _require_schema(payload: dict[str, Any], label: str) -> None:
    if payload.get("schema_version") != _SCHEMA_VERSION:
        raise ValueError(f"{label}: expected schema_version={_SCHEMA_VERSION}")
    status = payload.get("program_status") or {}
    expected = {
        "current_priority": "P2",
        "current_task_id": "P2-137",
        "next_task_id": "P2-138",
        "read_only_mode": True,
        "runtime_authority": _RUNTIME_AUTHORITY,
        "overall_completion_percent": 100,
    }
    mismatches = _mismatches(status, expected)
    if mismatches:
        raise ValueError(f"{label}: program_status mismatch: {mismatches}")
    if not status.get("status_note"):
        raise ValueError(f"{label}: program_status.status_note is required")


def _require_prior(payload: dict[str, Any], label: str) -> None:
    prior = payload.get("prior_release_verifier_preflight_gate") or {}
    expected = {
        "schema_version": "ai_agent_result_capture_release_verifier_preflight_gate_v1",
        "release_verifier_preflight_count": 5,
        "rollback_verifier_preflight_count": 5,
        "maintenance_window_verifier_hold_count": 5,
        "live_apply_verifier_hold_count": 5,
        "blocked_verifier_preflight_transition_count": 6,
        "operator_action_count": 5,
        "approval_required_total": 8,
        "blocked_total": 9,
    }
    expected.update(_zero_count_expectations(include_owner_review=True))
    mismatches = _mismatches(prior, expected)
    if mismatches:
        raise ValueError(f"{label}: prior_release_verifier_preflight_gate mismatch: {mismatches}")
    if not prior.get("readiness_note"):
        raise ValueError(f"{label}: prior_release_verifier_preflight_gate.readiness_note is required")


def _require_truth(payload: dict[str, Any], label: str) -> None:
    truth = payload.get("release_verifier_owner_review_truth") or {}
    required_true = {
        "p2_136_release_verifier_preflight_gate_loaded",
        "owner_review_packet_ready",
        "release_verifier_review_required",
        "rollback_owner_review_required",
        "maintenance_window_review_required",
        "live_apply_review_required",
        "redaction_review_required",
        "owner_review_packet_only",
    }
    missing = sorted(field for field in required_true if truth.get(field) is not True)
    if missing:
        raise ValueError(f"{label}: owner review packet flags must remain true: {missing}")

    required_false = {
        "owner_release_authorized",
        "owner_release_approved",
        "owner_review_approved",
        "maintenance_window_approved",
        "rollback_owner_confirmed",
        "post_release_verifier_ready",
        "final_release_candidate_approved",
        "final_release_candidate_passed",
        "release_authorization_granted",
        "release_authorization_passed",
        "rollback_release_passed",
        "live_apply_release_passed",
        "writer_apply_enabled",
        "execution_apply_enabled",
        "receipt_write_enabled",
        "reviewer_queue_write_enabled",
        "gateway_queue_write_enabled",
        "telegram_send_enabled",
        "bot_api_call_enabled",
        "report_receipt_write_enabled",
        "result_capture_write_enabled",
        "learning_write_enabled",
        "playbook_trust_write_enabled",
        "production_write_enabled",
        "secret_read_enabled",
        "destructive_operation_enabled",
    }
    unsafe = sorted(field for field in required_false if truth.get(field) is not False)
    if unsafe:
        raise ValueError(f"{label}: owner review packet live/send/write flags must remain false: {unsafe}")

    non_zero = sorted(field for field in _zero_count_expectations(include_owner_review=True) if truth.get(field) != 0)
    if non_zero:
        raise ValueError(f"{label}: owner review packet live counters must remain zero: {non_zero}")
    if not truth.get("truth_note"):
        raise ValueError(f"{label}: release_verifier_owner_review_truth.truth_note is required")


def _require_owner_review_packets(payload: dict[str, Any], label: str) -> None:
    items = payload.get("owner_review_packets") or []
    _require_ids(
        items,
        "packet_id",
        {
            "owner_review_packet_result_capture",
            "owner_review_packet_learning",
            "owner_review_packet_playbook_trust",
            "owner_review_packet_reviewer_queue",
            "owner_review_packet_gateway_queue",
        },
        label,
        "owner review packets",
    )
    for item in items:
        item_id = item.get("packet_id")
        if item.get("packet_mode") != "release_verifier_owner_review_packet":
            raise ValueError(f"{label}: owner review packet {item_id} mode is invalid")
        if item.get("owner_release_authorized") is not False or item.get("owner_review_approved") is not False:
            raise ValueError(f"{label}: owner review packet {item_id} must stay unauthorized and unapproved")
        if item.get("release_authorization_granted") is not False or item.get("release_authorization_passed") is not False:
            raise ValueError(f"{label}: owner review packet {item_id} must stay ungranted and unpassed")
        _require_valid_status(item, label, f"owner review packet {item_id}")
        if not item.get("review_summary") or not _is_redacted_sha256(item.get("evidence_hash")):
            raise ValueError(f"{label}: owner review packet {item_id} must include review_summary and redacted evidence_hash")


def _require_verifier_packets(payload: dict[str, Any], label: str) -> None:
    items = payload.get("verifier_review_packets") or []
    _require_count(items, 5, label, "verifier review packets")
    for item in items:
        item_id = item.get("packet_id")
        if item.get("packet_mode") != "release_verifier_review_packet":
            raise ValueError(f"{label}: verifier review packet {item_id} mode is invalid")
        if item.get("post_release_verifier_required") is not True:
            raise ValueError(f"{label}: verifier review packet {item_id} must require post-release verifier")
        if item.get("post_release_verifier_ready") is not False or item.get("release_authorization_passed") is not False:
            raise ValueError(f"{label}: verifier review packet {item_id} must stay unready and unpassed")
        _require_valid_status(item, label, f"verifier review packet {item_id}")


def _require_rollback_owner_packets(payload: dict[str, Any], label: str) -> None:
    items = payload.get("rollback_owner_review_packets") or []
    _require_count(items, 5, label, "rollback owner review packets")
    for item in items:
        item_id = item.get("packet_id")
        if item.get("packet_mode") != "rollback_owner_review_packet":
            raise ValueError(f"{label}: rollback owner review packet {item_id} mode is invalid")
        if item.get("rollback_owner_required") is not True:
            raise ValueError(f"{label}: rollback owner review packet {item_id} must require rollback owner")
        if item.get("rollback_owner_confirmed") is not False or item.get("rollback_release_passed") is not False:
            raise ValueError(f"{label}: rollback owner review packet {item_id} must stay unconfirmed and unpassed")
        _require_valid_status(item, label, f"rollback owner review packet {item_id}")


def _require_maintenance_holds(payload: dict[str, Any], label: str) -> None:
    items = payload.get("maintenance_window_review_holds") or []
    _require_count(items, 5, label, "maintenance window review holds")
    for item in items:
        item_id = item.get("hold_id")
        if item.get("hold_mode") != "maintenance_window_owner_review_hold":
            raise ValueError(f"{label}: maintenance window review hold {item_id} mode is invalid")
        if item.get("maintenance_window_required") is not True:
            raise ValueError(f"{label}: maintenance window review hold {item_id} must require maintenance window")
        if item.get("owner_release_authorized") is not False or item.get("maintenance_window_approved") is not False:
            raise ValueError(f"{label}: maintenance window review hold {item_id} must keep owner release and maintenance unapproved")
        _require_valid_status(item, label, f"maintenance window review hold {item_id}")


def _require_live_apply_holds(payload: dict[str, Any], label: str) -> None:
    items = payload.get("live_apply_owner_review_holds") or []
    _require_count(items, 5, label, "live apply owner review holds")
    for item in items:
        item_id = item.get("hold_id")
        if item.get("hold_mode") != "live_apply_owner_review_hold":
            raise ValueError(f"{label}: live apply owner review hold {item_id} mode is invalid")
        if (
            item.get("release_authorization_granted") is not False
            or item.get("release_authorization_passed") is not False
            or item.get("live_apply_release_passed") is not False
            or item.get("live_apply_release_enabled") is not False
        ):
            raise ValueError(f"{label}: live apply owner review hold {item_id} must stay ungranted, unpassed, and disabled")
        _require_valid_status(item, label, f"live apply owner review hold {item_id}")


def _require_blocked_transitions(payload: dict[str, Any], label: str) -> None:
    items = payload.get("blocked_owner_review_transitions") or []
    _require_count(items, 6, label, "blocked owner review transitions")
    for item in items:
        item_id = item.get("transition_id")
        if item.get("runtime_write_allowed") is not False:
            raise ValueError(f"{label}: blocked owner review transition {item_id} must keep runtime_write_allowed=false")
        if item.get("status") not in {"blocked_by_policy", "approval_required"}:
            raise ValueError(f"{label}: blocked owner review transition {item_id} status is invalid")
        if not item.get("reason"):
            raise ValueError(f"{label}: blocked owner review transition {item_id}.reason is required")


def _require_actions(payload: dict[str, Any], label: str) -> None:
    items = payload.get("operator_actions") or []
    _require_count(items, 5, label, "operator actions")
    for item in items:
        item_id = item.get("action_id")
        if item.get("runtime_write_allowed") is not False:
            raise ValueError(f"{label}: operator action {item_id} must keep runtime_write_allowed=false")
        if item.get("status") not in {"ready_for_operator_review", "approval_required"}:
            raise ValueError(f"{label}: operator action {item_id} status is invalid")
        if not item.get("operator_instruction"):
            raise ValueError(f"{label}: operator action {item_id}.operator_instruction is required")


def _require_display_redaction(payload: dict[str, Any], label: str) -> None:
    contract = payload.get("display_redaction_contract") or {}
    expected = {
        "redaction_required": True,
        "raw_prompt_display_allowed": False,
        "private_reasoning_display_allowed": False,
        "secret_value_display_allowed": False,
        "raw_runtime_payload_display_allowed": False,
        "internal_collaboration_content_display_allowed": False,
    }
    mismatches = _mismatches(contract, expected)
    if mismatches:
        raise ValueError(f"{label}: display_redaction_contract mismatch: {mismatches}")
    if not contract.get("frontend_display_policy"):
        raise ValueError(f"{label}: display_redaction_contract.frontend_display_policy is required")


def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
    rollups = payload.get("rollups") or {}
    expected = {
        "owner_review_packet_count": len(payload.get("owner_review_packets") or []),
        "verifier_review_packet_count": len(payload.get("verifier_review_packets") or []),
        "rollback_owner_review_packet_count": len(payload.get("rollback_owner_review_packets") or []),
        "maintenance_window_review_hold_count": len(payload.get("maintenance_window_review_holds") or []),
        "live_apply_owner_review_hold_count": len(payload.get("live_apply_owner_review_holds") or []),
        "blocked_owner_review_transition_count": len(payload.get("blocked_owner_review_transitions") or []),
        "operator_action_count": len(payload.get("operator_actions") or []),
    }
    expected.update(_zero_count_expectations(include_owner_review=True))
    mismatches = _mismatches(rollups, expected)
    if mismatches:
        raise ValueError(f"{label}: rollups mismatch: {mismatches}")


def _require_no_forbidden_display_terms(payload: Any, label: str) -> None:
    forbidden = {
        "work_window_transcript",
        "internal_collaboration_transcript",
        "raw_prompt",
        "private_reasoning",
        "chain_of_thought",
        "authorization_header",
        "secret_value",
    }
    found = sorted(term for term in forbidden if _contains_term(payload, term))
    if found:
        raise ValueError(f"{label}: forbidden display terms leaked: {found}")


def _contains_term(value: Any, term: str) -> bool:
    if isinstance(value, str):
        return term.lower() in value.lower()
    if isinstance(value, dict):
        return any(_contains_term(child, term) for child in value.values())
    if isinstance(value, list):
        return any(_contains_term(child, term) for child in value)
    return False


def _zero_count_expectations(*, include_owner_review: bool) -> dict[str, int]:
    counts = {
        "owner_release_authorized_count": 0,
        "owner_release_approved_count": 0,
        "maintenance_window_approved_count": 0,
        "rollback_owner_confirmed_count": 0,
        "post_release_verifier_ready_count": 0,
        "final_release_candidate_approved_count": 0,
        "final_release_candidate_pass_count": 0,
        "release_authorization_granted_count": 0,
        "release_authorization_pass_count": 0,
        "rollback_release_pass_count": 0,
        "live_apply_release_pass_count": 0,
        "writer_apply_count": 0,
        "execution_apply_count": 0,
        "receipt_write_count": 0,
        "reviewer_queue_write_count": 0,
        "gateway_queue_write_count": 0,
        "telegram_send_count": 0,
        "bot_api_call_count": 0,
        "report_receipt_write_count": 0,
        "result_capture_write_count": 0,
        "learning_write_count": 0,
        "playbook_trust_write_count": 0,
        "production_write_count": 0,
        "secret_read_count": 0,
        "destructive_operation_count": 0,
    }
    if include_owner_review:
        counts["owner_review_approved_count"] = 0
    return counts


def _require_ids(
    items: list[dict[str, Any]],
    field: str,
    expected_ids: set[str],
    label: str,
    group_name: str,
) -> None:
    actual_ids = {str(item.get(field)) for item in items}
    if actual_ids != expected_ids:
        raise ValueError(f"{label}: {group_name} ids mismatch: expected={sorted(expected_ids)} actual={sorted(actual_ids)}")


def _require_count(items: list[Any], expected: int, label: str, group_name: str) -> None:
    if len(items) != expected:
        raise ValueError(f"{label}: expected {expected} {group_name}, got {len(items)}")


def _require_valid_status(item: dict[str, Any], label: str, item_label: str) -> None:
    if item.get("status") not in {"ready_for_owner_review", "approval_required", "blocked_by_policy"}:
        raise ValueError(f"{label}: {item_label} status is invalid")


def _is_redacted_sha256(value: Any) -> bool:
    return isinstance(value, str) and re.fullmatch(r"sha256:[0-9a-f]{64}", value) is not None


def _mismatches(payload: dict[str, Any], expected: dict[str, Any]) -> dict[str, dict[str, Any]]:
    return {
        key: {"expected": expected_value, "actual": payload.get(key)}
        for key, expected_value in expected.items()
        if payload.get(key) != expected_value
    }
