"""P0-006 reboot auto-recovery SLO scorecard readback.

This loader promotes the committed reboot recovery scorecard and the latest
runtime verifier artifact into a stable API contract. It does not reboot hosts,
restart services, query runtime secrets, or write StockPlatform data.
"""

from __future__ import annotations

import json
import os
import urllib.error
import urllib.parse
import urllib.request
from datetime import datetime
from pathlib import Path
from typing import Any
from zoneinfo import ZoneInfo

from src.services.snapshot_paths import default_operations_dir

_DEFAULT_OPERATIONS_DIR = default_operations_dir(Path(__file__))
_SCORECARD_FILE = "awoooi-reboot-auto-recovery-slo-scorecard.snapshot.json"
_SOURCE_SCHEMA_VERSION = "awoooi_reboot_auto_recovery_slo_scorecard_v1"
_API_SCHEMA_VERSION = "reboot_auto_recovery_slo_scorecard_readback_v1"
_PUBLIC_MAINTENANCE_RUNTIME_FILE_ENV = (
    "AWOOOI_PUBLIC_MAINTENANCE_FALLBACK_READBACK_FILE"
)
_RUNTIME_SCORECARD_FILE_ENV = "AWOOOI_REBOOT_RECOVERY_SLO_SCORECARD_FILE"
_PUBLIC_MAINTENANCE_RUNTIME_DIR_ENV = "AWOOOI_REBOOT_RECOVERY_LOG_DIR"
_RUNTIME_SCORECARD_DIR_ENV = "AWOOOI_REBOOT_RECOVERY_LOG_DIR"
_DEFAULT_REBOOT_RECOVERY_LOG_DIR = Path("/home/wooo/reboot-recovery")
_PUBLIC_MAINTENANCE_RUNTIME_PATTERN = (
    "reboot-auto-recovery-slo-*/public-maintenance-fallback.json"
)
_RUNTIME_SCORECARD_PATTERN = "reboot-auto-recovery-slo-*/scorecard.json"
_PROMETHEUS_READBACK_ENABLED_ENV = "AWOOOI_REBOOT_SLO_PROMETHEUS_READBACK_ENABLED"
_PROMETHEUS_QUERY_URL_ENV = "AWOOOI_REBOOT_SLO_PROMETHEUS_QUERY_URL"
_PROMETHEUS_TIMEOUT_SECONDS_ENV = "AWOOOI_REBOOT_SLO_PROMETHEUS_TIMEOUT_SECONDS"
_DEFAULT_PROMETHEUS_QUERY_URL = "http://192.168.0.110:9090/api/v1/query"
_PROMETHEUS_RUNTIME_QUERIES = {
    "active_blocker": "awoooi_reboot_auto_recovery_slo_active_blocker",
    "primary_blocker": "awoooi_reboot_auto_recovery_slo_primary_blocker",
    "blocker_count": "awoooi_reboot_auto_recovery_slo_blocker_count",
    "ready": "awoooi_reboot_auto_recovery_slo_ready",
    "last_run_timestamp": "awoooi_reboot_auto_recovery_slo_last_run_timestamp",
}
_PROMETHEUS_RUNTIME_COMBINED_QUERY = (
    '{__name__=~"'
    + "|".join(_PROMETHEUS_RUNTIME_QUERIES.values())
    + '"}'
)
_PUBLIC_MAINTENANCE_BLOCKERS = {
    "public_maintenance_fallback_runtime_readback_missing",
    "public_route_raw_5xx_without_maintenance_fallback",
    "public_route_unreachable_without_external_l1_fallback",
}
_PROMETHEUS_SOURCE_CONTROLLED_BLOCKERS = {
    "conversation_event_hot_path_index_migration_source_missing": (
        "conversation_event_hot_path_index_migration_source_present"
    ),
}


def load_latest_reboot_auto_recovery_slo_scorecard(
    operations_dir: Path | None = None,
    public_maintenance_runtime_path: Path | None = None,
    public_maintenance_runtime_dir: Path | None = None,
    runtime_scorecard_path: Path | None = None,
    runtime_scorecard_dir: Path | None = None,
    prometheus_metric_readback: dict[str, Any] | None = None,
    prometheus_query_url: str | None = None,
) -> dict[str, Any]:
    """Load the committed P0-006 scorecard and overlay trusted runtime artifacts."""
    directory = operations_dir or _DEFAULT_OPERATIONS_DIR
    path = directory / _SCORECARD_FILE
    with path.open(encoding="utf-8") as handle:
        scorecard = json.load(handle)

    if not isinstance(scorecard, dict):
        raise ValueError(f"{path}: expected JSON object")
    if scorecard.get("schema_version") != _SOURCE_SCHEMA_VERSION:
        raise ValueError(f"{path}: unsupported schema_version={scorecard.get('schema_version')!r}")

    source_scorecard = scorecard
    runtime_scorecard, runtime_scorecard_source = _load_latest_runtime_scorecard(
        runtime_path=runtime_scorecard_path,
        runtime_dir=runtime_scorecard_dir,
    )
    if runtime_scorecard:
        source_scorecard = runtime_scorecard

    payload = _build_payload(source_scorecard, path)
    _annotate_runtime_scorecard_readback(
        payload=payload,
        committed_scorecard=scorecard,
        runtime_scorecard=runtime_scorecard,
        runtime_scorecard_source=runtime_scorecard_source,
    )
    public_maintenance_runtime = _load_latest_public_maintenance_runtime_readback(
        runtime_path=public_maintenance_runtime_path,
        runtime_dir=public_maintenance_runtime_dir,
    )
    if public_maintenance_runtime:
        apply_public_maintenance_runtime_readback(payload, public_maintenance_runtime)
    metric_readback = prometheus_metric_readback
    if metric_readback is None and _env_flag(_PROMETHEUS_READBACK_ENABLED_ENV):
        metric_readback = _load_reboot_slo_prometheus_metric_readback(
            prometheus_query_url=prometheus_query_url,
        )
    if metric_readback:
        _annotate_prometheus_metric_readback(payload, metric_readback)
        if not runtime_scorecard:
            _apply_prometheus_metric_active_blockers(payload, metric_readback)
    _require_operation_boundaries(payload, str(path))
    return payload


def _load_latest_runtime_scorecard(
    *,
    runtime_path: Path | None = None,
    runtime_dir: Path | None = None,
) -> tuple[dict[str, Any], Path | None]:
    explicit_path = runtime_path or _path_from_env(_RUNTIME_SCORECARD_FILE_ENV)
    if explicit_path:
        payload = _read_json_file(explicit_path)
        return _runtime_scorecard_if_supported(payload), explicit_path

    directory = (
        runtime_dir
        or _path_from_env(_RUNTIME_SCORECARD_DIR_ENV)
        or _DEFAULT_REBOOT_RECOVERY_LOG_DIR
    )
    try:
        candidates = [
            path
            for path in directory.glob(_RUNTIME_SCORECARD_PATTERN)
            if path.is_file()
        ]
    except OSError:
        return {}, None
    if not candidates:
        return {}, None
    for latest in sorted(
        candidates,
        key=lambda path: path.stat().st_mtime,
        reverse=True,
    ):
        payload = _runtime_scorecard_if_supported(_read_json_file(latest))
        if payload:
            return payload, latest
    return {}, None


def _runtime_scorecard_if_supported(payload: dict[str, Any]) -> dict[str, Any]:
    if payload.get("schema_version") != _SOURCE_SCHEMA_VERSION:
        return {}
    return payload


def _annotate_runtime_scorecard_readback(
    *,
    payload: dict[str, Any],
    committed_scorecard: dict[str, Any],
    runtime_scorecard: dict[str, Any],
    runtime_scorecard_source: Path | None,
) -> None:
    runtime_present = bool(runtime_scorecard)
    committed_generated_at = str(committed_scorecard.get("generated_at") or "")
    runtime_generated_at = str(runtime_scorecard.get("generated_at") or "")
    runtime_source_ref = str(runtime_scorecard_source or "")

    payload["snapshot_generated_at"] = committed_generated_at
    payload["runtime_scorecard_readback_present"] = runtime_present
    payload["runtime_scorecard_generated_at"] = runtime_generated_at
    payload["runtime_scorecard_source_ref"] = runtime_source_ref

    readback = _dict(payload.setdefault("readback", {}))
    readback["snapshot_generated_at"] = committed_generated_at
    readback["runtime_scorecard_readback_present"] = runtime_present
    readback["runtime_scorecard_generated_at"] = runtime_generated_at
    readback["runtime_scorecard_source_ref"] = runtime_source_ref

    rollups = _dict(payload.setdefault("rollups", {}))
    rollups["runtime_scorecard_readback_present"] = runtime_present
    rollups["runtime_scorecard_generated_at"] = runtime_generated_at


def _load_latest_public_maintenance_runtime_readback(
    *,
    runtime_path: Path | None = None,
    runtime_dir: Path | None = None,
) -> dict[str, Any]:
    explicit_path = runtime_path or _path_from_env(_PUBLIC_MAINTENANCE_RUNTIME_FILE_ENV)
    if explicit_path:
        return _read_json_file(explicit_path)

    directory = (
        runtime_dir
        or _path_from_env(_PUBLIC_MAINTENANCE_RUNTIME_DIR_ENV)
        or _DEFAULT_REBOOT_RECOVERY_LOG_DIR
    )
    try:
        candidates = [
            path
            for path in directory.glob(_PUBLIC_MAINTENANCE_RUNTIME_PATTERN)
            if path.is_file()
        ]
    except OSError:
        return {}
    if not candidates:
        return {}
    latest = max(candidates, key=lambda path: path.stat().st_mtime)
    return _read_json_file(latest)


