from __future__ import annotations

import json
from pathlib import Path

from fastapi import FastAPI
from fastapi.testclient import TestClient

from src.api.v1 import agents
from src.api.v1.agents import router
from src.services import reboot_auto_recovery_slo_scorecard as reboot_slo_scorecard
from src.services.reboot_auto_recovery_drill_preflight import (
    load_latest_reboot_auto_recovery_drill_preflight,
)
from src.services.reboot_auto_recovery_slo_scorecard import (
    load_latest_reboot_auto_recovery_slo_scorecard,
)

EXPECTED_REBOOT_SLO_BLOCKERS = [
    "all_required_hosts_not_in_10_minute_reboot_window",
    "backup_core_green_not_1",
    "host_boot_observation_older_than_target_window",
    "host_unreachable_after_reboot",
    "host_uptime_unknown",
    "post_start_blocked_not_zero",
    "reboot_event_required_host_unreachable",
    "service_green_not_1",
    "wazuh_dashboard_degraded",
    "windows99_remote_execution_channel_unavailable",
    "windows99_vmware_autostart_readback_missing",
]

EXPECTED_DRILL_PREFLIGHT_BLOCKERS = [
    "service_green_not_ready",
    "backup_core_green_not_ready",
    "all_required_hosts_reachable_not_ready",
    "latest_verify_only_metric_present_not_ready",
    "blocked_only_by_fresh_reboot_window_not_ready",
]

EXPECTED_WINDOWS99_NEXT_STEP = (
    "restore_windows99_no_secret_management_channel_or_collect_local_console_"
    "verify_readback_then_rerun_reboot_scorecard_no_reboot"
)

PUBLIC_MAINTENANCE_RUNTIME_READY = {
    "schema_version": "awoooi_public_maintenance_fallback_probe_v1",
    "generated_at": "2026-07-02T18:08:00+08:00",
    "runtime_readback_present": True,
    "ready": True,
    "target_url_count": 6,
    "route_count": 6,
    "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": [],
    "blockers": [],
    "routes": [
        {
            "url": "https://awoooi.wooo.work/api/v1/health",
            "http_status": 200,
            "status": "normal_origin_serving",
            "fallback_header": "",
            "maintenance_body_detected": False,
            "maintenance_fallback_serving": False,
            "raw_5xx_without_fallback": False,
            "route_unreachable_without_external_fallback": False,
            "error": "",
        }
    ],
}

_REPO_ROOT = Path(__file__).resolve().parents[3]
_SOURCE_SCORECARD = (
    _REPO_ROOT
    / "docs"
    / "operations"
    / "awoooi-reboot-auto-recovery-slo-scorecard.snapshot.json"
)

PROMETHEUS_RUNTIME_BLOCKERS = [
    "all_required_hosts_not_in_10_minute_reboot_window",
    "conversation_event_hot_path_index_migration_source_missing",
    "host_boot_observation_older_than_target_window",
    "host_unreachable_after_reboot",
    "host_uptime_unknown",
    "reboot_event_required_host_unreachable",
    "windows99_vmware_autostart_readback_missing",
]
PROMETHEUS_SOURCE_RECONCILED_BLOCKER = (
    "conversation_event_hot_path_index_migration_source_missing"
)
PROMETHEUS_RUNTIME_SOURCE_RECONCILED_BLOCKERS = [
    blocker
    for blocker in PROMETHEUS_RUNTIME_BLOCKERS
    if blocker != PROMETHEUS_SOURCE_RECONCILED_BLOCKER
]

PROMETHEUS_RUNTIME_READBACK = {
    "schema_version": "reboot_slo_prometheus_metric_readback_v1",
    "readback_present": True,
    "source": "prometheus_query_api",
    "query_url": "http://192.168.0.110:9090/api/v1/query",
    "active_blockers": PROMETHEUS_RUNTIME_BLOCKERS,
    "active_blocker_count": 7,
    "primary_blocker": "reboot_event_required_host_unreachable",
    "ready": False,
    "last_run_timestamp": 1783010479,
}


def test_reboot_auto_recovery_slo_scorecard_loader_exposes_stockplatform_gate():
    payload = load_latest_reboot_auto_recovery_slo_scorecard()

    _assert_reboot_slo_payload(payload)


def test_reboot_auto_recovery_slo_scorecard_overlays_public_maintenance_runtime_artifact(
    tmp_path,
):
    runtime_path = tmp_path / "public-maintenance-fallback.json"
    runtime_path.write_text(
        json.dumps(PUBLIC_MAINTENANCE_RUNTIME_READY),
        encoding="utf-8",
    )

    payload = load_latest_reboot_auto_recovery_slo_scorecard(
        public_maintenance_runtime_path=runtime_path
    )

    assert (
        "public_maintenance_fallback_runtime_readback_missing"
        not in payload["active_blockers"]
    )
    assert payload["active_blocker_count"] == 11
    assert payload["readiness_percent"] == 47
    assert payload["required_checks"][
        "public_maintenance_fallback_runtime_ready"
    ] is True
    assert payload["public_maintenance_fallback"]["runtime_readback_present"] is True
    assert payload["public_maintenance_fallback"]["ready"] is True
    assert payload["readback"]["public_maintenance_runtime_readback_present"] is True
    assert payload["readback"]["public_maintenance_fallback_ready"] is True
    assert payload["rollups"]["public_maintenance_runtime_readback_present"] is True
    assert payload["rollups"]["public_maintenance_fallback_ready"] is True
    assert payload["reboot_sop_progress"]["current_phase"] == (
        "host_boot_detection_blocked"
    )
    assert payload["reboot_sop_progress"]["active_blocker_count"] == 11


