"""AI Agent LOG controlled writeback plan readback.

Builds the machine-readable target selectors, source-of-truth diffs,
check-mode gates, rollback refs, and post-apply verifier refs needed to turn
verified LOG feedback receipts into a controlled KM / RAG / PlayBook / MCP /
AI Agent writeback lane. This module prepares the apply plan only; it does not
perform writes, call MCP tools, trigger workflows, or persist raw log payloads.
"""

from __future__ import annotations

from typing import Any

from src.services.ai_agent_log_feedback_receipt_dry_run import (
    load_latest_ai_agent_log_feedback_receipt_dry_run,
)
from src.services.ai_agent_log_post_write_verifier_dry_run import (
    load_latest_ai_agent_log_post_write_verifier_dry_run,
)

_SCHEMA_VERSION = "ai_agent_log_controlled_writeback_plan_readback_v1"
_VERIFIER_READY_STATUS = "post_write_verifier_dry_run_ready"
_FEEDBACK_READY_STATUS = "trusted_feedback_receipt_dry_run_ready"
_TARGETS = ("km", "rag", "playbook", "mcp", "verifier", "ai_agent")


def load_latest_ai_agent_log_controlled_writeback_plan_readback() -> dict[str, Any]:
    """Return a controlled apply plan for verified LOG feedback receipts."""
    verifier = load_latest_ai_agent_log_post_write_verifier_dry_run()
    feedback = load_latest_ai_agent_log_feedback_receipt_dry_run()
    receipts = _candidate_receipts(feedback)
    verifier_ready = (
        verifier.get("status") == _VERIFIER_READY_STATUS
        and verifier.get("active_blockers") == []
        and (verifier.get("rollups") or {}).get("controlled_writeback_next_step_ready")
        is True
    )
    feedback_ready = (
        feedback.get("status") == _FEEDBACK_READY_STATUS
        and feedback.get("active_blockers") == []
        and (feedback.get("rollups") or {}).get("dry_run_ready") is True
    )
    writeback_plans = _writeback_plans(receipts)
    active_blockers = _active_blockers(
        verifier_ready=verifier_ready,
        feedback_ready=feedback_ready,
        receipts=receipts,
        writeback_plans=writeback_plans,
    )

    return {
        "schema_version": _SCHEMA_VERSION,
        "priority": "P1-LOG-KM-RAG-MCP-PLAYBOOK",
        "scope": "ai_agent_log_controlled_writeback_plan",
        "status": (
            "controlled_writeback_plan_ready"
            if not active_blockers
            else "blocked_waiting_controlled_writeback_plan_inputs"
        ),
        "readback": {
            "workplan_id": "P1-LOG-CONTROLLED-WRITEBACK-PLAN",
            "workplan_title": "LOG feedback controlled KM / RAG / MCP / PlayBook / AI Agent writeback plan",
            "feedback_schema_version": feedback.get("schema_version"),
            "feedback_status": feedback.get("status"),
            "verifier_schema_version": verifier.get("schema_version"),
            "verifier_status": verifier.get("status"),
            "safe_next_step": "execute_controlled_writeback_apply_with_post_apply_verifier",
        },
        "controlled_apply": {
            "mode": "controlled_apply_prepared",
            "target_selector_required": True,
            "source_of_truth_diff_required": True,
            "check_mode_required": True,
            "rollback_required": True,
            "post_apply_verifier_required": True,
            "owner_review_required_for_low_medium_high": False,
            "critical_break_glass_required": True,
        },
        "writeback_plans": writeback_plans,
        "target_rollups": _target_rollups(writeback_plans),
        "rollups": {
            "target_count": len(_TARGETS),
            "candidate_receipt_count": len(receipts),
            "writeback_plan_count": len(writeback_plans),
            "ready_writeback_plan_count": sum(
                1 for plan in writeback_plans if plan["status"] == "controlled_apply_ready"
            ),
            "current_blocker_recovery_plan_count": sum(
                1 for plan in writeback_plans if plan.get("current_blocker_recovery")
            ),
            "current_blocker_recovery_unique_count": len(
                _unique(
                    [
                        str((plan.get("current_blocker_recovery") or {}).get("blocker_id"))
                        for plan in writeback_plans
                        if plan.get("current_blocker_recovery")
                    ]
                )
            ),
            "check_mode_plan_count": sum(
                1 for plan in writeback_plans if plan["check_mode"]["enabled"] is True
            ),
            "rollback_plan_count": sum(
                1 for plan in writeback_plans if plan["rollback"]["required"] is True
            ),
            "post_apply_verifier_plan_count": sum(
                1
                for plan in writeback_plans
                if plan["post_apply_verifier"]["required"] is True
            ),
            "controlled_writeback_plan_ready": not active_blockers,
            "runtime_write_performed": False,
        },
        "active_blockers": active_blockers,
        "operation_boundaries": {
            "plan_readback_only": True,
            "km_write_performed": False,
            "rag_index_write_performed": False,
            "playbook_trust_write_performed": False,
            "mcp_tool_call_performed": False,
            "agent_runtime_action_performed": False,
            "workflow_trigger_performed": False,
            "raw_log_payload_persisted": False,
            "secret_value_collection_allowed": False,
            "github_api_used": False,
        },
    }


