"""
OpenAI Agents SDK Coordinator Replay Adapter
===========================================

Deterministic offline adapter for the `openai_agents_sdk_coordinator` market
candidate. The OpenAI Agents SDK is not installed in this repo environment, so
this module models the coordinator boundary without adding dependencies or
calling OpenAI APIs.

It never executes tools, never writes production systems, never sends messages,
and never reads fixture labels.
"""

from __future__ import annotations

import json
import time
from dataclasses import dataclass
from typing import Any

from src.services.agent_market_candidate_adapter import get_market_candidate_spec
from src.services.agent_replay_input import assert_no_evaluation_label_leak

OPENAI_COORDINATOR_CANDIDATE_ID = "openai_agents_sdk_coordinator"


@dataclass(frozen=True)
class OpenAICoordinatorDecision:
    """Candidate replay result produced by the OpenAI-shaped coordinator."""

    payload: dict[str, Any]

    def to_dict(self) -> dict[str, Any]:
        return dict(self.payload)


def build_openai_coordinator_candidate_result(
    candidate_input: dict[str, Any],
) -> OpenAICoordinatorDecision:
    """Build one offline OpenAI coordinator replay result."""
    started = time.perf_counter()
    assert_no_evaluation_label_leak(candidate_input)
    spec = get_market_candidate_spec(OPENAI_COORDINATOR_CANDIDATE_ID)
    incident_id = str(candidate_input.get("incident_id", "")).strip()
    run_id = str(candidate_input.get("run_id", "")).strip()
    if not incident_id or not run_id:
        raise ValueError("candidate input must include incident_id and run_id")

    context = dict(candidate_input.get("incident_context") or {})
    state = _build_state(context)
    route = _route_specialist(state)
    plan = _plan_for_route(state, route)
    risk_level = _risk_level(state, plan)
    requires_human_approval = _requires_human_approval(risk_level, plan)
    trace_events = _trace_events(state, route, plan, risk_level, requires_human_approval)
    latency_ms = (time.perf_counter() - started) * 1000

    return OpenAICoordinatorDecision(
        payload={
            "schema_version": "agent_candidate_replay_result_v1",
            "run_id": run_id,
            "incident_id": incident_id,
            "candidate_id": spec.candidate_id,
            "candidate_role": spec.candidate_role,
            "proposed_action": plan["proposed_action"],
            "action_plan": plan["action_plan"],
            "risk_level": risk_level,
            "requires_human_approval": requires_human_approval,
            "blocked_by_policy": plan["blocked_by_policy"],
            "fallback_used": False,
            "trace_complete": True,
            "trace_events": trace_events,
            "rca_correct": None,
            "tool_dry_run_pass": None,
            "repair_success": None,
            "false_repair": False,
            "latency_ms": latency_ms,
            "cost_usd": 0,
            "error": None,
            "metadata": {
                "adapter_mode": "deterministic_offline_coordinator_boundary",
                "candidate_framework": "openai_agents_sdk",
                "sdk_dependency": "openai_agents_sdk_package_not_installed",
                "openai_api_calls": False,
                "new_dependency_added": False,
                "coordinator_route": route,
                "handoff_targets": _handoff_targets(route, risk_level),
                "guardrail_checks": [
                    "answer_key_leak_check",
                    "dangerous_action_block",
                    "human_approval_for_risky_actions",
                    "trace_required",
                ],
                "source": "openai_agents_sdk_coordinator_offline_adapter",
            },
        }
    )


def build_openai_coordinator_candidate_results(
    candidate_inputs: list[dict[str, Any]],
) -> list[OpenAICoordinatorDecision]:
    """Build many OpenAI coordinator replay results."""
    return [
        build_openai_coordinator_candidate_result(candidate_input)
        for candidate_input in candidate_inputs
    ]


def _build_state(context: dict[str, Any]) -> dict[str, Any]:
    haystack = json.dumps(context, ensure_ascii=False, sort_keys=True).lower()
    severity = str(context.get("severity") or "P3").strip().upper()
    status = str(context.get("status") or "").strip().lower()
    category = str(context.get("alert_category") or "general").strip().lower()
    alertname = str(context.get("alertname") or "").strip()
    service = _primary_service(context)
    namespace = _namespace(context)
    return {
        "alertname": alertname,
        "category": category,
        "severity": severity,
        "status": status,
        "service": service,
        "namespace": namespace,
        "haystack": haystack,
        "is_resolved": status == "resolved",
        "is_backup": "backup" in haystack,
        "is_postgres": any(marker in haystack for marker in ("postgres", "deadlock", "pg_")),
        "is_kubernetes": any(marker in haystack for marker in ("pod", "deployment", "kubernetes", "k8s")),
        "is_host": any(marker in haystack for marker in ("host", "disk", "filesystem", "systemd")),
        "is_container": any(marker in haystack for marker in ("docker", "container", "cadvisor", "cpu", "memory")),
        "is_aiops": any(marker in haystack for marker in ("flywheel", "openclaw", "awooop", "agent")),
        "is_security": any(marker in haystack for marker in ("secret", "token", "tls", "certificate", "auth")),
    }