def test_reboot_auto_recovery_slo_scorecard_overlays_runtime_scorecard_artifact(
    tmp_path,
):
    runtime_scorecard = _runtime_scorecard_with_service_data_backup_green()
    runtime_path = tmp_path / "scorecard.json"
    runtime_path.write_text(json.dumps(runtime_scorecard), encoding="utf-8")

    payload = load_latest_reboot_auto_recovery_slo_scorecard(
        runtime_scorecard_path=runtime_path
    )

    service_blockers = {
        "backup_core_green_not_1",
        "post_start_blocked_not_zero",
        "service_green_not_1",
        "wazuh_dashboard_degraded",
    }
    assert payload["runtime_scorecard_readback_present"] is True
    assert payload["runtime_scorecard_generated_at"] == (
        "2026-07-02T23:59:00+08:00"
    )
    assert payload["snapshot_generated_at"] == "2026-07-02T15:08:44+08:00"
    assert not service_blockers.intersection(payload["active_blockers"])
    assert payload["active_blocker_count"] == 7
    assert payload["readiness_percent"] == 60
    assert payload["service_green"] is True
    assert payload["backup_core_green"] is True
    assert payload["controlled_service_data_backup_readback"]["status"] == (
        "ready_service_data_backup_green"
    )
    assert payload["controlled_service_data_backup_readback"]["blocking_fields"] == []
    assert (
        payload["controlled_service_data_backup_readback"][
            "can_clear_service_data_backup_blockers"
        ]
        is True
    )
    assert payload["windows99_vmware_verify_ready"] is False
    assert payload["primary_blocker"] == "reboot_event_required_host_unreachable"
    assert payload["readback"]["runtime_scorecard_readback_present"] is True
    assert payload["rollups"]["runtime_scorecard_readback_present"] is True


def test_reboot_auto_recovery_slo_scorecard_uses_latest_runtime_scorecard_from_dir(
    tmp_path,
):
    runtime_dir = tmp_path / "reboot-recovery"
    artifact_dir = runtime_dir / "reboot-auto-recovery-slo-20260703-002055"
    artifact_dir.mkdir(parents=True)
    runtime_scorecard = json.loads(_SOURCE_SCORECARD.read_text(encoding="utf-8"))
    runtime_scorecard["generated_at"] = "2026-07-03T00:20:55+08:00"
    runtime_scorecard["active_blockers"] = [
        "all_required_hosts_not_in_10_minute_reboot_window",
        "conversation_event_hot_path_index_migration_source_missing",
        "host_boot_observation_older_than_target_window",
        "host_unreachable_after_reboot",
        "host_uptime_unknown",
        "public_maintenance_fallback_runtime_readback_missing",
        "reboot_event_required_host_unreachable",
        "windows99_vmware_autostart_readback_missing",
    ]
    runtime_scorecard["windows99_management_channel"]["ssh_users"] = [
        "administrator",
        "wooo",
    ]
    runtime_scorecard["windows99_management_channel"]["ssh_batch_candidates"] = [
        {
            "user": "administrator",
            "checked": True,
            "ready": False,
            "status": "permission_denied",
        },
        {
            "user": "wooo",
            "checked": True,
            "ready": False,
            "status": "permission_denied",
        },
    ]
    (artifact_dir / "scorecard.json").write_text(
        json.dumps(runtime_scorecard),
        encoding="utf-8",
    )

    payload = load_latest_reboot_auto_recovery_slo_scorecard(
        runtime_scorecard_dir=runtime_dir,
        public_maintenance_runtime_dir=runtime_dir,
    )

    assert payload["runtime_scorecard_readback_present"] is True
    assert payload["runtime_scorecard_generated_at"] == (
        "2026-07-03T00:20:55+08:00"
    )
    assert payload["snapshot_generated_at"] == "2026-07-02T15:08:44+08:00"
    assert payload["active_blocker_count"] == 8
    assert payload["readback"]["runtime_scorecard_source_ref"].endswith(
        "reboot-auto-recovery-slo-20260703-002055/scorecard.json"
    )
    assert (
        payload["windows99_management_channel"]["ssh_batch_candidates"][1][
            "user"
        ]
        == "wooo"
    )