def _candidate_receipts(feedback: dict[str, Any]) -> list[dict[str, Any]]:
    receipts = feedback.get("candidate_receipts")
    if not isinstance(receipts, list):
        return []
    return [receipt for receipt in receipts if isinstance(receipt, dict)]


def _writeback_plans(receipts: list[dict[str, Any]]) -> list[dict[str, Any]]:
    plans = []
    for receipt in receipts:
        target = str(receipt.get("target") or "")
        source_sample_id = str(receipt.get("source_sample_id") or "")
        receipt_id = str(receipt.get("receipt_id") or "")
        plan_id = f"log-feedback-writeback::{target}::{source_sample_id}"
        current_blocker_recovery = _current_blocker_recovery(receipt)
        plan = {
            "plan_id": plan_id,
            "receipt_id": receipt_id,
            "target": target,
            "status": "controlled_apply_ready",
            "risk_tier": "medium" if target in {"km", "rag", "playbook"} else "low",
            "target_selector": {
                "project_id": receipt.get("project_id"),
                "product": receipt.get("product"),
                "service": receipt.get("service"),
                "package": receipt.get("package"),
                "tool": receipt.get("tool"),
                "source_system": receipt.get("source_system"),
                "source_sample_id": source_sample_id,
                "target_surface": _target_surface(target),
            },
            "source_of_truth_diff": {
                "current_state": "metadata_only_feedback_not_written",
                "desired_state": "metadata_only_feedback_receipt_bound_to_target",
                "delta_kind": _delta_kind(target),
                "raw_payload_included": False,
                "redaction_state": receipt.get("redaction_state"),
                "observed_event_count": receipt.get("observed_event_count"),
                "observed_field_count": receipt.get("observed_field_count"),
            },
            "check_mode": {
                "enabled": True,
                "checks": [
                    "target_selector_resolves_single_surface",
                    "metadata_only_redaction_state",
                    "raw_log_payload_absent",
                    "post_apply_verifier_ref_present",
                ],
            },
            "rollback": {
                "required": True,
                "rollback_ref": f"rollback://ai-agent-log-feedback/{target}/{source_sample_id}",
                "strategy": "mark_receipt_superseded_and_remove_target_binding",
            },
            "post_apply_verifier": {
                "required": True,
                "verifier_ref": f"post-write-verifier://ai-agent-log-feedback/{target}/{source_sample_id}",
                "canonical_readback": (
                    "/api/v1/agents/agent-log-controlled-writeback-plan-readback"
                ),
            },
            "write_enabled_by_plan": False,
        }
        if current_blocker_recovery:
            plan["current_blocker_recovery"] = current_blocker_recovery
        plans.append(plan)
    return plans