def _route_specialist(state: dict[str, Any]) -> str:
    if state["is_resolved"]:
        return "observer"
    if state["is_security"]:
        return "security_reviewer"
    if state["is_backup"]:
        return "backup_sre"
    if state["is_postgres"]:
        return "database_sre"
    if state["is_aiops"]:
        return "aiops_reviewer"
    if state["is_host"]:
        return "host_sre"
    if state["is_kubernetes"] or state["is_container"]:
        return "kubernetes_sre"
    return "incident_triage"


def _plan_for_route(state: dict[str, Any], route: str) -> dict[str, Any]:
    if route == "observer":
        return _safe_observe_plan(state, "incident already resolved; preserve evidence")
    if route == "security_reviewer":
        return _security_plan(state)
    if route == "backup_sre":
        return _backup_plan(state)
    if route == "database_sre":
        return _database_plan(state)
    if route == "aiops_reviewer":
        return _aiops_plan(state)
    if route == "host_sre":
        return _host_plan(state)
    if route == "kubernetes_sre":
        return _kubernetes_plan(state)
    return _safe_observe_plan(state, "insufficient routing evidence; collect read-only context")


def _safe_observe_plan(state: dict[str, Any], reason: str) -> dict[str, Any]:
    return {
        "proposed_action": (
            f"COORDINATE_OBSERVE: {reason}; open read-only incident trace for "
            f"{state['alertname']} on {state['service']}"
        ),
        "blocked_by_policy": True,
        "action_plan": [
            _step("triage", "coordinator", [state["category"], state["severity"]]),
            _step("timeline", "awoooi-api", ["GET", "/api/v1/incidents/{incident_id}/timeline"]),
            _step("handoff", "human", ["review-if-recurs"]),
        ],
    }


def _security_plan(state: dict[str, Any]) -> dict[str, Any]:
    return {
        "proposed_action": (
            "COORDINATE_SECURITY_REVIEW: inspect auth/TLS/secret-related evidence only; "
            "block credential rotation or disclosure until explicit approval"
        ),
        "blocked_by_policy": False,
        "action_plan": [
            _step("classify-secret-risk", "security_reviewer", [state["alertname"], state["service"]]),
            _step("inspect-events", "awoooi-api", ["GET", "/api/v1/incidents/{incident_id}/evidence"]),
            _step("inspect-cert", "prometheus", ["ssl_cert_not_after", state["service"]]),
            _step("approval-gate", "human", ["approve-before-secret-or-auth-change"]),
        ],
    }


def _backup_plan(state: dict[str, Any]) -> dict[str, Any]:
    return {
        "proposed_action": (
            "COORDINATE_BACKUP_SRE: gather backup freshness, job, log, storage, and "
            "offsite evidence; do not delete backups or rotate retention"
        ),
        "blocked_by_policy": False,
        "action_plan": [
            _step("handoff", "backup_sre", ["backup freshness RCA"]),
            _step("inspect-cronjob", "kubectl", ["get", "cronjob", "-A"]),
            _step("inspect-jobs", "kubectl", ["get", "jobs", "-A"]),
            _step("inspect-storage", "prometheus", ["backup_last_success_timestamp", state["service"]]),
        ],
    }


def _database_plan(state: dict[str, Any]) -> dict[str, Any]:
    return {
        "proposed_action": (
            "COORDINATE_DATABASE_SRE: inspect PostgreSQL activity, lock, deadlock, and "
            "connection evidence; do not kill sessions without HITL"
        ),
        "blocked_by_policy": False,
        "action_plan": [
            _step("handoff", "database_sre", ["postgres RCA"]),
            _step("inspect-activity", "postgres", ["select", "pg_stat_activity"]),
            _step("inspect-locks", "postgres", ["select", "pg_locks"]),
            _step("approval-gate", "human", ["approve-before-terminate-backend"]),
        ],
    }