def test_reboot_auto_recovery_slo_scorecard_overlays_prometheus_runtime_metrics():
    payload = load_latest_reboot_auto_recovery_slo_scorecard(
        prometheus_metric_readback=PROMETHEUS_RUNTIME_READBACK
    )

    assert payload["runtime_scorecard_readback_present"] is False
    assert payload["runtime_metric_readback_present"] is True
    assert payload["runtime_metric_active_blocker_count"] == 7
    assert payload["runtime_metric_last_run_timestamp"] == 1783010479
    assert (
        payload["runtime_metric_source_control_reconciled_blockers"]
        == [PROMETHEUS_SOURCE_RECONCILED_BLOCKER]
    )
    assert payload["runtime_metric_source_control_reconciled_blocker_count"] == 1
    assert payload["active_blockers"] == PROMETHEUS_RUNTIME_SOURCE_RECONCILED_BLOCKERS
    assert payload["active_blocker_count"] == 6
    assert payload["readiness_percent"] == 47
    assert payload["primary_blocker"] == "reboot_event_required_host_unreachable"
    assert payload["next_safe_action"] == (
        "rerun_reboot_event_detector_and_host_probe_verify_only_no_reboot"
    )
    assert "backup_core_green_not_1" not in payload["active_blockers"]
    assert "service_green_not_1" not in payload["active_blockers"]
    assert PROMETHEUS_SOURCE_RECONCILED_BLOCKER not in payload["active_blockers"]
    assert payload["active_blocker_action_matrix"]["item_count"] == 6
    action_by_blocker = {
        item["blocker"]: item
        for item in payload["active_blocker_action_matrix"]["items"]
    }
    assert PROMETHEUS_SOURCE_RECONCILED_BLOCKER not in action_by_blocker
    assert payload["active_blocker_action_matrix"]["category_counts"].get(
        "host_cpu_pressure",
        0,
    ) == 0
    assert payload["readback"]["active_blocker_count"] == 6
    assert payload["readback"]["runtime_metric_readback_present"] is True
    assert payload["readback"][
        "runtime_metric_source_control_reconciled_blocker_count"
    ] == 1
    assert payload["rollups"]["active_blocker_count"] == 6
    assert payload["rollups"]["runtime_metric_readback_present"] is True
    assert payload["rollups"][
        "runtime_metric_source_control_reconciled_blocker_count"
    ] == 1
    assert payload["rollups"]["primary_blocker_owner_lane"] == (
        "reboot_event_detector_and_host_probe"
    )


def test_reboot_auto_recovery_slo_scorecard_keeps_prometheus_source_missing_when_source_control_missing(
    tmp_path,
):
    scorecard = json.loads(_SOURCE_SCORECARD.read_text(encoding="utf-8"))
    scorecard["source_controls"][
        "conversation_event_hot_path_index_migration_source_present"
    ] = False
    (tmp_path / _SOURCE_SCORECARD.name).write_text(
        json.dumps(scorecard),
        encoding="utf-8",
    )

    payload = load_latest_reboot_auto_recovery_slo_scorecard(
        operations_dir=tmp_path,
        prometheus_metric_readback=PROMETHEUS_RUNTIME_READBACK,
    )

    assert payload["active_blockers"] == PROMETHEUS_RUNTIME_BLOCKERS
    assert payload["active_blocker_count"] == 7
    assert payload["runtime_metric_source_control_reconciled_blocker_count"] == 0
    action_by_blocker = {
        item["blocker"]: item
        for item in payload["active_blocker_action_matrix"]["items"]
    }
    hot_path_source_action = action_by_blocker[PROMETHEUS_SOURCE_RECONCILED_BLOCKER]
    assert hot_path_source_action["category"] == "host_cpu_pressure"
    assert hot_path_source_action["owner_lane"] == "host_pressure_controller"
    assert hot_path_source_action["evidence_inputs"] == [
        "source_controls",
        "runtime_metric_readback",
    ]
    assert hot_path_source_action["next_safe_action"] == (
        "restore_conversation_event_hot_path_migration_source_then_rerun_"
        "host_pressure_and_reboot_slo_scorecard_no_restart"
    )
    assert payload["active_blocker_action_matrix"]["category_counts"][
        "host_cpu_pressure"
    ] == 1


def test_reboot_slo_prometheus_readback_uses_single_combined_query(monkeypatch):
    monkeypatch.delenv("AWOOOI_REBOOT_SLO_PROMETHEUS_TIMEOUT_SECONDS", raising=False)
    calls = []

    def fake_query_prometheus_vector(query_url, query, *, timeout_seconds):
        calls.append((query_url, query, timeout_seconds))
        active_metric = "awoooi_reboot_auto_recovery_slo_active_blocker"
        return [
            *[
                {
                    "metric": {"__name__": active_metric, "blocker": blocker},
                    "value": [1783010479, "1"],
                }
                for blocker in PROMETHEUS_RUNTIME_BLOCKERS
            ],
            {
                "metric": {
                    "__name__": "awoooi_reboot_auto_recovery_slo_primary_blocker",
                    "blocker": "reboot_event_required_host_unreachable",
                },
                "value": [1783010479, "1"],
            },
            {
                "metric": {
                    "__name__": "awoooi_reboot_auto_recovery_slo_blocker_count",
                },
                "value": [1783010479, "7"],
            },
            {
                "metric": {"__name__": "awoooi_reboot_auto_recovery_slo_ready"},
                "value": [1783010479, "0"],
            },
            {
                "metric": {
                    "__name__": "awoooi_reboot_auto_recovery_slo_last_run_timestamp",
                },
                "value": [1783010479, "1783010479"],
            },
        ]

    monkeypatch.setattr(
        reboot_slo_scorecard,
        "_query_prometheus_vector",
        fake_query_prometheus_vector,
    )

    payload = reboot_slo_scorecard._load_reboot_slo_prometheus_metric_readback(
        prometheus_query_url="http://prometheus.example/api/v1/query"
    )

    assert len(calls) == 1
    assert calls[0][0] == "http://prometheus.example/api/v1/query"
    assert calls[0][2] == 1.0
    assert "awoooi_reboot_auto_recovery_slo_active_blocker" in calls[0][1]
    assert "awoooi_reboot_auto_recovery_slo_last_run_timestamp" in calls[0][1]
    assert payload["readback_present"] is True
    assert payload["active_blockers"] == PROMETHEUS_RUNTIME_BLOCKERS
    assert payload["active_blocker_count"] == 7
    assert payload["primary_blocker"] == "reboot_event_required_host_unreachable"
    assert payload["ready"] is False
    assert payload["last_run_timestamp"] == 1783010479


