from __future__ import annotations

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.harbor_registry_controlled_recovery_preflight import (
    load_latest_harbor_registry_controlled_recovery_preflight,
)


def test_harbor_registry_preflight_packages_110_upstream_502(tmp_path: Path) -> None:
    payload = load_latest_harbor_registry_controlled_recovery_preflight(
        route_source_path=_route_source(tmp_path),
        watchdog_source_path=_watchdog_source(tmp_path),
        probe=_probe_for_upstream_502,
    )

    assert payload["schema_version"] == "harbor_registry_controlled_recovery_preflight_v1"
    assert payload["priority"] == "P0-006"
    assert payload["status"] == (
        "controlled_recovery_preflight_packaged_harbor_registry_upstream_502"
    )
    assert payload["source_of_truth_diff"]["status"] == (
        "route_source_present_110_harbor_registry_upstream_502"
    )
    assert payload["rollups"]["harbor_registry_upstream_502_shape"] is True
    assert payload["rollups"]["controlled_recovery_candidate_packaged"] is True
    assert payload["rollups"]["control_channel_readback_required"] is True
    assert payload["rollups"]["awoooi_host_runner_required"] is True
    assert payload["rollups"]["ssh_publickey_diagnosis_required"] is True
    assert payload["rollups"]["watchdog_executor_ready"] is True
    assert payload["control_channel_contract"]["required_before_runtime_apply"] is True
    assert (
        payload["control_channel_contract"]["blocked_runtime_apply_reason"]
        == "harbor_watchdog_repair_once_requires_110_local_or_awoooi_host_runner_control_channel"
    )
    assert payload["control_channel_contract"]["token_collection_allowed"] is False
    assert (
        payload["control_channel_contract"]["runner_registration_token_read_allowed"]
        is False
    )
    assert payload["control_channel_contract"]["raw_authorized_keys_read_allowed"] is False
    assert payload["controlled_apply_policy"]["manual_end_state"] is False
    assert payload["controlled_apply_policy"]["break_glass_required"] is False
    assert payload["controlled_apply_policy"]["current_apply_allowed"] is False
    assert payload["controlled_action_candidates"][1]["id"] == (
        "harbor_watchdog_repair_once"
    )
    assert payload["controlled_action_candidates"][0]["current_status"] == (
        "blocked_waiting_110_ssh_or_awoooi_host_runner_control_channel"
    )
    assert payload["controlled_work_items"][0]["id"] == "110-control-channel-readback"
    assert payload["controlled_work_items"][0]["status"] == (
        "blocked_waiting_ssh_publickey_or_awoooi_host_runner"
    )
    assert payload["controlled_work_items"][3]["id"] == "harbor-watchdog-repair-once"
    assert "harbor_registry_upstream_502" in payload["active_blockers"]
    assert (
        "awoooi_host_runner_or_ssh_control_channel_unavailable"
        in payload["active_blockers"]
    )
    assert "ssh_publickey_diagnosis_required_before_repair" in payload[
        "active_blockers"
    ]
    assert payload["safe_next_step"].startswith(
        "restore_110_ssh_or_awoooi_host_runner_control_channel"
    )
    assert "docker_daemon_restart" in payload["controlled_apply_policy"][
        "forbidden_scope"
    ]
    assert payload["operation_boundaries"]["ssh_used"] is False
    assert payload["operation_boundaries"]["docker_command_performed"] is False
    assert payload["operation_boundaries"]["docker_daemon_restart_performed"] is False
    assert payload["operation_boundaries"]["host_reboot_performed"] is False
    assert payload["operation_boundaries"]["secret_value_collection_allowed"] is False


def test_harbor_registry_preflight_ready_when_registry_v2_ready(tmp_path: Path) -> None:
    payload = load_latest_harbor_registry_controlled_recovery_preflight(
        route_source_path=_route_source(tmp_path),
        watchdog_source_path=_watchdog_source(tmp_path),
        probe=_probe_ready,
    )

    assert payload["status"] == "harbor_registry_ready"
    assert payload["active_blockers"] == []
    assert payload["rollups"]["registry_ready"] is True
    assert payload["control_channel_contract"]["required_before_runtime_apply"] is False
    assert payload["safe_next_step"] == "rerun_gitea_cd_and_verify_deploy_marker"


def test_harbor_registry_preflight_routes_gateway_drift(tmp_path: Path) -> None:
    payload = load_latest_harbor_registry_controlled_recovery_preflight(
        route_source_path=_route_source(tmp_path),
        watchdog_source_path=_watchdog_source(tmp_path),
        probe=_probe_gateway_drift,
    )

    assert payload["status"] == (
        "controlled_recovery_preflight_packaged_public_gateway_route_drift"
    )
    assert payload["source_of_truth_diff"]["status"] == (
        "route_source_present_public_gateway_route_drift"
    )
    assert payload["rollups"]["public_gateway_route_drift_shape"] is True
    assert payload["controlled_action_candidates"][1]["id"] == (
        "registry_public_gateway_rendered_diff"
    )


def test_harbor_registry_preflight_endpoint_returns_payload(
    monkeypatch,
    tmp_path: Path,
) -> None:
    monkeypatch.setattr(
        agents,
        "load_latest_harbor_registry_controlled_recovery_preflight",
        lambda: load_latest_harbor_registry_controlled_recovery_preflight(
            route_source_path=_route_source(tmp_path),
            watchdog_source_path=_watchdog_source(tmp_path),
            probe=_probe_for_upstream_502,
        ),
    )
    app = FastAPI()
    app.include_router(router, prefix="/api/v1")
    client = TestClient(app)

    response = client.get(
        "/api/v1/agents/harbor-registry-controlled-recovery-preflight"
    )

    assert response.status_code == 200
    data = response.json()
    assert data["status"] == (
        "controlled_recovery_preflight_packaged_harbor_registry_upstream_502"
    )
    assert data["rollups"]["controlled_recovery_candidate_packaged"] is True


def _route_source(tmp_path: Path) -> Path:
    path = tmp_path / "188-internal-tools-https.conf.j2"
    path.write_text(
        """
server {
    listen 443 ssl http2;
    server_name harbor.wooo.work;
    location / {
        proxy_pass http://192.168.0.110:5000;
    }
}
server {
    listen 443 ssl http2;
    server_name registry.wooo.work;
    location / {
        proxy_pass http://192.168.0.110:5000;
    }
}
""",
        encoding="utf-8",
    )
    return path


def _watchdog_source(tmp_path: Path) -> Path:
    path = tmp_path / "harbor-watchdog.sh"
    path.write_text(
        """
harbor_is_healthy() {
  curl -s --max-time 5 -o /dev/null -w "%{http_code}" http://127.0.0.1:5000/v2/
}
case "${1:-}" in
  --check) echo AWOOOI_HARBOR_WATCHDOG_CHECK ;;
  --repair-once) echo HARBOR_REPAIR_PERFORMED=1 ;;
esac
docker compose up -d harbor-log
docker compose up -d
""",
        encoding="utf-8",
    )
    return path


def _probe_for_upstream_502(url: str, _timeout_seconds: float) -> dict:
    if "/v2/" in url:
        return {"http_status": 502}
    return {"http_status": 200}


def _probe_ready(url: str, _timeout_seconds: float) -> dict:
    if "/v2/" in url:
        return {"http_status": 401}
    return {"http_status": 200}


def _probe_gateway_drift(url: str, _timeout_seconds: float) -> dict:
    if url == "https://registry.wooo.work/v2/":
        return {"http_status": 502}
    if url == "http://192.168.0.110:5000/v2/":
        return {"http_status": 401}
    return {"http_status": 200}