def _current_blocker_recovery(receipt: dict[str, Any]) -> dict[str, Any] | None:
    classification = receipt.get("classification")
    if not isinstance(classification, dict):
        return None
    blocker_id = str(classification.get("current_blocker") or "")
    if not blocker_id:
        return None
    source_sample_id = str(receipt.get("source_sample_id") or "")
    registry_v2_status = classification.get("registry_v2_status")
    registry_v2_ready = _registry_v2_ready(registry_v2_status)
    current_cd_status = str(classification.get("current_cd_run_status") or "")
    harbor_repair_status = str(
        classification.get("harbor_110_repair_run_status") or ""
    )
    cd_failed_after_registry_ready = bool(
        registry_v2_ready and current_cd_status in {"Failure", "Blocked", "Canceled"}
    )
    historical_harbor_repair_failed_after_registry_ready = bool(
        registry_v2_ready and harbor_repair_status in {"Failure", "Blocked"}
    )
    harbor_repair_failed_after_registry_ready = bool(
        historical_harbor_repair_failed_after_registry_ready
        and blocker_id != "controlled_cd_lane_guardrails_blocked"
    )
    ssh_auth_classification = str(
        classification.get("ssh_auth_classification") or ""
    )
    external_control_path_blocker = ""
    if ssh_auth_classification not in {"", "ssh_control_path_ready"}:
        external_control_path_blocker = ssh_auth_classification

    recovery = {
        "source_sample_id": source_sample_id,
        "project_id": str(receipt.get("project_id") or ""),
        "product": str(receipt.get("product") or ""),
        "service": str(receipt.get("service") or ""),
        "package": str(receipt.get("package") or ""),
        "tool": str(receipt.get("tool") or ""),
        "source_system": str(receipt.get("source_system") or ""),
        "incident_id": str(classification.get("incident_id") or ""),
        "blocker_id": blocker_id,
        "risk_tier": str(classification.get("risk_tier") or "unknown"),
        "runner_label": str(classification.get("runner_label") or ""),
        "ssh_auth_classification": str(
            classification.get("ssh_auth_classification") or ""
        ),
        "node_load_classifier": str(classification.get("node_load_classifier") or ""),
        "registry_v2_status": registry_v2_status,
        "registry_v2_ready": registry_v2_ready,
        "registry_v2_status_classifier": _registry_v2_status_classifier(
            registry_v2_status
        ),
        "deployment_closure_state": _deployment_closure_state(
            registry_v2_ready=registry_v2_ready,
            current_cd_status=current_cd_status,
            harbor_repair_failed_after_registry_ready=(
                harbor_repair_failed_after_registry_ready
            ),
            fallback=str(classification.get("deployment_closure_state") or ""),
        ),
        "deploy_marker_readback_required": bool(
            registry_v2_ready
            and (
                cd_failed_after_registry_ready
                or harbor_repair_failed_after_registry_ready
                or classification.get("deploy_marker_readback_required") is True
            )
        ),
        "current_cd_run_id": str(classification.get("current_cd_run_id") or ""),
        "current_cd_run_status": current_cd_status,
        "current_cd_commit_sha": str(
            classification.get("current_cd_commit_sha") or ""
        ),
        "cd_failed_after_registry_ready": cd_failed_after_registry_ready,
        "harbor_110_repair_run_id": str(
            classification.get("harbor_110_repair_run_id") or ""
        ),
        "harbor_110_repair_run_status": harbor_repair_status,
        "harbor_110_repair_failed_after_registry_ready": (
            harbor_repair_failed_after_registry_ready
        ),
        "harbor_110_repair_failure_classifier": str(
            classification.get("harbor_110_repair_failure_classifier") or ""
        ),
        "controlled_recovery_package": str(
            classification.get("controlled_recovery_package") or ""
        ),
        "post_apply_verifier": str(classification.get("post_apply_verifier") or ""),
        "safe_next_step": str(classification.get("safe_next_step") or ""),
        "runtime_apply_required_on_110_local_console": blocker_id
        in {
            "harbor_110_repair_no_matching_runner",
            "harbor_110_remote_control_channel_unavailable",
            "harbor_110_remote_ssh_publickey_auth_stalled",
        },
        "external_control_path_blocker": external_control_path_blocker,
        "metadata_only": True,
    }
    recovery["controlled_local_console_execution_plan"] = _list_of_dicts(
        classification.get("controlled_local_console_execution_plan")
    )
    recovery["post_recovery_readback_commands"] = _list_of_strings(
        classification.get("post_recovery_readback_commands")
    )
    recovery["forbidden_runtime_actions"] = _list_of_strings(
        classification.get("forbidden_runtime_actions")
    )
    return recovery


def _registry_v2_ready(value: Any) -> bool:
    try:
        return int(str(value)) in {200, 401}
    except (TypeError, ValueError):
        return False