def test_reboot_auto_recovery_slo_scorecard_endpoint_returns_readback(monkeypatch):
    monkeypatch.setattr(
        agents,
        "load_latest_stockplatform_public_api_runtime_readback",
        _stockplatform_runtime_ready,
    )
    app = FastAPI()
    app.include_router(router, prefix="/api/v1")
    client = TestClient(app)

    response = client.get("/api/v1/agents/reboot-auto-recovery-slo-scorecard")

    assert response.status_code == 200
    _assert_reboot_slo_payload(response.json())


def test_reboot_auto_recovery_slo_scorecard_endpoint_overlays_live_stockplatform_blocked(
    monkeypatch,
):
    monkeypatch.setattr(
        agents,
        "load_latest_stockplatform_public_api_runtime_readback",
        _stockplatform_runtime_blocked,
    )
    app = FastAPI()
    app.include_router(router, prefix="/api/v1")
    client = TestClient(app)

    response = client.get("/api/v1/agents/reboot-auto-recovery-slo-scorecard")

    assert response.status_code == 200
    payload = response.json()
    assert payload["stockplatform_freshness_status"] == "blocked"
    assert payload["stockplatform_ingestion_status"] == "blocked"
    assert payload["stockplatform_data_freshness"]["latest_trading_date"] == (
        "2026-07-02"
    )
    assert payload["stockplatform_data_freshness"]["freshness_sla_source_count"] == 9
    assert payload["stockplatform_data_freshness"]["freshness_blockers"] == [
        "core_margin_short_daily_missing",
        "ai_recommendations_stale",
    ]
    assert payload["stockplatform_data_freshness"]["ingestion_blockers"] == [
        "core.margin_short_daily_incomplete"
    ]
    assert payload["product_data_green"] is False
    assert payload["required_checks"]["stockplatform_freshness_ok"] is False
    assert payload["required_checks"]["stockplatform_ingestion_ok"] is False
    assert payload["required_checks"]["product_data_green"] is False
    assert payload["readiness_percent"] == 27
    assert payload["active_blocker_count"] == 15
    assert "product_data_green_not_1" in payload["active_blockers"]
    assert "stockplatform_freshness_core_margin_short_daily_missing" in payload[
        "active_blockers"
    ]
    assert "stockplatform_ingestion_core.margin_short_daily_incomplete" in payload[
        "active_blockers"
    ]
    assert payload["rollups"]["stockplatform_freshness_status"] == "blocked"
    assert payload["rollups"]["stockplatform_freshness_sla_source_count"] == 9
    assert payload["controlled_service_data_backup_readback"][
        "product_data_green"
    ] is False
    assert "stockplatform_freshness_status" in payload[
        "controlled_service_data_backup_readback"
    ]["blocking_fields"]
    assert payload["rollups"]["controlled_service_data_backup_blocker_count"] == 7


def test_reboot_auto_recovery_drill_preflight_loader_returns_break_glass_package():
    payload = load_latest_reboot_auto_recovery_drill_preflight()

    _assert_drill_preflight_payload(payload)


def test_reboot_auto_recovery_drill_preflight_endpoint_returns_readback():
    app = FastAPI()
    app.include_router(router, prefix="/api/v1")
    client = TestClient(app)

    response = client.get("/api/v1/agents/reboot-auto-recovery-drill-preflight")

    assert response.status_code == 200
    _assert_drill_preflight_payload(response.json())


