"""
IwoooS Wazuh owner evidence preflight readback.

This module only exposes committed, public-safe preflight metadata. It never
queries Wazuh, never reads secret values, and never authorizes active response,
host writes, scans, restarts, reloads, or gateway changes.
"""

from __future__ import annotations

import json
from pathlib import Path
from typing import Any

from src.services.snapshot_paths import default_security_dir

_DEFAULT_SECURITY_DIR = default_security_dir(Path(__file__))
_SNAPSHOT_FILE = "wazuh-agent-visibility-owner-evidence-preflight.snapshot.json"
_EXPECTED_SCHEMA = "wazuh_agent_visibility_owner_evidence_preflight_v1"

_REQUIRED_FALSE_BOUNDARIES = {
    "agent_identity_public_display_allowed",
    "host_write_authorized",
    "internal_ip_public_display_allowed",
    "raw_wazuh_payload_storage_allowed",
    "runtime_execution_authorized",
    "secret_value_collection_allowed",
    "wazuh_active_response_authorized",
    "wazuh_api_live_query_authorized",
}


def load_latest_iwooos_wazuh_owner_evidence_preflight(
    security_dir: Path | None = None,
) -> dict[str, Any]:
    """Load the committed Wazuh owner evidence preflight as a public-safe payload."""
    directory = security_dir or _DEFAULT_SECURITY_DIR
    snapshot = _load_snapshot(directory)
    _require_boundaries(snapshot)

    summary = _summary(snapshot)
    contract = snapshot.get("registry_export_contract")
    contract = contract if isinstance(contract, dict) else {}
    merged_summary = {
        "required_field_count": _int(summary.get("required_field_count")),
        "reviewer_check_count": _int(summary.get("reviewer_check_count")),
        "outcome_lane_count": _int(summary.get("outcome_lane_count")),
        "forbidden_payload_count": _int(summary.get("forbidden_payload_count")),
        "expected_scope_alias_count": _int(summary.get("expected_scope_alias_count")),
        "per_host_required_field_count": _int(summary.get("per_host_required_field_count")),
        "allowed_collection_method_count": _len(contract.get("allowed_collection_methods")),
        "registry_export_received_count": _int(summary.get("registry_export_received_count")),
        "registry_export_accepted_count": _int(summary.get("registry_export_accepted_count")),
        "owner_evidence_received_count": _int(summary.get("owner_evidence_received_count")),
        "owner_evidence_accepted_count": _int(summary.get("owner_evidence_accepted_count")),
        "owner_evidence_rejected_count": _int(summary.get("owner_evidence_rejected_count")),
        "owner_evidence_quarantined_count": _int(summary.get("owner_evidence_quarantined_count")),
        "runtime_gate_count": _int(summary.get("runtime_gate_count")),
        "wazuh_api_live_query_authorized_count": 0,
        "active_response_authorized_count": _int(summary.get("active_response_authorized_count")),
        "host_write_authorized_count": _int(summary.get("host_write_authorized_count")),
        "secret_value_collection_allowed_count": _int(summary.get("secret_value_collection_allowed_count")),
    }

    return {
        "schema_version": "iwooos_wazuh_owner_evidence_preflight_readback_v1",
        "status": snapshot.get("status", "owner_evidence_preflight_ready_no_runtime_action"),
        "mode": "committed_snapshot_readback_redacted_metadata_only",
        "source_refs": [
            f"docs/security/{_SNAPSHOT_FILE}",
            "scripts/security/wazuh-agent-visibility-owner-evidence-preflight.py",
        ],
        "summary": merged_summary,
        "items": _items(merged_summary),
        "boundary_markers": _boundary_markers(merged_summary),
        "boundaries": {
            "wazuh_api_live_query_authorized": False,
            "wazuh_active_response_authorized": False,
            "host_write_authorized": False,
            "secret_value_collection_allowed": False,
            "raw_wazuh_payload_storage_allowed": False,
            "agent_identity_public_display_allowed": False,
            "internal_ip_public_display_allowed": False,
            "runtime_execution_authorized": False,
            "not_authorization": True,
        },
        "no_false_green_rules": [
            "負責人證據預檢 ready 不代表已收件或已接受",
            "Wazuh 儀表板可見不是 manager registry counts 已驗收",
            "Dashboard index pattern 三綠勾不可替代 API connection、API version 或 manager registry",
            "agent service active、TCP 連線或舊截圖不可替代逐主機 registry matrix",
            "收件封包若夾帶原始紀錄、內網識別、agent 原名或機密，必須隔離，不得渲染到前台",
            "active response、host write、firewall、Nginx、Docker、K8s 或 secret 變更一律不是這個預檢授權",
        ],
    }


def _load_snapshot(directory: Path) -> dict[str, Any]:
    path = directory / _SNAPSHOT_FILE
    if not path.is_file():
        raise FileNotFoundError(f"{path}: Wazuh 負責人證據預檢快照不存在")
    with path.open(encoding="utf-8") as handle:
        payload = json.load(handle)
    if not isinstance(payload, dict):
        raise ValueError(f"{path}: expected JSON object")
    if payload.get("schema_version") != _EXPECTED_SCHEMA:
        raise ValueError(f"{path}: expected schema_version={_EXPECTED_SCHEMA}")
    return payload