def _aiops_plan(state: dict[str, Any]) -> dict[str, Any]:
    return {
        "proposed_action": (
            "COORDINATE_AIOPS_REVIEW: inspect agent sessions, approval queue, timeline, "
            "and learning gaps before proposing any repair"
        ),
        "blocked_by_policy": False,
        "action_plan": [
            _step("handoff", "aiops_reviewer", ["agent-session RCA"]),
            _step("inspect-agent-sessions", "database", ["select", "agent_sessions"]),
            _step("inspect-approvals", "database", ["select", "approval_records"]),
            _step("inspect-timeline", "database", ["select", "timeline_events"]),
        ],
    }


def _host_plan(state: dict[str, Any]) -> dict[str, Any]:
    return {
        "proposed_action": (
            f"COORDINATE_HOST_SRE: run read-only host diagnostics for {state['service']} "
            "and route any write/restart/reboot through approval"
        ),
        "blocked_by_policy": False,
        "action_plan": [
            _step("handoff", "host_sre", ["host resource RCA"]),
            _step("disk", "ssh", ["df", "-h"]),
            _step("systemd", "ssh", ["systemctl", "status", state["service"]]),
            _step("journal", "ssh", ["journalctl", "--no-pager", "-n", "200"]),
            _step("approval-gate", "human", ["approve-before-restart-or-reboot"]),
        ],
    }


def _kubernetes_plan(state: dict[str, Any]) -> dict[str, Any]:
    return {
        "proposed_action": (
            f"COORDINATE_KUBERNETES_SRE: inspect workload, logs, events, and resource "
            f"signals for {state['service']}; require approval before rollout changes"
        ),
        "blocked_by_policy": False,
        "action_plan": [
            _step("handoff", "kubernetes_sre", ["workload RCA"]),
            _step("describe-workload", "kubectl", ["describe", "deployment", state["service"], "-n", state["namespace"]]),
            _step("read-logs", "kubectl", ["logs", f"deployment/{state['service']}", "-n", state["namespace"], "--tail=200"]),
            _step("inspect-events", "kubectl", ["get", "events", "-n", state["namespace"]]),
            _step("approval-gate", "human", ["approve-before-rollout-or-scale"]),
        ],
    }


def _risk_level(state: dict[str, Any], plan: dict[str, Any]) -> str:
    if state["severity"] == "P0":
        return "critical"
    if state["severity"] == "P1" or state["is_security"]:
        return "high"
    action = json.dumps(plan, ensure_ascii=False).lower()
    if any(marker in action for marker in ("restart", "reboot", "rollout", "scale", "terminate", "secret")):
        return "medium"
    if state["severity"] == "P2":
        return "medium"
    return "low"


def _requires_human_approval(risk_level: str, plan: dict[str, Any]) -> bool:
    action = json.dumps(plan, ensure_ascii=False).lower()
    return risk_level in {"medium", "high", "critical"} or any(
        marker in action
        for marker in ("restart", "reboot", "rollout", "scale", "terminate", "secret", "write")
    )


def _handoff_targets(route: str, risk_level: str) -> list[str]:
    targets = ["coordinator", route]
    if risk_level in {"medium", "high", "critical"}:
        targets.append("human_approver")
    if risk_level in {"high", "critical"}:
        targets.append("independent_reviewer")
    return targets


def _trace_events(
    state: dict[str, Any],
    route: str,
    plan: dict[str, Any],
    risk_level: str,
    requires_human_approval: bool,
) -> list[dict[str, Any]]:
    return [
        {
            "type": "input_loaded",
            "alertname": state["alertname"],
            "service": state["service"],
        },
        {
            "type": "guardrails_checked",
            "answer_key_leak": False,
            "external_api_called": False,
        },
        {
            "type": "specialist_selected",
            "route": route,
        },
        {
            "type": "handoff_planned",
            "targets": _handoff_targets(route, risk_level),
        },
        {
            "type": "risk_reviewed",
            "risk_level": risk_level,
            "requires_human_approval": requires_human_approval,
        },
        {
            "type": "read_only_plan_built",
            "steps": len(plan["action_plan"]),
            "blocked_by_policy": plan["blocked_by_policy"],
        },
    ]


def _step(name: str, tool: str, args: list[str]) -> dict[str, Any]:
    return {
        "name": name,
        "tool": tool,
        "args": args,
        "mode": "read_only",
    }


def _primary_service(context: dict[str, Any]) -> str:
    affected = context.get("affected_services")
    if isinstance(affected, list) and affected:
        return str(affected[0]).strip() or "unknown-service"
    service = context.get("service") or context.get("target_service")
    return str(service or "unknown-service").strip()


def _namespace(context: dict[str, Any]) -> str:
    namespace = context.get("namespace") or context.get("kubernetes_namespace")
    return str(namespace or "awoooi-prod").strip()