def _assert_reboot_slo_payload(payload: dict):
    assert payload["schema_version"] == "reboot_auto_recovery_slo_scorecard_readback_v1"
    assert payload["snapshot_generated_at"] == "2026-07-02T15:08:44+08:00"
    assert payload["generated_at"] != payload["snapshot_generated_at"]
    assert payload["generated_at"].endswith("+08:00")
    assert payload["runtime_readback_generated_at"] == payload["generated_at"]
    assert payload["priority"] == "P0-006"
    assert payload["status"] == "blocked_reboot_auto_recovery_slo_not_ready"
    assert payload["current_phase"] == "host_boot_detection_blocked"
    assert payload["eta_or_wait_reason"] == (
        "target_window_elapsed_eta_unavailable_until_fresh_all_host_reboot_"
        "event_and_probe"
    )
    assert payload["primary_blocker"] == "reboot_event_required_host_unreachable"
    assert payload["safe_next_step"] == EXPECTED_WINDOWS99_NEXT_STEP
    assert payload["next_safe_action"] == payload["safe_next_step"]
    assert payload["can_claim_all_services_recovered_within_target"] is False
    assert payload["active_blocker_count"] == 11
    assert payload["readiness_percent"] == 47
    assert payload["service_green"] is False
    assert payload["product_data_green"] is True
    assert payload["backup_core_green"] is False
    assert payload["host_188_service_green"] is True
    assert payload["observed_host_count"] == 7
    assert payload["missing_host_count"] == 0
    assert payload["unreachable_host_count"] == 1
    assert payload["stale_host_count"] == 5
    assert payload["blocked_by_fresh_reboot_window_only"] is False
    assert payload["latest_verify_only_metric_present"] is False
    assert payload["latest_verify_only_metric_ready"] == 0
    assert payload["latest_verify_only_metric_blocker_count"] == 0
    assert payload["latest_verify_only_metric_max_host_uptime_seconds"] == 0
    assert payload["latest_verify_only_metric_last_run_timestamp"] == 0
    assert payload["stockplatform_freshness_status"] == "ok"
    assert payload["stockplatform_ingestion_status"] == "ok"
    assert payload["required_checks"][
        "public_maintenance_fallback_runtime_ready"
    ] is True
    assert payload["public_maintenance_fallback"]["runtime_readback_present"] is True
    assert payload["public_maintenance_fallback"]["ready"] is True
    assert payload["public_maintenance_fallback"]["blockers"] == []
    assert payload["public_maintenance_fallback"]["route_count"] == 6
    assert payload["public_maintenance_fallback"][
        "raw_5xx_without_fallback_count"
    ] == 0
    assert payload["public_maintenance_fallback"][
        "route_unreachable_without_external_fallback_count"
    ] == 0
    assert payload["windows99_vmware_verify_ready"] is False
    assert payload["windows99_update_no_auto_reboot_ready"] is False
    assert payload["windows99_remote_execution_channel_ready"] is False
    assert payload["windows99_ssh_batch_status"] == "permission_denied"
    assert payload["source_controls"][
        "host_110_startup_controlled_drain_guarded_autostart_source_present"
    ] is True
    assert payload["source_controls"][
        "windows99_management_channel_probe_source_present"
    ] is True
    assert payload["readback"]["workplan_id"] == "P0-006"
    assert payload["readback"]["generated_at"] == payload["generated_at"]
    assert payload["readback"]["runtime_readback_generated_at"] == payload[
        "generated_at"
    ]
    assert payload["readback"]["snapshot_generated_at"] == payload[
        "snapshot_generated_at"
    ]
    assert payload["readback"]["target_minutes"] == 10
    assert payload["readback"]["current_phase"] == "host_boot_detection_blocked"
    assert payload["readback"]["eta_or_wait_reason"] == (
        "target_window_elapsed_eta_unavailable_until_fresh_all_host_reboot_"
        "event_and_probe"
    )
    assert payload["readback"]["primary_blocker"] == (
        "reboot_event_required_host_unreachable"
    )
    assert payload["readback"]["safe_next_step"] == EXPECTED_WINDOWS99_NEXT_STEP
    assert payload["readback"]["next_safe_action"] == payload["safe_next_step"]
    assert payload["readback"]["active_blocker_count"] == 11
    assert payload["readback"]["readiness_percent"] == 47
    assert payload["readback"]["blocked_by_fresh_reboot_window_only"] is False
    assert payload["readback"]["latest_verify_only_metric_present"] is False
    assert payload["readback"]["public_maintenance_runtime_readback_present"] is True
    assert payload["readback"]["public_maintenance_fallback_ready"] is True
    assert payload["readback"]["public_route_raw_5xx_without_fallback_count"] == 0
    assert payload["readback"]["windows99_vmware_verify_ready"] is False
    assert payload["readback"]["windows99_update_no_auto_reboot_ready"] is False
    assert payload["readback"]["windows99_verify_collection_status"] == (
        "blocked_windows99_verify_output_missing_host_reachable"
    )
    assert (
        payload["readback"]["windows99_verify_collection_can_collect_no_secret"]
        is True
    )
    assert payload["readback"]["windows99_remote_execution_channel_ready"] is False
    assert payload["readback"]["windows99_ssh_batch_status"] == "permission_denied"
    assert payload["rollups"]["active_blocker_count"] == 11
    assert payload["rollups"]["readiness_percent"] == 47
    assert payload["rollups"]["observed_host_count"] == 7
    assert payload["rollups"]["missing_host_count"] == 0
    assert payload["rollups"]["unreachable_host_count"] == 1
    assert payload["rollups"]["stale_host_count"] == 5
    assert payload["rollups"]["service_green"] is False
    assert payload["rollups"]["product_data_green"] is True
    assert payload["rollups"]["backup_core_green"] is False
    assert payload["rollups"]["host_188_service_green"] is True
    assert payload["rollups"]["blocked_by_fresh_reboot_window_only"] is False
    assert payload["rollups"]["latest_verify_only_metric_present"] is False
    assert payload["rollups"]["latest_verify_only_metric_ready"] == 0
    assert payload["rollups"]["latest_verify_only_metric_blocker_count"] == 0
    assert payload["rollups"]["stockplatform_freshness_status"] == "ok"
    assert payload["rollups"]["stockplatform_ingestion_status"] == "ok"
    assert payload["rollups"]["stockplatform_freshness_blocker_count"] == 0
    assert payload["rollups"]["stockplatform_ingestion_blocker_count"] == 0
    assert payload["rollups"]["public_maintenance_runtime_readback_present"] is True
    assert payload["rollups"]["public_maintenance_fallback_ready"] is True
    assert payload["rollups"]["public_route_raw_5xx_without_fallback_count"] == 0
    assert (
        payload["rollups"]["controlled_service_data_backup_readback_present"]
        is True
    )
    assert payload["rollups"]["controlled_service_data_backup_blocker_count"] == 4
    assert (
        payload["rollups"]["controlled_service_data_backup_can_clear_blockers"]
        is False
    )
    assert payload["rollups"]["controlled_service_data_backup_readback_status"] == (
        "blocked_service_data_backup_readback_not_green"
    )
    assert payload["rollups"]["windows99_vmware_readback_present"] is False
    assert payload["rollups"]["windows99_vmware_verify_ready"] is False
    assert payload["rollups"]["windows99_update_no_auto_reboot_ready"] is False
    assert payload["rollups"]["windows99_verify_collection_status"] == (
        "blocked_windows99_verify_output_missing_host_reachable"
    )
    assert (
        payload["rollups"]["windows99_verify_collection_can_collect_no_secret"]
        is True
    )
    assert payload["rollups"]["windows99_verify_collection_blocker_count"] == 2
    assert payload["rollups"]["windows99_host99_reachable"] is True
    assert payload["rollups"]["windows99_host99_uptime_known"] is False
    assert payload["rollups"]["windows99_management_readback_present"] is True
    assert payload["rollups"]["windows99_host_reachable"] is True
    assert payload["rollups"]["windows99_remote_execution_channel_ready"] is False
    assert payload["rollups"]["windows99_ssh_batch_status"] == "permission_denied"
    assert payload["rollups"]["runtime_readback_generated_at_present"] is True
    assert payload["rollups"]["windows99_hyperv_vmconnect_open"] is True
    assert payload["rollups"]["windows99_rdp_console_reachable"] is True
    assert (
        payload["rollups"]["windows99_local_console_channel_reachable"]
        is True
    )
    assert payload["rollups"]["windows99_console_collection_channels"] == [
        "rdp_console",
        "hyperv_vmconnect",
    ]
    assert payload["rollups"]["stockplatform_final_retry_window_passed"] is False
    assert (
        payload["rollups"]["stockplatform_controlled_recovery_gate_required"]
        is False
    )
    assert payload["active_blockers"] == EXPECTED_REBOOT_SLO_BLOCKERS
    matrix = payload["active_blocker_action_matrix"]
    assert matrix["schema_version"] == "reboot_active_blocker_action_matrix_v1"
    assert matrix["item_count"] == 11
    assert matrix["telegram_alert_required_count"] == 11
    assert matrix["primary_blocker_action"]["blocker"] == (
        "reboot_event_required_host_unreachable"
    )
    assert matrix["primary_blocker_action"]["category"] == "host_boot_detection"
    assert matrix["primary_blocker_action"]["owner_lane"] == (
        "reboot_event_detector_and_host_probe"
    )
    assert matrix["category_counts"]["host_boot_detection"] == 5
    assert matrix["category_counts"]["windows99_vmware_autostart"] == 2
    assert matrix["category_counts"]["backup_observability"] == 1
    action_by_blocker = {item["blocker"]: item for item in matrix["items"]}
    assert action_by_blocker["windows99_remote_execution_channel_unavailable"][
        "owner_lane"
    ] == "windows99_console_or_no_secret_management_channel"
    assert action_by_blocker["backup_core_green_not_1"]["category"] == (
        "backup_observability"
    )
    assert action_by_blocker["wazuh_dashboard_degraded"][
        "telegram_severity"
    ] == "warning"
    assert action_by_blocker["reboot_event_required_host_unreachable"][
        "controlled_apply_authorized_by_scorecard"
    ] is False
    assert "host_reboot" in action_by_blocker[
        "reboot_event_required_host_unreachable"
    ]["forbidden_actions"]
    assert payload["readback"]["active_blocker_action_count"] == 11
    assert payload["readback"]["primary_blocker_owner_lane"] == (
        "reboot_event_detector_and_host_probe"
    )
    assert payload["rollups"]["active_blocker_action_category_counts"][
        "windows99_vmware_autostart"
    ] == 2
    progress = payload["reboot_sop_progress"]
    assert progress["current_phase"] == "host_boot_detection_blocked"
    assert progress["eta_or_wait_reason"] == (
        "target_window_elapsed_eta_unavailable_until_fresh_all_host_reboot_"
        "event_and_probe"
    )
    assert progress["primary_blocker"] == "reboot_event_required_host_unreachable"
    assert progress["active_blocker_count"] == 11
    assert progress["readiness_percent"] == 47
    assert progress["next_safe_action"] == payload["safe_next_step"]
    assert progress["fixed_triage_order"][0] == "99_vmware_autostart_and_vm_power"
    service_data_backup = payload["controlled_service_data_backup_readback"]
    assert service_data_backup["schema_version"] == (
        "controlled_service_data_backup_readback_v1"
    )
    assert service_data_backup["status"] == (
        "blocked_service_data_backup_readback_not_green"
    )
    assert service_data_backup["readback_present"] is True
    assert service_data_backup["service_green"] is False
    assert service_data_backup["product_data_green"] is True
    assert service_data_backup["backup_core_green"] is False
    assert service_data_backup["host_188_service_green"] is True
    assert service_data_backup["post_start_blocked"] == 1
    assert service_data_backup["wazuh_dashboard_degraded"] is True
    assert service_data_backup["stockplatform_freshness_status"] == "ok"
    assert service_data_backup["stockplatform_ingestion_status"] == "ok"
    assert service_data_backup["blocking_fields"] == [
        "service_green",
        "post_start_blocked",
        "backup_core_green",
        "wazuh_dashboard_degraded",
    ]
    assert service_data_backup["related_active_blockers"] == [
        "backup_core_green_not_1",
        "post_start_blocked_not_zero",
        "service_green_not_1",
        "wazuh_dashboard_degraded",
    ]
    assert service_data_backup["can_clear_service_data_backup_blockers"] is False
    assert service_data_backup["next_safe_action"] == (
        "collect_public_service_data_backup_readback_and_refresh_reboot_slo_"
        "scorecard_no_reboot_no_db_write"
    )
    assert service_data_backup["runtime_write_allowed"] is False
    assert "host_reboot" in service_data_backup["forbidden_actions"]
    assert "manual_db_update" in service_data_backup["forbidden_actions"]
    windows99 = payload["windows99_vmware_autostart"]
    assert windows99["readback_present"] is False
    assert windows99["required_vm_aliases"] == ["111", "112", "120", "121", "188"]
    assert windows99["blockers"] == ["windows99_vmware_autostart_readback_missing"]
    collection = payload["windows99_verify_collection"]
    assert collection["schema_version"] == (
        "windows99_vmware_verify_collection_packet_v1"
    )
    assert collection["target_host"] in {"192.168.0.99", "host:internal-node"}
    assert collection["host99_reachable"] is True
    assert collection["host99_uptime_known"] is False
    assert collection["readback_present"] is False
    assert collection["verify_ready"] is False
    assert collection["can_collect_no_secret_verify"] is True
    assert collection["collection_blockers"] == [
        "windows99_vmware_autostart_readback_missing",
        "windows99_uptime_unknown",
    ]
    assert "VMRUN_PRESENT" in collection["expected_no_secret_output_fields"]
    assert "-Mode Verify" in collection["no_secret_verify_command"]
    assert collection["no_secret_collector_check_command"] == (
        "bash scripts/reboot-recovery/collect-windows99-vmware-verify.sh --check"
    )
    assert collection["no_secret_collector_collect_command"] == (
        "bash scripts/reboot-recovery/collect-windows99-vmware-verify.sh --collect"
    )
    assert (
        "no_secret_ssh_batchmode_verify_collector"
        in collection["safe_collection_channels"]
    )
    assert "host_reboot" in collection["forbidden_actions"]
    assert "windows_password_or_secret_collection" in collection["forbidden_actions"]
    windows99_management = payload["windows99_management_channel"]
    assert windows99_management["readback_present"] is True
    assert windows99_management["host_reachable"] is True
    assert windows99_management["remote_execution_channel_ready"] is False
    assert windows99_management["ssh_batch"]["status"] == "permission_denied"
    assert windows99_management["hyperv_vmconnect_open"] is True
    assert windows99_management["rdp_console_reachable"] is True
    assert windows99_management["local_console_channel_reachable"] is True
    assert windows99_management["console_collection_channels"] == [
        "rdp_console",
        "hyperv_vmconnect",
    ]
    stockplatform = payload["stockplatform_data_freshness"]
    assert stockplatform["freshness_endpoint_readback_present"] is True
    assert stockplatform["ingestion_endpoint_readback_present"] is True
    assert stockplatform["freshness_blockers"] == []
    assert stockplatform["ingestion_blockers"] == []
    assert stockplatform["margin_short_recovery"]["status"] == "not_verified"
    assert stockplatform["margin_short_recovery"]["successful_source_run_ids"] == []
    assert stockplatform["ai_recommendations_recovery"]["status"] == "recovered"
    assert stockplatform["eod_window"]["final_retry_window_passed"] is False
    assert stockplatform["controlled_recovery_gate"]["required"] is False
    assert (
        stockplatform["controlled_recovery_gate"]["status"]
        == "not_required_freshness_recovered"
    )
    assert "manual_db_update" in stockplatform["controlled_recovery_gate"][
        "forbidden_actions"
    ]
    boundaries = payload["operation_boundaries"]
    assert boundaries["host_reboot_performed"] is False
    assert boundaries["service_restart_performed"] is False
    assert boundaries["database_write_or_restore_performed"] is False
    assert boundaries["stockplatform_manual_data_write_performed"] is False
    assert boundaries["secret_value_collection_allowed"] is False
    assert boundaries["github_api_used"] is False