def _load_reboot_slo_prometheus_metric_readback(
    *,
    prometheus_query_url: str | None = None,
) -> dict[str, Any]:
    query_url = (
        prometheus_query_url
        or os.environ.get(_PROMETHEUS_QUERY_URL_ENV, "").strip()
        or _DEFAULT_PROMETHEUS_QUERY_URL
    )
    timeout_seconds = _env_float(_PROMETHEUS_TIMEOUT_SECONDS_ENV, default=1.0)
    try:
        combined_results = _query_prometheus_vector(
            query_url,
            _PROMETHEUS_RUNTIME_COMBINED_QUERY,
            timeout_seconds=timeout_seconds,
        )
    except (
        OSError,
        TimeoutError,
        urllib.error.URLError,
        json.JSONDecodeError,
        ValueError,
    ) as exc:
        return {
            "schema_version": "reboot_slo_prometheus_metric_readback_v1",
            "readback_present": False,
            "source": "prometheus_query_api",
            "query_url": query_url,
            "error_class": exc.__class__.__name__,
        }

    results_by_name: dict[str, list[dict[str, Any]]] = {}
    for result in combined_results:
        metric_name = str(_dict(result.get("metric")).get("__name__") or "")
        if metric_name:
            results_by_name.setdefault(metric_name, []).append(result)
    active_results = results_by_name.get(
        _PROMETHEUS_RUNTIME_QUERIES["active_blocker"],
        [],
    )
    primary_results = results_by_name.get(
        _PROMETHEUS_RUNTIME_QUERIES["primary_blocker"],
        [],
    )
    scalar_results = {
        key: results_by_name.get(query, [])
        for key, query in _PROMETHEUS_RUNTIME_QUERIES.items()
        if key not in {"active_blocker", "primary_blocker"}
    }
    active_blockers = _unique_strings(
        [
            str(_dict(result.get("metric")).get("blocker") or "")
            for result in active_results
            if str(_dict(result.get("metric")).get("blocker") or "")
        ]
    )
    primary_blocker = next(
        (
            str(_dict(result.get("metric")).get("blocker") or "")
            for result in primary_results
            if str(_dict(result.get("metric")).get("blocker") or "")
        ),
        "",
    )
    if not primary_blocker:
        primary_blocker = _reboot_sop_primary_blocker(active_blockers)
    blocker_count = _prometheus_first_int(
        scalar_results.get("blocker_count") or [],
        default=len(active_blockers),
    )
    ready = _prometheus_first_int(scalar_results.get("ready") or [], default=0) == 1
    last_run_timestamp = _prometheus_first_int(
        scalar_results.get("last_run_timestamp") or [],
        default=0,
    )
    return {
        "schema_version": "reboot_slo_prometheus_metric_readback_v1",
        "readback_present": bool(combined_results),
        "source": "prometheus_query_api",
        "query_url": query_url,
        "active_blockers": active_blockers,
        "active_blocker_count": blocker_count,
        "primary_blocker": primary_blocker,
        "ready": ready,
        "last_run_timestamp": last_run_timestamp,
    }


def _query_prometheus_vector(
    query_url: str,
    query: str,
    *,
    timeout_seconds: float,
) -> list[dict[str, Any]]:
    url = f"{query_url}?{urllib.parse.urlencode({'query': query})}"
    request = urllib.request.Request(url, method="GET")
    with urllib.request.urlopen(request, timeout=timeout_seconds) as response:
        payload = json.loads(response.read(1_000_000).decode("utf-8", errors="replace"))
    if not isinstance(payload, dict) or payload.get("status") != "success":
        raise ValueError("prometheus_status_not_success")
    return _list_of_dicts(_dict(payload.get("data")).get("result"))


def _prometheus_first_int(results: list[dict[str, Any]], *, default: int) -> int:
    if not results:
        return default
    value_pair = _list(_dict(results[0]).get("value"))
    if len(value_pair) < 2:
        return default
    try:
        return int(float(value_pair[1]))
    except (TypeError, ValueError):
        return default


def _annotate_prometheus_metric_readback(
    payload: dict[str, Any],
    metric_readback: dict[str, Any],
) -> None:
    present = metric_readback.get("readback_present") is True
    payload["runtime_metric_readback"] = metric_readback
    payload["runtime_metric_readback_present"] = present
    payload["runtime_metric_source"] = str(metric_readback.get("source") or "")
    payload["runtime_metric_active_blocker_count"] = _int(
        metric_readback.get("active_blocker_count")
    )
    payload["runtime_metric_last_run_timestamp"] = _int(
        metric_readback.get("last_run_timestamp")
    )
    payload["runtime_metric_source_control_reconciled_blockers"] = []
    payload["runtime_metric_source_control_reconciled_blocker_count"] = 0

    readback = _dict(payload.setdefault("readback", {}))
    readback["runtime_metric_readback_present"] = present
    readback["runtime_metric_source"] = payload["runtime_metric_source"]
    readback["runtime_metric_active_blocker_count"] = payload[
        "runtime_metric_active_blocker_count"
    ]
    readback["runtime_metric_last_run_timestamp"] = payload[
        "runtime_metric_last_run_timestamp"
    ]
    readback["runtime_metric_source_control_reconciled_blockers"] = []
    readback["runtime_metric_source_control_reconciled_blocker_count"] = 0

    rollups = _dict(payload.setdefault("rollups", {}))
    rollups["runtime_metric_readback_present"] = present
    rollups["runtime_metric_active_blocker_count"] = payload[
        "runtime_metric_active_blocker_count"
    ]
    rollups["runtime_metric_last_run_timestamp"] = payload[
        "runtime_metric_last_run_timestamp"
    ]
    rollups["runtime_metric_source_control_reconciled_blocker_count"] = 0


def _reconcile_prometheus_metric_active_blockers_with_source_controls(
    payload: dict[str, Any],
    active_blockers: list[str],
) -> list[str]:
    source_controls = _dict(payload.get("source_controls"))
    reconciled: list[str] = []
    removed: list[str] = []

    for blocker in active_blockers:
        source_control_key = _PROMETHEUS_SOURCE_CONTROLLED_BLOCKERS.get(blocker)
        if source_control_key and source_controls.get(source_control_key) is True:
            removed.append(blocker)
            continue
        reconciled.append(blocker)

    removed = _unique_strings(removed)
    if removed:
        payload["runtime_metric_source_control_reconciled_blockers"] = removed
        payload["runtime_metric_source_control_reconciled_blocker_count"] = len(removed)

        readback = _dict(payload.setdefault("readback", {}))
        readback["runtime_metric_source_control_reconciled_blockers"] = removed
        readback["runtime_metric_source_control_reconciled_blocker_count"] = len(removed)

        rollups = _dict(payload.setdefault("rollups", {}))
        rollups["runtime_metric_source_control_reconciled_blocker_count"] = len(
            removed
        )

    return _unique_strings(reconciled)


def _apply_prometheus_metric_active_blockers(
    payload: dict[str, Any],
    metric_readback: dict[str, Any],
) -> None:
    if metric_readback.get("readback_present") is not True:
        return
    active_blockers = _strings(metric_readback.get("active_blockers"))
    if not active_blockers and _int(metric_readback.get("active_blocker_count")):
        return
    active_blockers = _reconcile_prometheus_metric_active_blockers_with_source_controls(
        payload,
        active_blockers,
    )

    can_claim_slo = metric_readback.get("ready") is True and not active_blockers
    primary_blocker = str(
        metric_readback.get("primary_blocker")
        or _reboot_sop_primary_blocker(active_blockers)
    )
    current_phase = _reboot_sop_current_phase(active_blockers, can_claim_slo)
    eta_or_wait_reason = _reboot_sop_eta_or_wait_reason(
        scorecard=payload,
        active_blockers=active_blockers,
        current_phase=current_phase,
        primary_blocker=primary_blocker,
    )
    action_matrix = _build_active_blocker_action_matrix(
        active_blockers=active_blockers,
        primary_blocker=primary_blocker,
    )
    primary_action = _dict(action_matrix.get("primary_blocker_action"))
    next_safe_action = str(
        primary_action.get("next_safe_action")
        or _dict(payload.get("reboot_sop_progress")).get("next_safe_action")
        or payload.get("next_safe_action")
        or ""
    )

    payload["active_blockers"] = active_blockers
    payload["active_blocker_count"] = len(active_blockers)
    payload["primary_blocker"] = primary_blocker
    payload["current_phase"] = current_phase
    payload["eta_or_wait_reason"] = eta_or_wait_reason
    payload["next_safe_action"] = next_safe_action
    payload["can_claim_all_services_recovered_within_target"] = can_claim_slo
    payload["blocked_by_fresh_reboot_window_only"] = active_blockers == [
        "host_boot_observation_older_than_target_window"
    ]
    payload["active_blocker_action_matrix"] = action_matrix

    progress = _dict(payload.setdefault("reboot_sop_progress", {}))
    progress.update(
        {
            "current_phase": current_phase,
            "eta_or_wait_reason": eta_or_wait_reason,
            "primary_blocker": primary_blocker,
            "active_blockers": active_blockers,
            "active_blocker_count": len(active_blockers),
            "next_safe_action": next_safe_action,
        }
    )

    readback = _dict(payload.setdefault("readback", {}))
    readback.update(
        {
            "current_phase": current_phase,
            "eta_or_wait_reason": eta_or_wait_reason,
            "primary_blocker": primary_blocker,
            "primary_blocker_owner_lane": primary_action.get("owner_lane", ""),
            "primary_blocker_action_category": primary_action.get("category", ""),
            "active_blocker_count": len(active_blockers),
            "active_blocker_action_count": action_matrix["item_count"],
            "telegram_active_blocker_alert_required_count": action_matrix[
                "telegram_alert_required_count"
            ],
            "next_safe_action": next_safe_action,
            "blocked_by_fresh_reboot_window_only": payload[
                "blocked_by_fresh_reboot_window_only"
            ],
        }
    )

    rollups = _dict(payload.setdefault("rollups", {}))
    rollups.update(
        {
            "active_blocker_count": len(active_blockers),
            "active_blocker_action_count": action_matrix["item_count"],
            "active_blocker_action_category_counts": action_matrix[
                "category_counts"
            ],
            "active_blocker_action_owner_lane_counts": action_matrix[
                "owner_lane_counts"
            ],
            "primary_blocker_owner_lane": primary_action.get("owner_lane", ""),
            "primary_blocker_action_category": primary_action.get("category", ""),
            "telegram_active_blocker_alert_required_count": action_matrix[
                "telegram_alert_required_count"
            ],
            "can_claim_all_services_recovered_within_target": can_claim_slo,
            "blocked_by_fresh_reboot_window_only": payload[
                "blocked_by_fresh_reboot_window_only"
            ],
        }
    )