def _registry_v2_status_classifier(value: Any) -> str:
    try:
        status = int(str(value))
    except (TypeError, ValueError):
        return "unknown"
    if status == 200:
        return "ready_http_200"
    if status == 401:
        return "ready_auth_required_http_401"
    if status:
        return f"blocked_http_{status}"
    return "unknown"


def _deployment_closure_state(
    *,
    registry_v2_ready: bool,
    current_cd_status: str,
    harbor_repair_failed_after_registry_ready: bool,
    fallback: str,
) -> str:
    if registry_v2_ready and current_cd_status in {"Failure", "Blocked", "Canceled"}:
        return "blocked_latest_visible_cd_failure_after_registry_ready"
    if registry_v2_ready and harbor_repair_failed_after_registry_ready:
        return "blocked_harbor_110_repair_failure_after_registry_ready"
    if registry_v2_ready:
        return fallback or "registry_ready_waiting_deploy_marker_readback"
    return fallback or "registry_v2_not_ready"


def _list_of_dicts(value: Any) -> list[dict[str, Any]]:
    if not isinstance(value, list):
        return []
    return [dict(item) for item in value if isinstance(item, dict)]


def _list_of_strings(value: Any) -> list[str]:
    if not isinstance(value, list):
        return []
    return [str(item) for item in value if str(item)]


def _target_rollups(plans: list[dict[str, Any]]) -> list[dict[str, Any]]:
    return [
        {
            "target": target,
            "plan_count": sum(1 for plan in plans if plan.get("target") == target),
            "ready_plan_count": sum(
                1
                for plan in plans
                if plan.get("target") == target
                and plan.get("status") == "controlled_apply_ready"
            ),
            "check_mode_ready": all(
                plan.get("check_mode", {}).get("enabled") is True
                for plan in plans
                if plan.get("target") == target
            ),
            "rollback_ready": all(
                plan.get("rollback", {}).get("required") is True
                for plan in plans
                if plan.get("target") == target
            ),
            "post_apply_verifier_ready": all(
                plan.get("post_apply_verifier", {}).get("required") is True
                for plan in plans
                if plan.get("target") == target
            ),
        }
        for target in _TARGETS
    ]


def _active_blockers(
    *,
    verifier_ready: bool,
    feedback_ready: bool,
    receipts: list[dict[str, Any]],
    writeback_plans: list[dict[str, Any]],
) -> list[str]:
    blockers = []
    if not verifier_ready:
        blockers.append("post_write_verifier_dry_run_not_ready")
    if not feedback_ready:
        blockers.append("feedback_receipt_dry_run_not_ready")
    if not receipts:
        blockers.append("candidate_receipts_missing")
    if len(writeback_plans) != len(receipts):
        blockers.append("writeback_plan_count_mismatch")
    for target in _TARGETS:
        if not any(plan.get("target") == target for plan in writeback_plans):
            blockers.append(f"{target}_writeback_plan_missing")
    for plan in writeback_plans:
        if plan.get("write_enabled_by_plan") is not False:
            blockers.append(f"{plan.get('plan_id')}:write_enabled_by_plan_not_false")
        if plan.get("source_of_truth_diff", {}).get("raw_payload_included") is not False:
            blockers.append(f"{plan.get('plan_id')}:raw_payload_included")
    return _unique(blockers)


def _target_surface(target: str) -> str:
    return {
        "km": "knowledge_memory",
        "rag": "rag_chunk_index",
        "playbook": "playbook_trust_learning",
        "mcp": "mcp_audit_context",
        "verifier": "post_apply_verifier_feedback",
        "ai_agent": "agent_decision_context",
    }.get(target, "unknown")


def _delta_kind(target: str) -> str:
    return {
        "km": "append_km_memory_receipt",
        "rag": "index_metadata_only_rag_chunk",
        "playbook": "append_playbook_trust_signal",
        "mcp": "append_mcp_audit_feedback",
        "verifier": "append_post_apply_verifier_feedback",
        "ai_agent": "publish_agent_context_receipt",
    }.get(target, "unknown")


def _unique(values: list[str]) -> list[str]:
    seen = set()
    result = []
    for value in values:
        if value in seen:
            continue
        seen.add(value)
        result.append(value)
    return result