def _assert_drill_preflight_payload(payload: dict):
    assert (
        payload["schema_version"]
        == "reboot_auto_recovery_drill_preflight_readback_v1"
    )
    assert payload["priority"] == "P0-006"
    assert payload["status"] == "blocked_reboot_drill_preflight_not_ready"
    assert payload["preflight_ready"] is False
    assert payload["preflight_blocker_count"] == 5
    assert payload["active_blockers"] == EXPECTED_DRILL_PREFLIGHT_BLOCKERS
    assert payload["break_glass_authorization_required"] is True
    assert payload["execution_authorized_by_this_endpoint"] is False
    assert payload["safe_next_step"] == (
        "collect_separate_reboot_drill_authorization_or_wait_for_next_"
        "real_all_host_reboot_event_then_rerun_verify_only"
    )
    target_selector = payload["target_selector"]
    assert target_selector["required_host_aliases"] == [
        "110",
        "111",
        "112",
        "120",
        "121",
        "188",
        "99",
    ]
    assert target_selector["required_host_count"] == 7
    assert target_selector["observed_host_count"] == 7
    assert target_selector["missing_host_count"] == 0
    assert target_selector["unreachable_host_count"] == 1
    assert target_selector["stale_host_count"] == 5
    assert set(payload["preconditions"]) == {
        "source_controls_present",
        "service_green",
        "product_data_green",
        "backup_core_green",
        "host_188_service_green",
        "all_required_hosts_observed",
        "all_required_hosts_reachable",
        "latest_verify_only_metric_present",
        "stockplatform_freshness_ok",
        "stockplatform_ingestion_ok",
        "blocked_only_by_fresh_reboot_window",
    }
    assert payload["preconditions"] == {
        "source_controls_present": True,
        "service_green": False,
        "product_data_green": True,
        "backup_core_green": False,
        "host_188_service_green": True,
        "all_required_hosts_observed": True,
        "all_required_hosts_reachable": False,
        "latest_verify_only_metric_present": False,
        "stockplatform_freshness_ok": True,
        "stockplatform_ingestion_ok": True,
        "blocked_only_by_fresh_reboot_window": False,
    }
    current = payload["current_readback"]
    assert current["scorecard_status"] == "blocked_reboot_auto_recovery_slo_not_ready"
    assert current["readiness_percent"] == 47
    assert current["active_blocker_count"] == 11
    assert current["active_blockers"] == EXPECTED_REBOOT_SLO_BLOCKERS
    assert current["latest_verify_only_metric_ready"] == 0
    assert current["latest_verify_only_metric_blocker_count"] == 0
    assert current["stockplatform_freshness_status"] == "ok"
    assert current["stockplatform_ingestion_status"] == "ok"
    check_mode = payload["check_mode"]
    assert check_mode["verify_only_available"] is True
    assert (
        check_mode["post_apply_verifier_endpoint"]
        == "/api/v1/agents/reboot-auto-recovery-slo-scorecard"
    )
    expected = check_mode["expected_after_real_fresh_boot_or_approved_drill"]
    assert expected["status"] == "slo_ready"
    assert expected["active_blocker_count"] == 0
    assert expected["latest_verify_only_metric_ready"] == 1
    assert expected["latest_verify_only_metric_blocker_count"] == 0
    assert expected["max_host_uptime_seconds_lte"] == 600
    rollback = payload["rollback_plan"]
    assert rollback["preflight_is_read_only"] is True
    assert rollback["rollback_required_for_this_endpoint"] is False
    readback = payload["readback"]
    assert readback["workplan_id"] == "P0-006"
    assert readback["preflight_ready"] is False
    assert readback["target_selector"]["required_host_count"] == 7
    assert readback["current_readback"]["active_blocker_count"] == 11
    assert readback["safe_next_step"] == payload["safe_next_step"]
    rollups = payload["rollups"]
    assert rollups["preflight_ready"] is False
    assert rollups["preflight_ready_count"] == 0
    assert rollups["preflight_blocker_count"] == 5
    assert rollups["target_required_host_count"] == 7
    assert rollups["target_observed_host_count"] == 7
    assert rollups["target_unreachable_host_count"] == 1
    assert rollups["blocked_only_by_fresh_reboot_window"] is False
    assert rollups["host_reboot_authorized_by_this_endpoint"] is False
    boundaries = payload["operation_boundaries"]
    assert boundaries["host_reboot_authorized_by_this_endpoint"] is False
    assert boundaries["host_reboot_performed"] is False
    assert boundaries["service_restart_performed"] is False
    assert boundaries["database_write_or_restore_performed"] is False
    assert boundaries["workflow_trigger_performed"] is False
    assert boundaries["secret_value_collection_allowed"] is False
    assert boundaries["github_api_used"] is False
    assert boundaries["runtime_write_allowed"] is False
    assert "host_reboot" in payload["forbidden_without_separate_break_glass"]