def _path_from_env(name: str) -> Path | None:
    value = os.environ.get(name, "").strip()
    return Path(value) if value else None


def _read_json_file(path: Path) -> dict[str, Any]:
    try:
        with path.open(encoding="utf-8") as handle:
            payload = json.load(handle)
    except (FileNotFoundError, json.JSONDecodeError, OSError):
        return {}
    return payload if isinstance(payload, dict) else {}


def apply_public_maintenance_runtime_readback(
    payload: dict[str, Any],
    runtime_readback: dict[str, Any],
) -> None:
    """Overlay exporter public-route fallback evidence onto the scorecard."""
    public_maintenance = _build_public_maintenance_fallback_readback(runtime_readback)
    payload["public_maintenance_fallback"] = public_maintenance

    active_blockers = [
        blocker
        for blocker in _strings(payload.get("active_blockers"))
        if blocker not in _PUBLIC_MAINTENANCE_BLOCKERS
    ]
    active_blockers.extend(_strings(public_maintenance.get("blockers")))
    active_blockers = _unique_strings(active_blockers)
    payload["active_blockers"] = active_blockers

    required_checks = _dict(payload.setdefault("required_checks", {}))
    required_checks["public_maintenance_fallback_runtime_ready"] = (
        public_maintenance.get("ready") is True
    )
    completed_check_count = sum(1 for value in required_checks.values() if value)
    readiness_percent = _percent(
        completed_check_count / max(len(required_checks), 1) * 100
    )
    active_blocker_count = len(active_blockers)
    payload["active_blocker_count"] = active_blocker_count
    payload["readiness_percent"] = readiness_percent

    progress = _dict(payload.setdefault("reboot_sop_progress", {}))
    progress["active_blockers"] = active_blockers
    progress["active_blocker_count"] = active_blocker_count
    progress["readiness_percent"] = readiness_percent
    progress["current_phase"] = _reboot_sop_current_phase(
        active_blockers,
        payload.get("can_claim_all_services_recovered_within_target") is True,
    )
    progress["primary_blocker"] = _reboot_sop_primary_blocker(active_blockers)
    payload["reboot_sop_progress"] = progress
    payload["current_phase"] = progress["current_phase"]
    payload["primary_blocker"] = progress["primary_blocker"]

    readback = _dict(payload.setdefault("readback", {}))
    readback["active_blocker_count"] = active_blocker_count
    readback["readiness_percent"] = readiness_percent
    readback["public_maintenance_runtime_readback_present"] = (
        public_maintenance.get("runtime_readback_present") is True
    )
    readback["public_maintenance_fallback_ready"] = (
        public_maintenance.get("ready") is True
    )
    readback["public_route_raw_5xx_without_fallback_count"] = _int(
        public_maintenance.get("raw_5xx_without_fallback_count")
    )

    rollups = _dict(payload.setdefault("rollups", {}))
    rollups["active_blocker_count"] = active_blocker_count
    rollups["completed_check_count"] = completed_check_count
    rollups["readiness_percent"] = readiness_percent
    rollups["public_maintenance_runtime_readback_present"] = (
        public_maintenance.get("runtime_readback_present") is True
    )
    rollups["public_maintenance_fallback_ready"] = (
        public_maintenance.get("ready") is True
    )
    rollups["public_route_raw_5xx_without_fallback_count"] = _int(
        public_maintenance.get("raw_5xx_without_fallback_count")
    )
    rollups["public_route_unreachable_without_external_fallback_count"] = _int(
        public_maintenance.get("route_unreachable_without_external_fallback_count")
    )
    rollups["public_maintenance_fallback_route_count"] = _int(
        public_maintenance.get("maintenance_fallback_route_count")
    )


def apply_stockplatform_runtime_readback(
    payload: dict[str, Any],
    runtime_readback: dict[str, Any],
) -> None:
    """Overlay live StockPlatform public API data truth onto the scorecard."""
    readback = _dict(runtime_readback.get("readback"))
    freshness_status = str(readback.get("freshness_status") or "unknown")
    ingestion_status = str(readback.get("ingestion_status") or "unknown")
    freshness_blockers = _strings(readback.get("freshness_blockers"))
    ingestion_blockers = _strings(readback.get("ingestion_blockers"))
    latest_trading_date = str(readback.get("freshness_latest_trading_date") or "")
    freshness_ok = freshness_status == "ok"
    ingestion_ok = ingestion_status == "ok"
    stockplatform = _dict(payload.setdefault("stockplatform_data_freshness", {}))
    stockplatform.update(
        {
            "freshness_status": freshness_status,
            "ingestion_status": ingestion_status,
            "latest_trading_date": latest_trading_date,
            "freshness_blockers": freshness_blockers,
            "ingestion_blockers": ingestion_blockers,
            "freshness_sla_source_count": _int(
                readback.get("freshness_sla_source_count")
            ),
            "freshness_source_count": _int(readback.get("freshness_source_count")),
            "freshness_non_ok_source_count": _int(
                readback.get("freshness_non_ok_source_count")
            ),
            "live_runtime_overlay_applied": True,
        }
    )

    required_checks = _dict(payload.setdefault("required_checks", {}))
    required_checks["stockplatform_freshness_ok"] = freshness_ok
    required_checks["stockplatform_ingestion_ok"] = ingestion_ok
    if not (freshness_ok and ingestion_ok):
        required_checks["product_data_green"] = False
        payload["product_data_green"] = False
        post_reboot = _dict(payload.setdefault("post_reboot_readiness", {}))
        post_reboot["product_data_green"] = False
        _append_live_stockplatform_blockers(
            payload=payload,
            freshness_status=freshness_status,
            ingestion_status=ingestion_status,
            freshness_blockers=freshness_blockers,
            ingestion_blockers=ingestion_blockers,
        )

    completed_check_count = sum(1 for value in required_checks.values() if value)
    readiness_percent = _percent(
        completed_check_count / max(len(required_checks), 1) * 100
    )
    active_blockers = _strings(payload.get("active_blockers"))
    active_blocker_count = len(active_blockers)
    payload["active_blocker_count"] = active_blocker_count
    payload["readiness_percent"] = readiness_percent
    payload["stockplatform_freshness_status"] = freshness_status
    payload["stockplatform_ingestion_status"] = ingestion_status

    readback_section = _dict(payload.setdefault("readback", {}))
    readback_section["active_blocker_count"] = active_blocker_count
    readback_section["readiness_percent"] = readiness_percent

    rollups = _dict(payload.setdefault("rollups", {}))
    rollups["active_blocker_count"] = active_blocker_count
    rollups["completed_check_count"] = completed_check_count
    rollups["readiness_percent"] = readiness_percent
    rollups["product_data_green"] = payload.get("product_data_green") is True
    rollups["stockplatform_freshness_status"] = freshness_status
    rollups["stockplatform_ingestion_status"] = ingestion_status
    rollups["stockplatform_freshness_blocker_count"] = len(freshness_blockers)
    rollups["stockplatform_ingestion_blocker_count"] = len(ingestion_blockers)
    rollups["stockplatform_freshness_sla_source_count"] = _int(
        readback.get("freshness_sla_source_count")
    )
    rollups["stockplatform_freshness_source_count"] = _int(
        readback.get("freshness_source_count")
    )
    rollups["stockplatform_freshness_non_ok_source_count"] = _int(
        readback.get("freshness_non_ok_source_count")
    )

    service_backup = _dict(
        payload.setdefault("controlled_service_data_backup_readback", {})
    )
    service_backup["product_data_green"] = payload.get("product_data_green") is True
    service_backup["stockplatform_freshness_status"] = freshness_status
    service_backup["stockplatform_ingestion_status"] = ingestion_status
    blocking_fields = _strings(service_backup.get("blocking_fields"))
    if not freshness_ok:
        blocking_fields.append("stockplatform_freshness_status")
    if not ingestion_ok:
        blocking_fields.append("stockplatform_ingestion_status")
    if payload.get("product_data_green") is not True:
        blocking_fields.append("product_data_green")
    service_backup["blocking_fields"] = _unique_strings(blocking_fields)
    service_backup["controlled_service_data_backup_blocker_count"] = len(
        service_backup["blocking_fields"]
    )
    rollups["controlled_service_data_backup_blocker_count"] = len(
        service_backup["blocking_fields"]
    )
    service_backup["status"] = "blocked_service_data_backup_readback_not_green"
    service_backup["can_clear_service_data_backup_blockers"] = False


