"""
AI Agent task result audit trail snapshot.

Loads the latest committed P2-103 task result audit trail contract. This module
validates repo-committed evidence only; it never writes KM, appends LOGBOOK,
writes audit DB rows, writes incident timeline, updates PlayBook trust, writes
Gateway queues, sends Telegram messages, reads secrets, or starts runtime work.
"""

from __future__ import annotations

import json
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_task_result_audit_trail_*.json"
_SCHEMA_VERSION = "ai_agent_task_result_audit_trail_v1"
_RUNTIME_AUTHORITY = "task_result_audit_trail_contract_only_no_live_writeback"


def load_latest_ai_agent_task_result_audit_trail(
    evaluations_dir: Path | None = None,
) -> dict[str, Any]:
    """Load the newest committed AI Agent task result audit trail contract."""
    directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR
    candidates = sorted(directory.glob(_SNAPSHOT_PATTERN))
    if not candidates:
        raise FileNotFoundError(f"no AI Agent task result audit trail 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")
    _require_schema(payload, str(latest))
    _require_no_live_boundaries(payload, str(latest))
    _require_result_routes(payload, str(latest))
    _require_writeback_contracts(payload, str(latest))
    _require_audit_checkpoints(payload, str(latest))
    _require_operator_handoffs(payload, str(latest))
    _require_redaction_contract(payload, str(latest))
    _require_rollup_consistency(payload, str(latest))
    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 {}
    if status.get("read_only_mode") is not True:
        raise ValueError(f"{label}: program_status.read_only_mode must be true")
    if status.get("runtime_authority") != _RUNTIME_AUTHORITY:
        raise ValueError(f"{label}: runtime_authority must remain {_RUNTIME_AUTHORITY}")
    if status.get("current_task_id") != "P2-103":
        raise ValueError(f"{label}: current_task_id must be P2-103")
    if status.get("next_task_id") != "P2-104":
        raise ValueError(f"{label}: next_task_id must be P2-104")


def _require_no_live_boundaries(payload: dict[str, Any], label: str) -> None:
    truth = payload.get("result_audit_truth") or {}
    required_true = {
        "p2_102_candidate_dry_run_loaded",
        "task_result_route_matrix_ready",
        "km_draft_contract_ready",
        "logbook_append_contract_ready",
        "audit_trail_contract_ready",
        "timeline_handoff_contract_ready",
        "operator_next_action_ready",
        "all_results_have_owner_and_next_step",
    }
    missing = sorted(field for field in required_true if truth.get(field) is not True)
    if missing:
        raise ValueError(f"{label}: result audit readiness flags must remain true: {missing}")

    required_false = {
        "runtime_execution_enabled",
        "km_write_enabled",
        "logbook_runtime_write_enabled",
        "audit_db_write_enabled",
        "timeline_write_enabled",
        "playbook_trust_write_enabled",
        "gateway_queue_write_enabled",
        "telegram_send_enabled",
        "delivery_receipt_write_enabled",
        "production_write_enabled",
        "secret_value_read_enabled",
        "host_or_cluster_command_enabled",
        "destructive_operation_enabled",
        "work_window_transcript_display_allowed",
    }
    unsafe = sorted(field for field in required_false if truth.get(field) is not False)
    if unsafe:
        raise ValueError(f"{label}: live write/send/execution flags must remain false: {unsafe}")

    zero_counts = {
        "runtime_execution_count_24h",
        "km_write_count_24h",
        "logbook_runtime_write_count_24h",
        "audit_db_write_count_24h",
        "timeline_write_count_24h",
        "playbook_trust_write_count_24h",
        "gateway_queue_write_count_24h",
        "telegram_send_count_24h",
        "delivery_receipt_write_count_24h",
        "production_write_count_24h",
        "secret_value_read_count_24h",
        "host_or_cluster_command_count_24h",
        "destructive_operation_count_24h",
    }
    non_zero = sorted(field for field in zero_counts if truth.get(field) != 0)
    if non_zero:
        raise ValueError(f"{label}: live write/send/execution counts must remain zero: {non_zero}")