def _stockplatform_runtime_ready() -> dict:
    return {
        "schema_version": "stockplatform_public_api_runtime_readback_v1",
        "status": "stockplatform_public_api_runtime_ready",
        "runtime_ready": True,
        "active_blockers": [],
        "readback": {
            "freshness_status": "ok",
            "ingestion_status": "ok",
            "freshness_latest_trading_date": "2026-07-02",
            "ingestion_latest_trading_date": "2026-07-02",
            "freshness_blockers": [],
            "ingestion_blockers": [],
            "freshness_sla_source_count": 9,
            "freshness_source_count": 9,
            "freshness_non_ok_source_count": 0,
        },
    }


def _stockplatform_runtime_blocked() -> dict:
    return {
        "schema_version": "stockplatform_public_api_runtime_readback_v1",
        "status": "blocked_stockplatform_public_api_runtime_drift",
        "runtime_ready": False,
        "active_blockers": [
            "stockplatform_freshness_core_margin_short_daily_missing",
            "stockplatform_freshness_ai_recommendations_stale",
            "stockplatform_ingestion_core.margin_short_daily_incomplete",
        ],
        "readback": {
            "freshness_status": "blocked",
            "ingestion_status": "blocked",
            "freshness_latest_trading_date": "2026-07-02",
            "ingestion_latest_trading_date": "2026-07-02",
            "freshness_blockers": [
                "core_margin_short_daily_missing",
                "ai_recommendations_stale",
            ],
            "ingestion_blockers": ["core.margin_short_daily_incomplete"],
            "freshness_sla_source_count": 9,
            "freshness_source_count": 9,
            "freshness_non_ok_source_count": 3,
        },
    }


def _runtime_scorecard_with_service_data_backup_green() -> dict:
    source_path = (
        Path(__file__).resolve().parents[3]
        / "docs/operations/awoooi-reboot-auto-recovery-slo-scorecard.snapshot.json"
    )
    payload = json.loads(source_path.read_text(encoding="utf-8"))
    payload["generated_at"] = "2026-07-02T23:59:00+08:00"
    payload["active_blockers"] = [
        blocker
        for blocker in payload["active_blockers"]
        if blocker
        not in {
            "backup_core_green_not_1",
            "post_start_blocked_not_zero",
            "service_green_not_1",
            "wazuh_dashboard_degraded",
        }
    ]
    payload["post_reboot_readiness"].update(
        {
            "backup_core_green": True,
            "post_start_blocked": 0,
            "post_start_result": "FULL_STACK_GREEN_REBOOT_SLO_HOST_BLOCKED",
            "service_green": True,
            "wazuh_dashboard_degraded": False,
        }
    )
    return payload