def _append_live_stockplatform_blockers(
    *,
    payload: dict[str, Any],
    freshness_status: str,
    ingestion_status: str,
    freshness_blockers: list[str],
    ingestion_blockers: list[str],
) -> None:
    active_blockers = _strings(payload.get("active_blockers"))
    active_blockers.append("product_data_green_not_1")
    if freshness_status != "ok" and not freshness_blockers:
        active_blockers.append("stockplatform_freshness_status_not_ok")
    if ingestion_status != "ok" and not ingestion_blockers:
        active_blockers.append("stockplatform_ingestion_status_not_ok")
    active_blockers.extend(
        f"stockplatform_freshness_{blocker}" for blocker in freshness_blockers
    )
    active_blockers.extend(
        f"stockplatform_ingestion_{blocker}" for blocker in ingestion_blockers
    )
    payload["active_blockers"] = _unique_strings(active_blockers)


def _build_payload(scorecard: dict[str, Any], path: Path) -> dict[str, Any]:
    host_boot_detection = _dict(scorecard.get("host_boot_detection"))
    post_reboot_readiness = _dict(scorecard.get("post_reboot_readiness"))
    stockplatform = _dict(scorecard.get("stockplatform_data_freshness"))
    public_maintenance = _build_public_maintenance_fallback_readback(
        scorecard.get("public_maintenance_fallback")
    )
    windows99 = _dict(scorecard.get("windows99_vmware_autostart"))
    windows99_management = _dict(scorecard.get("windows99_management_channel"))
    windows99_ssh_batch = _dict(windows99_management.get("ssh_batch"))
    source_controls = _dict(scorecard.get("source_controls"))
    active_blockers = _unique_strings(
        _strings(scorecard.get("active_blockers"))
        + _strings(public_maintenance.get("blockers"))
    )
    required_checks = {
        "source_controls_present": all(source_controls.values()),
        "required_hosts_observed": not _strings(host_boot_detection.get("missing_hosts")),
        "required_hosts_reachable": not _strings(host_boot_detection.get("unreachable_hosts")),
        "windows99_vmware_autostart_ready": windows99.get("verify_ready") is True,
        "windows_update_no_auto_reboot_ready": (
            windows99.get("windows_update_no_auto_reboot_ready") is True
        ),
        "windows99_management_channel_ready": (
            windows99.get("verify_ready") is True
            or windows99_management.get("remote_execution_channel_ready") is True
        ),
        "service_green": post_reboot_readiness.get("service_green") is True,
        "product_data_green": post_reboot_readiness.get("product_data_green") is True,
        "backup_core_green": post_reboot_readiness.get("backup_core_green") is True,
        "host_188_service_green": post_reboot_readiness.get("host_188_service_green") is True,
        "stockplatform_freshness_ok": stockplatform.get("freshness_status") == "ok",
        "stockplatform_ingestion_ok": stockplatform.get("ingestion_status") in {"ok", "unknown"},
        "public_maintenance_fallback_runtime_ready": (
            public_maintenance.get("ready") is True
        ),
        "fresh_reboot_window_observed": not _strings(host_boot_detection.get("stale_hosts")),
        "can_claim_slo": scorecard.get("can_claim_all_services_recovered_within_target")
        is True,
    }
    completed_check_count = sum(1 for value in required_checks.values() if value)
    readiness_percent = _percent(
        completed_check_count / max(len(required_checks), 1) * 100
    )
    recovery_gate = _dict(stockplatform.get("controlled_recovery_gate"))
    safe_next_step = str(scorecard.get("safe_next_step") or "")
    can_claim_slo = (
        scorecard.get("can_claim_all_services_recovered_within_target") is True
    )
    if can_claim_slo and not active_blockers:
        readiness_percent = 100
    snapshot_generated_at = str(scorecard.get("generated_at") or "")
    runtime_readback_generated_at = _taipei_now_iso()
    latest_verify_metric = _dict(scorecard.get("latest_verify_only_metric"))
    source_scorecard_ref = (
        f"docs/operations/{path.name}"
        if path.name == _SCORECARD_FILE
        else str(path)
    )
    active_blocker_count = len(active_blockers)
    observed_host_count = len(_strings(host_boot_detection.get("observed_hosts")))
    missing_host_count = len(_strings(host_boot_detection.get("missing_hosts")))
    unreachable_host_count = len(_strings(host_boot_detection.get("unreachable_hosts")))
    stale_host_count = len(_strings(host_boot_detection.get("stale_hosts")))
    service_green = post_reboot_readiness.get("service_green") is True
    product_data_green = post_reboot_readiness.get("product_data_green") is True
    backup_core_green = post_reboot_readiness.get("backup_core_green") is True
    host_188_service_green = post_reboot_readiness.get("host_188_service_green") is True
    controlled_service_data_backup_readback = (
        _build_controlled_service_data_backup_readback(
            post_reboot_readiness=post_reboot_readiness,
            stockplatform=stockplatform,
            active_blockers=active_blockers,
        )
    )
    windows99_verify_collection = _build_windows99_verify_collection_packet(
        windows99=windows99,
        host_boot_detection=host_boot_detection,
    )
    blocked_by_fresh_reboot_window_only = active_blockers == [
        "host_boot_observation_older_than_target_window"
    ]
    latest_verify_only_metric_present = bool(latest_verify_metric)
    sop_progress = _build_reboot_sop_progress(
        scorecard=scorecard,
        active_blockers=active_blockers,
        readiness_percent=readiness_percent,
        can_claim_slo=can_claim_slo,
    )
    active_blocker_action_matrix = _build_active_blocker_action_matrix(
        active_blockers=active_blockers,
        primary_blocker=sop_progress["primary_blocker"],
    )
    rollups = {
        "active_blocker_count": active_blocker_count,
        "active_blocker_action_count": active_blocker_action_matrix["item_count"],
        "active_blocker_action_category_counts": active_blocker_action_matrix[
            "category_counts"
        ],
        "active_blocker_action_owner_lane_counts": active_blocker_action_matrix[
            "owner_lane_counts"
        ],
        "primary_blocker_owner_lane": active_blocker_action_matrix[
            "primary_blocker_action"
        ].get("owner_lane", ""),
        "primary_blocker_action_category": active_blocker_action_matrix[
            "primary_blocker_action"
        ].get("category", ""),
        "telegram_active_blocker_alert_required_count": active_blocker_action_matrix[
            "telegram_alert_required_count"
        ],
        "readiness_percent": readiness_percent,
        "completed_check_count": completed_check_count,
        "required_check_count": len(required_checks),
        "can_claim_all_services_recovered_within_target": can_claim_slo,
        "observed_host_count": observed_host_count,
        "missing_host_count": missing_host_count,
        "unreachable_host_count": unreachable_host_count,
        "stale_host_count": stale_host_count,
        "post_start_blocked": _int(post_reboot_readiness.get("post_start_blocked")),
        "service_green": service_green,
        "product_data_green": product_data_green,
        "backup_core_green": backup_core_green,
        "host_188_service_green": host_188_service_green,
        "blocked_by_fresh_reboot_window_only": blocked_by_fresh_reboot_window_only,
        "latest_verify_only_metric_present": latest_verify_only_metric_present,
        "latest_verify_only_metric_ready": _int(latest_verify_metric.get("ready")),
        "latest_verify_only_metric_blocker_count": _int(
            latest_verify_metric.get("blocker_count")
        ),
        "latest_verify_only_metric_max_host_uptime_seconds": _int(
            latest_verify_metric.get("max_host_uptime_seconds")
        ),
        "latest_verify_only_metric_last_run_timestamp": _int(
            latest_verify_metric.get("last_run_timestamp")
        ),
        "stockplatform_freshness_status": str(
            stockplatform.get("freshness_status") or "unknown"
        ),
        "stockplatform_ingestion_status": str(
            stockplatform.get("ingestion_status") or "unknown"
        ),
        "stockplatform_freshness_blocker_count": len(
            _strings(stockplatform.get("freshness_blockers"))
        ),
        "stockplatform_ingestion_blocker_count": len(
            _strings(stockplatform.get("ingestion_blockers"))
        ),
        "stockplatform_final_retry_window_passed": _dict(
            stockplatform.get("eod_window")
        ).get("final_retry_window_passed")
        is True,
        "stockplatform_controlled_recovery_gate_required": recovery_gate.get(
            "required"
        )
        is True,
        "public_maintenance_runtime_readback_present": (
            public_maintenance.get("runtime_readback_present") is True
        ),
        "public_maintenance_fallback_ready": (
            public_maintenance.get("ready") is True
        ),
        "public_route_raw_5xx_without_fallback_count": _int(
            public_maintenance.get("raw_5xx_without_fallback_count")
        ),
        "public_route_unreachable_without_external_fallback_count": _int(
            public_maintenance.get(
                "route_unreachable_without_external_fallback_count"
            )
        ),
        "public_maintenance_fallback_route_count": _int(
            public_maintenance.get("maintenance_fallback_route_count")
        ),
        "controlled_service_data_backup_readback_present": (
            controlled_service_data_backup_readback["readback_present"] is True
        ),
        "controlled_service_data_backup_readback_status": str(
            controlled_service_data_backup_readback["status"]
        ),
        "controlled_service_data_backup_blocker_count": len(
            _strings(controlled_service_data_backup_readback.get("blocking_fields"))
        ),
        "controlled_service_data_backup_can_clear_blockers": (
            controlled_service_data_backup_readback[
                "can_clear_service_data_backup_blockers"
            ]
            is True
        ),
        "controlled_service_data_backup_next_safe_action": str(
            controlled_service_data_backup_readback["next_safe_action"]
        ),
        "windows99_vmware_readback_present": windows99.get("readback_present") is True,
        "windows99_vmrun_present": windows99.get("vmrun_present") is True,
        "windows99_vmware_config_ready": windows99.get("config_ready") is True,
        "windows99_vmware_power_ready": windows99.get("power_ready") is True,
        "windows99_update_no_auto_reboot_ready": (
            windows99.get("windows_update_no_auto_reboot_ready") is True
        ),
        "windows99_vmware_verify_ready": windows99.get("verify_ready") is True,
        "windows99_vmware_missing_vmx_count": len(
            _strings(windows99.get("missing_vmx_aliases"))
        ),
        "windows99_vmware_powered_off_count": len(
            _strings(windows99.get("powered_off_aliases"))
        ),
        "windows99_verify_collection_status": windows99_verify_collection["status"],
        "windows99_verify_collection_can_collect_no_secret": (
            windows99_verify_collection["can_collect_no_secret_verify"] is True
        ),
        "windows99_verify_collection_blocker_count": len(
            _strings(windows99_verify_collection.get("collection_blockers"))
        ),
        "windows99_host99_reachable": (
            windows99_verify_collection["host99_reachable"] is True
        ),
        "windows99_host99_uptime_known": (
            windows99_verify_collection["host99_uptime_known"] is True
        ),
        "windows99_management_readback_present": (
            windows99_management.get("readback_present") is True
        ),
        "windows99_host_reachable": (
            windows99_management.get("host_reachable") is True
        ),
        "windows99_remote_execution_channel_ready": (
            windows99_management.get("remote_execution_channel_ready") is True
        ),
        "windows99_can_collect_vmware_verify_without_secret": (
            windows99_management.get("can_collect_vmware_verify_without_secret") is True
        ),
        "windows99_ssh_batch_ready": windows99_ssh_batch.get("ready") is True,
        "windows99_ssh_batch_status": str(
            windows99_ssh_batch.get("status") or "unknown"
        ),
        "windows99_winrm_http_open": (
            windows99_management.get("winrm_http_open") is True
        ),
        "windows99_winrm_https_open": (
            windows99_management.get("winrm_https_open") is True
        ),
        "windows99_hyperv_vmconnect_open": (
            windows99_management.get("hyperv_vmconnect_open") is True
        ),
        "windows99_rdp_console_reachable": (
            windows99_management.get("rdp_console_reachable") is True
        ),
        "runtime_readback_generated_at_present": True,
        "windows99_local_console_channel_reachable": (
            windows99_management.get("local_console_channel_reachable") is True
        ),
        "windows99_console_collection_channels": _strings(
            windows99_management.get("console_collection_channels")
        ),
    }
    return {
        "schema_version": _API_SCHEMA_VERSION,
        "generated_at": runtime_readback_generated_at,
        "runtime_readback_generated_at": runtime_readback_generated_at,
        "snapshot_generated_at": snapshot_generated_at,
        "priority": "P0-006",
        "scope": "reboot_auto_recovery_slo_scorecard",
        "status": str(scorecard.get("status") or "unknown"),
        "current_phase": sop_progress["current_phase"],
        "eta_or_wait_reason": sop_progress["eta_or_wait_reason"],
        "safe_next_step": safe_next_step,
        "next_safe_action": sop_progress["next_safe_action"],
        "primary_blocker": sop_progress["primary_blocker"],
        "can_claim_all_services_recovered_within_target": can_claim_slo,
        "active_blocker_count": active_blocker_count,
        "readiness_percent": readiness_percent,
        "service_green": service_green,
        "product_data_green": product_data_green,
        "backup_core_green": backup_core_green,
        "host_188_service_green": host_188_service_green,
        "observed_host_count": observed_host_count,
        "missing_host_count": missing_host_count,
        "unreachable_host_count": unreachable_host_count,
        "stale_host_count": stale_host_count,
        "blocked_by_fresh_reboot_window_only": blocked_by_fresh_reboot_window_only,
        "latest_verify_only_metric_present": latest_verify_only_metric_present,
        "latest_verify_only_metric_ready": rollups["latest_verify_only_metric_ready"],
        "latest_verify_only_metric_blocker_count": rollups[
            "latest_verify_only_metric_blocker_count"
        ],
        "latest_verify_only_metric_max_host_uptime_seconds": rollups[
            "latest_verify_only_metric_max_host_uptime_seconds"
        ],
        "latest_verify_only_metric_last_run_timestamp": rollups[
            "latest_verify_only_metric_last_run_timestamp"
        ],
        "stockplatform_freshness_status": rollups["stockplatform_freshness_status"],
        "stockplatform_ingestion_status": rollups["stockplatform_ingestion_status"],
        "windows99_vmware_verify_ready": rollups["windows99_vmware_verify_ready"],
        "windows99_update_no_auto_reboot_ready": rollups[
            "windows99_update_no_auto_reboot_ready"
        ],
        "windows99_remote_execution_channel_ready": rollups[
            "windows99_remote_execution_channel_ready"
        ],
        "windows99_ssh_batch_status": rollups["windows99_ssh_batch_status"],
        "windows99_local_console_channel_reachable": rollups[
            "windows99_local_console_channel_reachable"
        ],
        "readback": {
            "workplan_id": "P0-006",
            "workplan_title": "主機重啟自動偵測、自動觸發與 10 分鐘恢復 SLO",
            "source_scorecard_ref": source_scorecard_ref,
            "generated_at": runtime_readback_generated_at,
            "runtime_readback_generated_at": runtime_readback_generated_at,
            "snapshot_generated_at": snapshot_generated_at,
            "target_minutes": _int(scorecard.get("target_minutes")),
            "current_phase": sop_progress["current_phase"],
            "eta_or_wait_reason": sop_progress["eta_or_wait_reason"],
            "safe_next_step": safe_next_step,
            "next_safe_action": sop_progress["next_safe_action"],
            "primary_blocker": sop_progress["primary_blocker"],
            "primary_blocker_owner_lane": active_blocker_action_matrix[
                "primary_blocker_action"
            ].get("owner_lane", ""),
            "primary_blocker_action_category": active_blocker_action_matrix[
                "primary_blocker_action"
            ].get("category", ""),
            "active_blocker_count": active_blocker_count,
            "active_blocker_action_count": active_blocker_action_matrix["item_count"],
            "telegram_active_blocker_alert_required_count": (
                active_blocker_action_matrix["telegram_alert_required_count"]
            ),
            "readiness_percent": readiness_percent,
            "blocked_by_fresh_reboot_window_only": blocked_by_fresh_reboot_window_only,
            "latest_verify_only_metric_present": latest_verify_only_metric_present,
            "public_maintenance_runtime_readback_present": rollups[
                "public_maintenance_runtime_readback_present"
            ],
            "public_maintenance_fallback_ready": rollups[
                "public_maintenance_fallback_ready"
            ],
            "public_route_raw_5xx_without_fallback_count": rollups[
                "public_route_raw_5xx_without_fallback_count"
            ],
            "controlled_service_data_backup_readback_status": rollups[
                "controlled_service_data_backup_readback_status"
            ],
            "controlled_service_data_backup_blocker_count": rollups[
                "controlled_service_data_backup_blocker_count"
            ],
            "controlled_service_data_backup_next_safe_action": rollups[
                "controlled_service_data_backup_next_safe_action"
            ],
            "windows99_vmware_verify_ready": rollups[
                "windows99_vmware_verify_ready"
            ],
            "windows99_update_no_auto_reboot_ready": rollups[
                "windows99_update_no_auto_reboot_ready"
            ],
            "windows99_verify_collection_status": rollups[
                "windows99_verify_collection_status"
            ],
            "windows99_verify_collection_can_collect_no_secret": rollups[
                "windows99_verify_collection_can_collect_no_secret"
            ],
            "windows99_remote_execution_channel_ready": rollups[
                "windows99_remote_execution_channel_ready"
            ],
            "windows99_ssh_batch_status": rollups["windows99_ssh_batch_status"],
            "windows99_local_console_channel_reachable": rollups[
                "windows99_local_console_channel_reachable"
            ],
            "windows99_console_collection_channels": rollups[
                "windows99_console_collection_channels"
            ],
        },
        "reboot_sop_progress": sop_progress,
        "active_blocker_action_matrix": active_blocker_action_matrix,
        "controlled_service_data_backup_readback": (
            controlled_service_data_backup_readback
        ),
        "host_boot_detection": host_boot_detection,
        "post_reboot_readiness": post_reboot_readiness,
        "stockplatform_data_freshness": stockplatform,
        "public_maintenance_fallback": public_maintenance,
        "windows99_vmware_autostart": windows99,
        "windows99_verify_collection": windows99_verify_collection,
        "windows99_management_channel": windows99_management,
        "source_controls": source_controls,
        "active_blockers": active_blockers,
        "required_checks": required_checks,
        "rollups": rollups,
        "operation_boundaries": {
            "read_only_api_allowed": True,
            "host_reboot_performed": False,
            "host_restart_performed": False,
            "service_restart_performed": False,
            "database_write_or_restore_performed": False,
            "stockplatform_manual_data_write_performed": False,
            "secret_value_collection_allowed": False,
            "github_api_used": False,
            "workflow_trigger_performed": False,
            "runtime_write_allowed": False,
        },
    }