def _require_result_routes(payload: dict[str, Any], label: str) -> None:
    routes = payload.get("result_routes") or []
    route_ids = {route.get("route_id") for route in routes}
    required = {
        "result_diagnostic_no_action",
        "result_repair_candidate_needs_owner",
        "result_execution_failed_manual",
        "result_verified_no_change",
        "result_evidence_missing",
        "result_policy_blocked",
        "result_provider_unmatched",
        "result_report_zero_signal",
    }
    if route_ids != required:
        raise ValueError(f"{label}: result routes must match {sorted(required)}")

    valid_states = {
        "diagnostic_only",
        "owner_review_required",
        "execution_failed",
        "verified_no_change",
        "blocked_until_evidence",
        "blocked_by_policy",
        "correlation_gap",
        "report_quality_gap",
    }
    for route in routes:
        route_id = route.get("route_id")
        if route.get("result_state") not in valid_states:
            raise ValueError(f"{label}: route {route_id} result_state is invalid")
        if route.get("writes_live_state") is not False:
            raise ValueError(f"{label}: route {route_id} writes_live_state must remain false")
        if not isinstance(route.get("requires_owner_review"), bool):
            raise ValueError(f"{label}: route {route_id} requires_owner_review must be boolean")
        if not isinstance(route.get("ready_for_km_draft"), bool):
            raise ValueError(f"{label}: route {route_id} ready_for_km_draft must be boolean")
        for field in {
            "primary_owner",
            "km_target",
            "logbook_target",
            "audit_target",
            "timeline_target",
            "operator_next_action",
            "blocked_reason",
        }:
            if not route.get(field):
                raise ValueError(f"{label}: route {route_id} must list {field}")
        if not _is_redacted_sha256(route.get("evidence_hash")):
            raise ValueError(f"{label}: route {route_id} must expose evidence_hash")


def _require_writeback_contracts(payload: dict[str, Any], label: str) -> None:
    contracts = payload.get("writeback_contracts") or []
    contract_ids = {contract.get("contract_id") for contract in contracts}
    required = {
        "contract_km_review_draft",
        "contract_logbook_evidence_append",
        "contract_audit_trail_entry",
        "contract_incident_timeline_handoff",
        "contract_playbook_trust_candidate",
        "contract_operator_handoff_packet",
    }
    if contract_ids != required:
        raise ValueError(f"{label}: writeback contracts must match {sorted(required)}")
    for contract in contracts:
        contract_id = contract.get("contract_id")
        if contract.get("write_enabled") is not False:
            raise ValueError(f"{label}: contract {contract_id} write_enabled must remain false")
        if contract.get("runtime_writer_enabled") is not False:
            raise ValueError(f"{label}: contract {contract_id} runtime_writer_enabled must remain false")
        if not contract.get("required_fields"):
            raise ValueError(f"{label}: contract {contract_id} must list required_fields")
        if not contract.get("blocker_summary"):
            raise ValueError(f"{label}: contract {contract_id} must list blocker_summary")
        if not _is_redacted_sha256(contract.get("evidence_hash")):
            raise ValueError(f"{label}: contract {contract_id} must expose evidence_hash")


def _require_audit_checkpoints(payload: dict[str, Any], label: str) -> None:
    checkpoints = payload.get("audit_checkpoints") or []
    checkpoint_ids = {checkpoint.get("checkpoint_id") for checkpoint in checkpoints}
    required = {
        "checkpoint_result_classification",
        "checkpoint_evidence_hash",
        "checkpoint_owner_next_action",
        "checkpoint_km_draft_review",
        "checkpoint_logbook_evidence",
        "checkpoint_timeline_handoff",
        "checkpoint_redaction_boundary",
    }
    if checkpoint_ids != required:
        raise ValueError(f"{label}: audit checkpoints must match {sorted(required)}")
    for checkpoint in checkpoints:
        checkpoint_id = checkpoint.get("checkpoint_id")
        if checkpoint.get("creates_runtime_action") is not False:
            raise ValueError(f"{label}: checkpoint {checkpoint_id} creates_runtime_action must remain false")
        if checkpoint.get("status") not in {"ready", "needs_owner_review", "blocked_by_policy"}:
            raise ValueError(f"{label}: checkpoint {checkpoint_id} status is invalid")
        if not checkpoint.get("failure_if_missing"):
            raise ValueError(f"{label}: checkpoint {checkpoint_id} must list failure_if_missing")


