"""
AI Agent proactive operations and version lifecycle contract snapshot.

Loads the latest committed, read-only contract for work that OpenClaw,
Hermes, and NemoTron may proactively perform across version lifecycle,
operations, security, backup, observability, cost, UI smoke, and learning
loops. This module never updates versions, installs tools, enables schedules,
sends Telegram messages, pulls images, mutates hosts, or changes production.
"""

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_proactive_operations_contract_*.json"
_SCHEMA_VERSION = "ai_agent_proactive_operations_contract_v1"


def load_latest_ai_agent_proactive_operations_contract(
    evaluations_dir: Path | None = None,
) -> dict[str, Any]:
    """Load the newest committed AI Agent proactive operations contract."""
    directory = evaluations_dir or _DEFAULT_EVALUATIONS_DIR
    candidates = sorted(directory.glob(_SNAPSHOT_PATTERN))
    if not candidates:
        raise FileNotFoundError(
            f"no AI Agent proactive operations contract 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, _SCHEMA_VERSION, str(latest))
    _require_read_only_boundaries(payload, str(latest))
    _require_rollup_consistency(payload, str(latest))
    _require_delegation_safety(payload, str(latest))
    return payload


def _require_schema(payload: dict[str, Any], expected: str, label: str) -> None:
    actual = payload.get("schema_version")
    if actual != expected:
        raise ValueError(f"{label}: expected schema_version={expected}, got {actual!r}")


def _require_read_only_boundaries(payload: dict[str, Any], label: str) -> None:
    program_status = payload.get("program_status") or {}
    if program_status.get("read_only_mode") is not True:
        raise ValueError(f"{label}: program_status.read_only_mode must be true")
    if program_status.get("runtime_authority") != "contract_only_no_version_or_runtime_update":
        raise ValueError(
            f"{label}: runtime_authority must stay contract_only_no_version_or_runtime_update"
        )

    boundaries = payload.get("approval_boundaries") or {}
    blocked_flags = {
        "runtime_version_update_allowed",
        "package_upgrade_allowed",
        "host_upgrade_allowed",
        "container_pull_allowed",
        "workflow_schedule_enabled",
        "auto_merge_allowed",
        "telegram_direct_send_allowed",
        "secret_plaintext_allowed",
        "paid_external_service_allowed",
        "production_route_change_allowed",
    }
    allowed = sorted(flag for flag in blocked_flags if boundaries.get(flag) is not False)
    if allowed:
        raise ValueError(f"{label}: approval boundaries must remain false: {allowed}")


def _require_rollup_consistency(payload: dict[str, Any], label: str) -> None:
    rollups = payload.get("rollups") or {}
    expected_counts = {
        "version_domain_count": len(payload.get("version_lifecycle_domains") or []),
        "delegable_capability_count": len(payload.get("delegable_capabilities") or []),
        "cadence_count": len(payload.get("cadence_matrix") or []),
        "mcp_tool_count": len(payload.get("mcp_tool_requirements") or []),
        "rag_memory_count": len(payload.get("rag_memory_contract") or []),
        "rollout_task_count": len(payload.get("rollout_tasks") or []),
    }
    mismatched = {
        key: {"expected": expected, "actual": rollups.get(key)}
        for key, expected in expected_counts.items()
        if rollups.get(key) != expected
    }
    if mismatched:
        raise ValueError(f"{label}: rollup counts must match payload sections: {mismatched}")

    auto_execute_allowed_count = sum(
        1
        for capability in payload.get("delegable_capabilities") or []
        if capability.get("automation_level") in {"L4_execute_after_human_approval", "L5_auto_execute"}
    )
    if rollups.get("auto_execute_allowed_count") != auto_execute_allowed_count:
        raise ValueError(f"{label}: rollups.auto_execute_allowed_count mismatch")

    blocked_domain_ids = sorted(
        domain.get("domain_id")
        for domain in payload.get("version_lifecycle_domains") or []
        if domain.get("update_authority") != "auto_update_allowed"
    )
    if sorted(rollups.get("blocked_update_domain_ids") or []) != blocked_domain_ids:
        raise ValueError(f"{label}: rollups.blocked_update_domain_ids mismatch")

    telegram_action_required = sorted(
        capability.get("capability_id")
        for capability in payload.get("delegable_capabilities") or []
        if "action_required" in str(capability.get("telegram_policy") or "")
    )
    if sorted(rollups.get("telegram_action_required_capability_ids") or []) != telegram_action_required:
        raise ValueError(f"{label}: rollups.telegram_action_required_capability_ids mismatch")


def _require_delegation_safety(payload: dict[str, Any], label: str) -> None:
    dangerous_levels = {"L5_auto_execute", "auto_update", "auto_merge"}
    unsafe_capabilities = [
        capability.get("capability_id")
        for capability in payload.get("delegable_capabilities") or []
        if capability.get("automation_level") in dangerous_levels
    ]
    if unsafe_capabilities:
        raise ValueError(f"{label}: capabilities must not auto execute: {unsafe_capabilities}")

    missing_gates = [
        item.get("capability_id") or item.get("domain_id") or item.get("tool_id")
        for section in (
            payload.get("delegable_capabilities") or [],
            payload.get("version_lifecycle_domains") or [],
            payload.get("mcp_tool_requirements") or [],
        )
        for item in section
        if not item.get("approval_gate")
    ]
    if missing_gates:
        raise ValueError(f"{label}: all proactive operation items need approval gates: {missing_gates}")

    external_cadence_enabled = [
        cadence.get("cadence_id")
        for cadence in payload.get("cadence_matrix") or []
        if "external" in str(cadence.get("cadence_id"))
        and cadence.get("allowed_now") is not False
    ]
    if external_cadence_enabled:
        raise ValueError(f"{label}: external cadence must stay disabled until approved")