def _build_public_maintenance_fallback_readback(value: Any) -> dict[str, Any]:
    public_maintenance = _dict(value)
    if not public_maintenance:
        return {
            "runtime_readback_present": False,
            "ready": False,
            "target_url_count": 0,
            "route_count": 0,
            "raw_5xx_without_fallback_count": 0,
            "route_unreachable_without_external_fallback_count": 0,
            "maintenance_fallback_route_count": 0,
            "raw_5xx_without_fallback_urls": [],
            "route_unreachable_without_external_fallback_urls": [],
            "maintenance_fallback_urls": [],
            "routes": [],
            "blockers": ["public_maintenance_fallback_runtime_readback_missing"],
        }

    raw_5xx_count = _int(public_maintenance.get("raw_5xx_without_fallback_count"))
    unreachable_count = _int(
        public_maintenance.get("route_unreachable_without_external_fallback_count")
    )
    blockers = _strings(public_maintenance.get("blockers"))
    if (
        raw_5xx_count
        and "public_route_raw_5xx_without_maintenance_fallback" not in blockers
    ):
        blockers.append("public_route_raw_5xx_without_maintenance_fallback")
    if (
        unreachable_count
        and "public_route_unreachable_without_external_l1_fallback" not in blockers
    ):
        blockers.append("public_route_unreachable_without_external_l1_fallback")

    return {
        "runtime_readback_present": True,
        "schema_version": str(public_maintenance.get("schema_version") or "unknown"),
        "generated_at": str(public_maintenance.get("generated_at") or ""),
        "ready": public_maintenance.get("ready") is True and not blockers,
        "target_url_count": _int(public_maintenance.get("target_url_count")),
        "route_count": _int(public_maintenance.get("route_count")),
        "raw_5xx_without_fallback_count": raw_5xx_count,
        "route_unreachable_without_external_fallback_count": unreachable_count,
        "maintenance_fallback_route_count": _int(
            public_maintenance.get("maintenance_fallback_route_count")
        ),
        "raw_5xx_without_fallback_urls": _strings(
            public_maintenance.get("raw_5xx_without_fallback_urls")
        ),
        "route_unreachable_without_external_fallback_urls": _strings(
            public_maintenance.get("route_unreachable_without_external_fallback_urls")
        ),
        "maintenance_fallback_urls": _strings(
            public_maintenance.get("maintenance_fallback_urls")
        ),
        "routes": _list_of_dicts(public_maintenance.get("routes")),
        "blockers": _unique_strings(blockers),
    }