def _summary(payload: dict[str, Any]) -> dict[str, Any]:
    summary = payload.get("summary")
    return summary if isinstance(summary, dict) else {}


def _int(value: Any) -> int:
    return value if isinstance(value, int) else 0


def _len(value: Any) -> int:
    return len(value) if isinstance(value, list) else 0


def _items(summary: dict[str, int]) -> list[dict[str, Any]]:
    return [
        _item(
            "scope_aliases",
            "EV-0",
            "scope_aliases_ready",
            "warn",
            {
                "expected_scope_aliases": summary["expected_scope_alias_count"],
                "allowed_collection_methods": summary["allowed_collection_method_count"],
            },
        ),
        _item(
            "registry_counts",
            "EV-1",
            "waiting_redacted_counts",
            "warn",
            {
                "registry_export_received": summary["registry_export_received_count"],
                "registry_export_accepted": summary["registry_export_accepted_count"],
            },
        ),
        _item(
            "per_host_matrix",
            "EV-2",
            "waiting_per_host_matrix",
            "warn",
            {"per_host_required_fields": summary["per_host_required_field_count"]},
        ),
        _item(
            "time_window",
            "EV-3",
            "waiting_time_window",
            "warn",
            {"owner_received": summary["owner_evidence_received_count"]},
        ),
        _item(
            "health_refs",
            "EV-4",
            "waiting_health_refs",
            "warn",
            {"reviewer_checks": summary["reviewer_check_count"]},
        ),
        _item(
            "redaction",
            "EV-5",
            "reject_sensitive_payloads",
            "locked",
            {
                "forbidden_payloads": summary["forbidden_payload_count"],
                "quarantined": summary["owner_evidence_quarantined_count"],
            },
        ),
        _item(
            "owner_decision",
            "EV-6",
            "waiting_owner_decision",
            "warn",
            {
                "owner_received": summary["owner_evidence_received_count"],
                "owner_accepted": summary["owner_evidence_accepted_count"],
            },
        ),
        _item(
            "runtime_boundary",
            "EV-7",
            "runtime_closed",
            "locked",
            {
                "runtime_gate": summary["runtime_gate_count"],
                "live_query": summary["wazuh_api_live_query_authorized_count"],
                "active_response": summary["active_response_authorized_count"],
                "host_write": summary["host_write_authorized_count"],
            },
        ),
    ]


def _item(
    item_id: str,
    check: str,
    state_key: str,
    tone: str,
    metrics: dict[str, int],
) -> dict[str, Any]:
    return {
        "item_id": item_id,
        "check": check,
        "state_key": state_key,
        "tone": tone,
        "metrics": metrics,
    }


def _boundary_markers(summary: dict[str, int]) -> list[str]:
    return [
        f"必要欄位={summary['required_field_count']}",
        f"審查檢查={summary['reviewer_check_count']}",
        f"結果分流={summary['outcome_lane_count']}",
        f"拒收敏感類型={summary['forbidden_payload_count']}",
        f"公開節點別名={summary['expected_scope_alias_count']}",
        f"逐主機矩陣欄位={summary['per_host_required_field_count']}",
        f"允許收集方式={summary['allowed_collection_method_count']}",
        f"registry export 已收件={summary['registry_export_received_count']}",
        f"registry export 已接受={summary['registry_export_accepted_count']}",
        f"負責人證據已收件={summary['owner_evidence_received_count']}",
        f"負責人證據已接受={summary['owner_evidence_accepted_count']}",
        f"負責人證據已隔離={summary['owner_evidence_quarantined_count']}",
        f"執行期閘門={summary['runtime_gate_count']}",
        f"Wazuh 即時查詢={summary['wazuh_api_live_query_authorized_count']}",
        f"Wazuh 主動回應={summary['active_response_authorized_count']}",
        f"主機寫入={summary['host_write_authorized_count']}",
        f"機密明文收集={summary['secret_value_collection_allowed_count']}",
        "原始 Wazuh 載荷保存=false",
        "agent 身分前台顯示=false",
        "內網識別前台顯示=false",
        "不是執行授權=true",
    ]


def _require_boundaries(payload: dict[str, Any]) -> None:
    summary = _summary(payload)
    for key in (
        "registry_export_accepted_count",
        "owner_evidence_accepted_count",
        "runtime_gate_count",
        "active_response_authorized_count",
        "host_write_authorized_count",
        "secret_value_collection_allowed_count",
    ):
        if _int(summary.get(key)) != 0:
            raise ValueError(f"Wazuh 負責人證據預檢 summary.{key} 必須維持 0")

    boundaries = payload.get("execution_boundaries")
    if not isinstance(boundaries, dict):
        raise ValueError("Wazuh 負責人證據預檢 execution_boundaries 缺失")
    for key in _REQUIRED_FALSE_BOUNDARIES:
        if boundaries.get(key) is not False:
            raise ValueError(f"Wazuh 負責人證據預檢 execution_boundaries.{key} 必須維持 false")
    if boundaries.get("not_authorization") is not True:
        raise ValueError("Wazuh 負責人證據預檢 not_authorization 必須維持 true")