def _require_operator_handoffs(payload: dict[str, Any], label: str) -> None:
    handoffs = payload.get("operator_handoffs") or []
    handoff_ids = {handoff.get("handoff_id") for handoff in handoffs}
    required = {
        "handoff_manual_fix_or_rollback",
        "handoff_collect_missing_repair_evidence",
        "handoff_provider_correlation_review",
        "handoff_km_owner_review",
        "handoff_report_quality_review",
    }
    if handoff_ids != required:
        raise ValueError(f"{label}: operator handoffs must match {sorted(required)}")
    for handoff in handoffs:
        handoff_id = handoff.get("handoff_id")
        if handoff.get("creates_runtime_action") is not False:
            raise ValueError(f"{label}: handoff {handoff_id} creates_runtime_action must remain false")
        if handoff.get("requires_human_review") is not True:
            raise ValueError(f"{label}: handoff {handoff_id} requires_human_review must remain true")
        if not handoff.get("human_instruction"):
            raise ValueError(f"{label}: handoff {handoff_id} must list human_instruction")


def _require_redaction_contract(payload: dict[str, Any], label: str) -> None:
    contract = payload.get("display_redaction_contract") or {}
    required_false = {
        "raw_prompt_display_allowed",
        "private_reasoning_display_allowed",
        "secret_value_display_allowed",
        "raw_telegram_payload_display_allowed",
        "work_window_transcript_display_allowed",
    }
    if contract.get("redaction_required") is not True:
        raise ValueError(f"{label}: display redaction must remain required")
    unsafe = sorted(field for field in required_false if contract.get(field) is not False)
    if unsafe:
        raise ValueError(f"{label}: display redaction fields must remain false: {unsafe}")


def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
    rollups = payload.get("rollups") or {}
    truth = payload.get("result_audit_truth") or {}
    routes = payload.get("result_routes") or []
    contracts = payload.get("writeback_contracts") or []
    checkpoints = payload.get("audit_checkpoints") or []
    handoffs = payload.get("operator_handoffs") or []
    blocked_states = {"blocked_until_evidence", "blocked_by_policy", "correlation_gap"}

    expected = {
        "result_route_count": len(routes),
        "owner_next_action_ready_count": sum(1 for route in routes if bool(route.get("operator_next_action"))),
        "requires_owner_review_count": sum(1 for route in routes if route.get("requires_owner_review") is True),
        "ready_for_km_draft_count": sum(1 for route in routes if route.get("ready_for_km_draft") is True),
        "blocked_result_count": sum(1 for route in routes if route.get("result_state") in blocked_states),
        "writeback_contract_count": len(contracts),
        "audit_checkpoint_count": len(checkpoints),
        "operator_handoff_count": len(handoffs),
        "runtime_execution_count": truth.get("runtime_execution_count_24h"),
        "km_write_count": truth.get("km_write_count_24h"),
        "logbook_runtime_write_count": truth.get("logbook_runtime_write_count_24h"),
        "audit_db_write_count": truth.get("audit_db_write_count_24h"),
        "timeline_write_count": truth.get("timeline_write_count_24h"),
        "playbook_trust_write_count": truth.get("playbook_trust_write_count_24h"),
        "gateway_queue_write_count": truth.get("gateway_queue_write_count_24h"),
        "telegram_send_count": truth.get("telegram_send_count_24h"),
        "production_write_count": truth.get("production_write_count_24h"),
        "secret_value_read_count": truth.get("secret_value_read_count_24h"),
        "destructive_operation_count": truth.get("destructive_operation_count_24h"),
    }
    mismatches = {
        key: {"expected": expected_value, "actual": rollups.get(key)}
        for key, expected_value in expected.items()
        if rollups.get(key) != expected_value
    }
    if mismatches:
        raise ValueError(f"{label}: rollup counts mismatch: {mismatches}")


def _is_redacted_sha256(value: Any) -> bool:
    if not isinstance(value, str):
        return False
    if not value.startswith("sha256:") or len(value) != 71:
        return False
    return all(char in "0123456789abcdef" for char in value.removeprefix("sha256:"))