def _build_controlled_service_data_backup_readback(
    *,
    post_reboot_readiness: dict[str, Any],
    stockplatform: dict[str, Any],
    active_blockers: list[str],
) -> dict[str, Any]:
    service_green = post_reboot_readiness.get("service_green") is True
    product_data_green = post_reboot_readiness.get("product_data_green") is True
    backup_core_green = post_reboot_readiness.get("backup_core_green") is True
    host_188_service_green = post_reboot_readiness.get("host_188_service_green") is True
    post_start_blocked = _int(post_reboot_readiness.get("post_start_blocked"))
    wazuh_dashboard_degraded = (
        post_reboot_readiness.get("wazuh_dashboard_degraded") is True
    )
    stockplatform_freshness_status = str(
        stockplatform.get("freshness_status") or "unknown"
    )
    stockplatform_ingestion_status = str(
        stockplatform.get("ingestion_status") or "unknown"
    )
    blocking_fields: list[str] = []
    if not service_green:
        blocking_fields.append("service_green")
    if post_start_blocked != 0:
        blocking_fields.append("post_start_blocked")
    if not product_data_green:
        blocking_fields.append("product_data_green")
    if not backup_core_green:
        blocking_fields.append("backup_core_green")
    if not host_188_service_green:
        blocking_fields.append("host_188_service_green")
    if wazuh_dashboard_degraded:
        blocking_fields.append("wazuh_dashboard_degraded")
    if stockplatform_freshness_status != "ok":
        blocking_fields.append("stockplatform_freshness_status")
    if stockplatform_ingestion_status not in {"ok", "unknown"}:
        blocking_fields.append("stockplatform_ingestion_status")

    related_blockers = [
        blocker
        for blocker in active_blockers
        if blocker
        in {
            "backup_core_green_not_1",
            "host_188_service_green_not_1",
            "post_start_blocked_not_zero",
            "product_data_green_not_1",
            "service_green_not_1",
            "stockplatform_freshness_blocked",
            "stockplatform_ingestion_blocked",
            "wazuh_dashboard_degraded",
        }
    ]
    readback_present = (
        post_reboot_readiness.get("summary_present") is True
        or stockplatform.get("freshness_endpoint_readback_present") is True
        or stockplatform.get("ingestion_endpoint_readback_present") is True
    )
    can_clear_blockers = readback_present and not blocking_fields
    return {
        "schema_version": "controlled_service_data_backup_readback_v1",
        "status": (
            "ready_service_data_backup_green"
            if can_clear_blockers
            else "blocked_service_data_backup_readback_not_green"
        ),
        "readback_present": readback_present,
        "service_green": service_green,
        "product_data_green": product_data_green,
        "backup_core_green": backup_core_green,
        "host_188_service_green": host_188_service_green,
        "post_start_blocked": post_start_blocked,
        "wazuh_dashboard_degraded": wazuh_dashboard_degraded,
        "stockplatform_freshness_status": stockplatform_freshness_status,
        "stockplatform_ingestion_status": stockplatform_ingestion_status,
        "stockplatform_freshness_blockers": _strings(
            stockplatform.get("freshness_blockers")
        ),
        "stockplatform_ingestion_blockers": _strings(
            stockplatform.get("ingestion_blockers")
        ),
        "blocking_fields": blocking_fields,
        "related_active_blockers": related_blockers,
        "can_clear_service_data_backup_blockers": can_clear_blockers,
        "next_safe_action": (
            "keep_timer_live_wait_for_fresh_all_host_reboot_event_or_drill_preflight"
            if can_clear_blockers
            else "collect_public_service_data_backup_readback_and_refresh_reboot_slo_scorecard_no_reboot_no_db_write"
        ),
        "controlled_lane": "read_only_verifier_input",
        "forbidden_actions": [
            "host_reboot",
            "service_restart",
            "manual_db_update",
            "truncate_or_restore",
            "fake_freshness_marker",
            "secret_value_read",
            "workflow_dispatch",
            "github_api",
        ],
        "runtime_write_allowed": False,
    }


def _build_windows99_verify_collection_packet(
    *,
    windows99: dict[str, Any],
    host_boot_detection: dict[str, Any],
) -> dict[str, Any]:
    host99 = _host_row_by_alias(host_boot_detection, "99")
    host99_reachable = host99.get("reachable") is True
    host99_uptime_known = bool(host99) and _int(host99.get("uptime_seconds")) >= 0
    readback_present = windows99.get("readback_present") is True
    verify_ready = windows99.get("verify_ready") is True
    collection_blockers: list[str] = []
    if not host99_reachable:
        collection_blockers.append("windows99_host_not_reachable_for_verify_collection")
    if not readback_present:
        collection_blockers.append("windows99_vmware_autostart_readback_missing")
    for blocker in _strings(windows99.get("blockers")):
        if blocker not in collection_blockers:
            collection_blockers.append(blocker)
    if not host99_uptime_known:
        collection_blockers.append("windows99_uptime_unknown")

    return {
        "schema_version": "windows99_vmware_verify_collection_packet_v1",
        "status": (
            "ready_windows99_vmware_verify_readback_green"
            if verify_ready
            else (
                "blocked_windows99_verify_output_missing_host_reachable"
                if host99_reachable and not readback_present
                else "blocked_windows99_verify_collection_not_ready"
            )
        ),
        "target_host_alias": "99",
        "target_host": "192.168.0.99",
        "host99_reachable": host99_reachable,
        "host99_uptime_known": host99_uptime_known,
        "readback_present": readback_present,
        "verify_ready": verify_ready,
        "can_collect_no_secret_verify": host99_reachable and not verify_ready,
        "required_vm_aliases": _strings(windows99.get("required_vm_aliases"))
        or ["111", "112", "120", "121", "188"],
        "expected_no_secret_output_fields": [
            "VMRUN_PRESENT",
            "VMX alias=<alias> present=<0|1>",
            "VMWARE_SERVICE name=<name> ok=<0|1>",
            "VMWARE_AUTOSTART_TASK name=AWOOOI-Start-VMware-VMs ok=<0|1>",
            "WINDOWS_UPDATE_POLICY name=<name> ok=<0|1>",
            "VM_POWER alias=<alias> running=<0|1>",
            "VMWARE_AUTOSTART_CONFIG_READY",
            "VMWARE_AUTOSTART_POWER_READY",
            "WINDOWS_UPDATE_NO_AUTO_REBOOT_READY",
            "VMWARE_AUTOSTART_VERIFY_READY",
        ],
        "no_secret_verify_command": (
            "powershell -ExecutionPolicy Bypass -File "
            ".\\windows99-vmware-autostart.ps1 -Mode Verify"
        ),
        "no_secret_collector_check_command": (
            "bash scripts/reboot-recovery/collect-windows99-vmware-verify.sh --check"
        ),
        "no_secret_collector_collect_command": (
            "bash scripts/reboot-recovery/collect-windows99-vmware-verify.sh --collect"
        ),
        "post_verifier": (
            "rerun_reboot_auto_recovery_slo_scorecard_with_"
            "windows99_vmware_file_no_secret_no_reboot"
        ),
        "collection_blockers": collection_blockers,
        "safe_collection_channels": [
            "authorized_windows99_console_verify_stdout_only",
            "existing_management_channel_verify_mode_only",
            "no_secret_ssh_batchmode_verify_collector",
            "committed_no_secret_artifact_file_then_scorecard_rerun",
        ],
        "forbidden_actions": [
            "windows_password_or_secret_collection",
            "host_reboot",
            "vm_power_change",
            "windows_update_policy_apply",
            "manual_registry_edit",
            "service_restart",
            "github_api",
        ],
    }


def _host_row_by_alias(
    host_boot_detection: dict[str, Any],
    alias: str,
) -> dict[str, Any]:
    rows = host_boot_detection.get("host_rows")
    if not isinstance(rows, list):
        return {}
    for item in rows:
        if isinstance(item, dict) and str(item.get("alias") or "") == alias:
            return item
    return {}


def _build_reboot_sop_progress(
    *,
    scorecard: dict[str, Any],
    active_blockers: list[str],
    readiness_percent: int,
    can_claim_slo: bool,
) -> dict[str, Any]:
    current_phase = _reboot_sop_current_phase(active_blockers, can_claim_slo)
    primary_blocker = _reboot_sop_primary_blocker(active_blockers)
    eta_or_wait_reason = _reboot_sop_eta_or_wait_reason(
        scorecard=scorecard,
        active_blockers=active_blockers,
        current_phase=current_phase,
        primary_blocker=primary_blocker,
    )
    sla_eta = _dict(scorecard.get("sla_recovery_eta"))
    return {
        "current_phase": current_phase,
        "eta_or_wait_reason": eta_or_wait_reason,
        "primary_blocker": primary_blocker,
        "active_blockers": active_blockers,
        "active_blocker_count": len(active_blockers),
        "readiness_percent": readiness_percent,
        "next_safe_action": str(
            scorecard.get("next_safe_action")
            or scorecard.get("safe_next_step")
            or ""
        ),
        "fixed_triage_order": _strings(sla_eta.get("fixed_triage_order")),
    }


def _reboot_sop_current_phase(active_blockers: list[str], can_claim_slo: bool) -> str:
    if can_claim_slo and not active_blockers:
        return "slo_ready"
    if active_blockers == ["host_boot_observation_older_than_target_window"]:
        return "awaiting_next_reboot_or_approved_drill"
    host_boot_blockers = {
        "all_host_reboot_detection_missing",
        "stateful_reboot_event_detection_missing",
        "host_boot_probe_missing_hosts",
        "host_unreachable_after_reboot",
        "host_boot_observation_older_than_target_window",
        "host_uptime_unknown",
        "reboot_event_missing_required_hosts",
        "reboot_event_required_host_unreachable",
        "fresh_all_host_reboot_event_missing",
        "all_required_hosts_not_in_10_minute_reboot_window",
        "windows99_remote_execution_channel_unavailable",
        "windows99_vmware_autostart_readback_missing",
        "windows99_vmrun_missing",
        "windows99_vmware_vmx_missing",
        "windows99_vmware_autostart_config_not_ready",
        "windows99_vmware_guest_power_not_ready",
        "windows99_update_no_auto_reboot_policy_not_ready",
    }
    if any(blocker in host_boot_blockers for blocker in active_blockers):
        return "host_boot_detection_blocked"
    service_blockers = {
        "post_reboot_summary_missing",
        "post_start_blocked_not_zero",
        "service_green_not_1",
        "host_188_service_green_not_1",
        "wazuh_dashboard_degraded",
    }
    if any(blocker in service_blockers for blocker in active_blockers):
        return "post_reboot_service_readiness_blocked"
    if any(
        "stockplatform" in blocker or "product_data" in blocker
        for blocker in active_blockers
    ):
        return "product_data_freshness_blocked"
    if any(blocker in _PUBLIC_MAINTENANCE_BLOCKERS for blocker in active_blockers):
        return "public_maintenance_fallback_blocked"
    if any("backup" in blocker for blocker in active_blockers):
        return "backup_readback_blocked"
    if "local_disk_free_below_minimum" in active_blockers:
        return "host_capacity_blocked"
    if any(
        blocker.startswith("host_")
        or blocker.startswith("awooop_")
        or blocker.startswith("conversation_event_hot_path_")
        for blocker in active_blockers
    ):
        return "host_pressure_blocked"
    return "slo_blocked"


def _reboot_sop_primary_blocker(active_blockers: list[str]) -> str:
    priority = [
        "reboot_event_required_host_unreachable",
        "host_unreachable_after_reboot",
        "all_host_reboot_detection_missing",
        "stateful_reboot_event_detection_missing",
        "host_boot_probe_missing_hosts",
        "fresh_all_host_reboot_event_missing",
        "all_required_hosts_not_in_10_minute_reboot_window",
        "host_boot_observation_older_than_target_window",
        "host_uptime_unknown",
        "windows99_remote_execution_channel_unavailable",
        "windows99_vmware_autostart_readback_missing",
        "windows99_vmrun_missing",
        "windows99_vmware_vmx_missing",
        "windows99_vmware_autostart_config_not_ready",
        "windows99_vmware_guest_power_not_ready",
        "windows99_update_no_auto_reboot_policy_not_ready",
        "public_route_raw_5xx_without_maintenance_fallback",
        "public_route_unreachable_without_external_l1_fallback",
        "public_maintenance_fallback_runtime_readback_missing",
        "post_start_blocked_not_zero",
        "service_green_not_1",
        "host_188_service_green_not_1",
        "product_data_green_not_1",
        "stockplatform_freshness_blocked",
        "stockplatform_ingestion_blocked",
        "backup_core_green_not_1",
        "local_disk_free_below_minimum",
        "wazuh_dashboard_degraded",
    ]
    for blocker in priority:
        if blocker in active_blockers:
            return blocker
    return active_blockers[0] if active_blockers else ""


def _reboot_sop_eta_or_wait_reason(
    *,
    scorecard: dict[str, Any],
    active_blockers: list[str],
    current_phase: str,
    primary_blocker: str,
) -> str:
    if current_phase == "slo_ready":
        return "recovered_within_10_minute_slo"
    sla_eta = _dict(scorecard.get("sla_recovery_eta"))
    reboot_event = _dict(scorecard.get("reboot_event_detection"))
    remaining = _int(sla_eta.get("target_seconds_remaining"))
    deadline_status = str(sla_eta.get("deadline_status") or "unknown")
    if remaining > 0:
        return (
            f"target_window_remaining_{remaining}s_but_blocked_by_"
            f"{primary_blocker or 'unknown'}"
        )
    if reboot_event.get("readback_present") is not True:
        return "reboot_event_readback_missing_eta_unavailable"
    if deadline_status == "target_window_elapsed":
        return (
            "target_window_elapsed_eta_unavailable_until_fresh_all_host_reboot_"
            "event_and_probe"
        )
    if active_blockers:
        return f"eta_unavailable_until_primary_blocker_clears:{primary_blocker}"
    return "eta_unavailable"


def _build_active_blocker_action_matrix(
    *,
    active_blockers: list[str],
    primary_blocker: str,
) -> dict[str, Any]:
    items = [
        _active_blocker_action_row(
            blocker=blocker,
            priority_order=index,
            is_primary=blocker == primary_blocker,
        )
        for index, blocker in enumerate(active_blockers, start=1)
    ]
    primary_action = next(
        (item for item in items if item.get("is_primary") is True),
        {},
    )
    return {
        "schema_version": "reboot_active_blocker_action_matrix_v1",
        "item_count": len(items),
        "telegram_alert_required_count": sum(
            1 for item in items if item.get("telegram_alert_required") is True
        ),
        "category_counts": _count_by(items, "category"),
        "owner_lane_counts": _count_by(items, "owner_lane"),
        "primary_blocker_action": primary_action,
        "items": items,
    }


def _active_blocker_action_row(
    *,
    blocker: str,
    priority_order: int,
    is_primary: bool,
) -> dict[str, Any]:
    category = "reboot_slo_unknown"
    owner_lane = "sre_reboot_slo_scorecard"
    severity = "critical"
    next_safe_action = (
        "read_active_blocker_evidence_then_rerun_reboot_slo_scorecard_no_reboot"
    )
    post_verifier = (
        "scripts/reboot-recovery/reboot-auto-recovery-slo-scorecard.py "
        "--output <scorecard.json>"
    )
    evidence_inputs = ["scorecard.active_blockers"]
    controlled_apply_mode = "verifier_only_from_reboot_slo_lane"
    forbidden_actions = [
        "host_reboot",
        "service_restart",
        "docker_daemon_restart",
        "node_drain",
        "database_write_or_restore",
        "secret_value_read",
        "workflow_dispatch",
        "github_api",
        "force_push_or_ref_delete",
    ]

    if blocker.startswith("windows99_"):
        category = "windows99_vmware_autostart"
        owner_lane = "windows99_console_or_no_secret_management_channel"
        next_safe_action = (
            "collect_windows99_vmware_autostart_verify_readback_then_rerun_"
            "reboot_scorecard_no_secret_no_reboot"
        )
        if blocker == "windows99_remote_execution_channel_unavailable":
            next_safe_action = (
                "restore_windows99_no_secret_management_channel_or_collect_local_"
                "console_verify_readback_then_rerun_reboot_scorecard_no_reboot"
            )
        post_verifier = (
            "bash scripts/reboot-recovery/collect-windows99-vmware-verify.sh "
            "--check && rerun_reboot_auto_recovery_slo_scorecard"
        )
        evidence_inputs = [
            "windows99_management_channel",
            "windows99_vmware_autostart",
            "windows99_verify_collection",
        ]
        controlled_apply_mode = "console_verify_or_no_secret_collector_only"
        forbidden_actions.extend(
            [
                "windows_password_or_secret_collection",
                "vm_power_change",
                "windows_update_policy_apply_from_scorecard",
                "manual_registry_edit",
            ]
        )
    elif blocker in {
        "all_host_reboot_detection_missing",
        "stateful_reboot_event_detection_missing",
        "host_boot_probe_missing_hosts",
        "host_unreachable_after_reboot",
        "host_boot_observation_older_than_target_window",
        "host_uptime_unknown",
        "reboot_event_missing_required_hosts",
        "reboot_event_required_host_unreachable",
        "fresh_all_host_reboot_event_missing",
        "all_required_hosts_not_in_10_minute_reboot_window",
    }:
        category = "host_boot_detection"
        owner_lane = "reboot_event_detector_and_host_probe"
        next_safe_action = (
            "rerun_reboot_event_detector_and_host_probe_verify_only_no_reboot"
        )
        post_verifier = (
            "scripts/reboot-recovery/reboot-auto-recovery-host-probe.sh && "
            "scripts/reboot-recovery/reboot-event-detector.py"
        )
        evidence_inputs = ["host_boot_detection", "reboot_event_detection"]
    elif blocker in {
        "post_reboot_summary_missing",
        "post_start_blocked_not_zero",
        "service_green_not_1",
        "host_188_service_green_not_1",
    }:
        category = "post_reboot_service_readiness"
        owner_lane = "service_readiness_and_k3s_workloads"
        next_safe_action = (
            "collect_post_reboot_readiness_summary_and_public_health_no_restart"
        )
        post_verifier = "scripts/reboot-recovery/post-reboot-readiness-summary.sh"
        evidence_inputs = ["post_reboot_readiness", "public_health_readback"]
    elif blocker == "backup_core_green_not_1" or "backup" in blocker:
        category = "backup_observability"
        owner_lane = "backup_health_and_restore_drill"
        next_safe_action = (
            "collect_backup_health_restore_drill_and_offsite_readback_no_restore"
        )
        post_verifier = "scripts/ops/backup-health-textfile-exporter.py --help"
        evidence_inputs = [
            "post_reboot_readiness.backup_core_green",
            "backup_health_textfile",
            "restore_drill_readback",
        ]
    elif blocker == "wazuh_dashboard_degraded":
        category = "security_observability"
        owner_lane = "wazuh_dashboard_and_security_readback"
        severity = "warning"
        next_safe_action = "collect_wazuh_dashboard_readback_no_service_restart"
        post_verifier = "read_wazuh_dashboard_or_registry_health_readback"
        evidence_inputs = ["post_reboot_readiness.wazuh_dashboard_degraded"]
    elif blocker in _PUBLIC_MAINTENANCE_BLOCKERS or blocker.startswith("public_"):
        category = "public_maintenance_fallback"
        owner_lane = "public_route_maintenance_fallback"
        next_safe_action = (
            "run_public_maintenance_fallback_probe_and_rerun_scorecard_no_reload"
        )
        post_verifier = (
            "python3 scripts/reboot-recovery/public-maintenance-fallback-probe.py"
        )
        evidence_inputs = ["public_maintenance_fallback"]
        controlled_apply_mode = "check_mode_then_separate_edge_or_nginx_apply"
    elif "stockplatform" in blocker or "product_data" in blocker:
        category = "product_data_freshness"
        owner_lane = "stockplatform_freshness_and_ingestion"
        next_safe_action = (
            "inspect_stockplatform_freshness_ingestion_readback_then_check_mode_"
            "recovery_if_required_no_manual_db_write"
        )
        post_verifier = "stockplatform_public_api_freshness_and_ingestion_readback"
        evidence_inputs = ["stockplatform_data_freshness"]
        controlled_apply_mode = "check_mode_then_controlled_data_recovery_lane"
        forbidden_actions.extend(
            ["manual_zero_fill", "copy_previous_trading_day_data"]
        )
    elif blocker in {
        "host_pressure_high_load",
        "host_container_cpu_attribution_stale",
        "host_110_gitea_cpu_pressure",
        "host_188_postgres_cpu_pressure",
        "awooop_conversation_event_hot_path_index_drift_detected",
        "conversation_event_hot_path_index_migration_source_missing",
    }:
        category = "host_cpu_pressure"
        owner_lane = "host_pressure_controller"
        if blocker == "conversation_event_hot_path_index_migration_source_missing":
            next_safe_action = (
                "restore_conversation_event_hot_path_migration_source_then_rerun_"
                "host_pressure_and_reboot_slo_scorecard_no_restart"
            )
            post_verifier = (
                "source_controls_conversation_event_hot_path_index_migration_"
                "and_host_pressure_readback"
            )
            evidence_inputs = ["source_controls", "runtime_metric_readback"]
        else:
            next_safe_action = (
                "collect_sanitized_host_pressure_and_apply_allowed_playbook_if_"
                "verifier_green_no_restart"
            )
            post_verifier = "host_pressure_readback_and_reboot_slo_scorecard"
            evidence_inputs = ["host_pressure"]
        controlled_apply_mode = "playbook_check_mode_then_controlled_apply_if_low_risk"
        forbidden_actions.extend(
            ["unmask_legacy_runner_or_restore_generic_labels", "kill_process_without_gate"]
        )
    elif blocker == "local_disk_free_below_minimum":
        category = "host_capacity"
        owner_lane = "capacity_and_disk_hygiene"
        next_safe_action = "collect_disk_usage_inventory_and_prepare_cleanup_dry_run"
        post_verifier = "df_and_capacity_scorecard_readback"
        evidence_inputs = ["capacity"]
        controlled_apply_mode = "cleanup_dry_run_then_controlled_apply"

    return {
        "blocker": blocker,
        "priority_order": priority_order,
        "is_primary": is_primary,
        "category": category,
        "owner_lane": owner_lane,
        "telegram_alert": "RebootAutoRecoveryActiveBlocker",
        "telegram_alert_required": True,
        "telegram_severity": severity,
        "metric_name": "awoooi_reboot_auto_recovery_slo_active_blocker",
        "evidence_inputs": evidence_inputs,
        "next_safe_action": next_safe_action,
        "post_verifier": post_verifier,
        "controlled_apply_mode": controlled_apply_mode,
        "controlled_apply_authorized_by_scorecard": False,
        "forbidden_actions": _unique_strings(forbidden_actions),
    }


def _count_by(items: list[dict[str, Any]], key: str) -> dict[str, int]:
    counts: dict[str, int] = {}
    for item in items:
        value = str(item.get(key) or "unknown")
        counts[value] = counts.get(value, 0) + 1
    return counts


def _require_operation_boundaries(payload: dict[str, Any], label: str) -> None:
    boundaries = _dict(payload.get("operation_boundaries"))
    forbidden_true = [
        key
        for key in (
            "host_reboot_performed",
            "host_restart_performed",
            "service_restart_performed",
            "database_write_or_restore_performed",
            "stockplatform_manual_data_write_performed",
            "secret_value_collection_allowed",
            "github_api_used",
            "workflow_trigger_performed",
            "runtime_write_allowed",
        )
        if boundaries.get(key) is True
    ]
    if forbidden_true:
        raise ValueError(f"{label}: forbidden operation boundary true: {forbidden_true}")


def _dict(value: Any) -> dict[str, Any]:
    return value if isinstance(value, dict) else {}


def _int(value: Any) -> int:
    if isinstance(value, bool):
        return int(value)
    if isinstance(value, int | float):
        return int(value)
    return 0


def _env_flag(name: str) -> bool:
    return os.environ.get(name, "").strip().lower() in {"1", "true", "yes", "on"}


def _env_float(name: str, *, default: float) -> float:
    try:
        return float(os.environ.get(name, "").strip() or default)
    except ValueError:
        return default


def _percent(value: Any) -> int:
    return max(0, min(100, round(float(value or 0))))


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


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


def _list(value: Any) -> list[Any]:
    return value if isinstance(value, list) else []


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


def _taipei_now_iso() -> str:
    return datetime.now(ZoneInfo("Asia/Taipei")).isoformat(timespec="seconds")
