from __future__ import annotations

import json

import pytest

from src.services.runtime_surface_inventory import load_latest_runtime_surface_inventory


def test_load_latest_runtime_surface_inventory_reads_newest_file(tmp_path):
    older = _snapshot(generated_at="2026-06-04T00:00:00+08:00", completion=40)
    newer = _snapshot(generated_at="2026-06-05T00:00:00+08:00", completion=100)
    (tmp_path / "runtime_surface_inventory_2026-06-04.json").write_text(
        json.dumps(older),
        encoding="utf-8",
    )
    (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text(
        json.dumps(newer),
        encoding="utf-8",
    )

    loaded = load_latest_runtime_surface_inventory(tmp_path)

    assert loaded["generated_at"] == "2026-06-05T00:00:00+08:00"
    assert loaded["program_status"]["overall_completion_percent"] == 100
    assert loaded["rollups"]["total_surfaces"] == 3
    assert loaded["operation_boundaries"]["kubectl_allowed"] is False


def test_runtime_surface_inventory_requires_read_only_mode(tmp_path):
    snapshot = _snapshot()
    snapshot["program_status"]["read_only_mode"] = False
    (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="read_only_mode"):
        load_latest_runtime_surface_inventory(tmp_path)


def test_runtime_surface_inventory_requires_blocked_operations(tmp_path):
    snapshot = _snapshot()
    snapshot["operation_boundaries"]["kubectl_allowed"] = True
    (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="operation boundaries"):
        load_latest_runtime_surface_inventory(tmp_path)


def test_runtime_surface_inventory_requires_rollup_consistency(tmp_path):
    snapshot = _snapshot()
    snapshot["rollups"]["by_kind"]["deployment"] = 99
    (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="by_kind"):
        load_latest_runtime_surface_inventory(tmp_path)


def test_runtime_surface_inventory_requires_secret_redaction(tmp_path):
    snapshot = _snapshot()
    snapshot["runtime_surfaces"][2]["secret_exposure"] = "none"
    (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="secret surfaces"):
        load_latest_runtime_surface_inventory(tmp_path)


def test_runtime_surface_inventory_requires_operator_denials(tmp_path):
    snapshot = _snapshot()
    snapshot["operator_contract"]["must_not_interpret_as"] = ["runtime 執行授權"]
    (tmp_path / "runtime_surface_inventory_2026-06-05.json").write_text(
        json.dumps(snapshot),
        encoding="utf-8",
    )

    with pytest.raises(ValueError, match="must_not_interpret_as"):
        load_latest_runtime_surface_inventory(tmp_path)


def test_runtime_surface_inventory_fails_when_missing(tmp_path):
    with pytest.raises(FileNotFoundError):
        load_latest_runtime_surface_inventory(tmp_path)


def _snapshot(
    *,
    generated_at: str = "2026-06-05T00:00:00+08:00",
    completion: int = 100,
) -> dict:
    return {
        "schema_version": "runtime_surface_inventory_v1",
        "generated_at": generated_at,
        "program_status": {
            "overall_completion_percent": completion,
            "current_priority": "P1",
            "current_task_id": "P1-001",
            "next_task_id": "P1-002",
            "read_only_mode": True,
        },
        "source_refs": ["k8s/awoooi-prod/"],
        "rollups": {
            "total_surfaces": 3,
            "by_kind": {"deployment": 1, "ingress": 1, "secret": 1},
            "by_status": {"manifest_mapped": 1, "action_required": 2},
            "by_evidence_level": {
                "committed_manifest": 1,
                "missing_manifest": 1,
                "live_check_required": 1,
            },
            "action_required_surface_ids": ["external_nginx_gateway_route", "awoooi_secrets"],
            "secret_surface_ids": ["awoooi_secrets"],
            "live_check_missing_surface_ids": ["external_nginx_gateway_route", "awoooi_secrets"],
            "total_source_components": 1,
            "source_components_with_runtime_binding": 1,
        },
        "runtime_surfaces": [
            _surface(
                "awoooi_api_deployment",
                "deployment",
                "manifest_mapped",
                "committed_manifest",
                "none",
                "not_run",
            ),
            _surface(
                "external_nginx_gateway_route",
                "ingress",
                "action_required",
                "missing_manifest",
                "none",
                "required",
            ),
            _surface(
                "awoooi_secrets",
                "secret",
                "action_required",
                "live_check_required",
                "template_only",
                "required",
            ),
        ],
        "source_runtime_components": [
            {
                "component_id": "api_fastapi_app",
                "display_name": "FastAPI app",
                "source_ref": "apps/api/src/main.py",
                "component_kind": "api_process",
                "runtime_binding": "Deployment/awoooi-api",
                "status": "bound",
                "next_action": "只讀確認。",
            }
        ],
        "evidence_gaps": [
            {
                "gap_id": "external_gateway_manifest_gap",
                "severity": "high",
                "status": "action_required",
                "summary": "缺外部 gateway manifest。",
                "evidence_refs": ["k8s/awoooi-prod/"],
                "next_action": "只讀補證據。",
            }
        ],
        "operator_contract": {
            "display_mode": "read_only_runtime_surface",
            "must_not_interpret_as": [
                "runtime 執行授權",
                "rollout / restart / scale / delete 批准",
                "Secret 已驗證或可讀取",
                "Ingress / DNS 可修改",
            ],
            "secret_display_policy": "只顯示 redacted metadata。",
        },
        "operation_boundaries": {
            "read_only_api_allowed": True,
            "live_k8s_query_allowed": False,
            "kubectl_allowed": False,
            "rollout_allowed": False,
            "restart_allowed": False,
            "scale_allowed": False,
            "delete_allowed": False,
            "secret_read_allowed": False,
            "secret_plaintext_allowed": False,
            "active_scan_allowed": False,
            "production_route_change_allowed": False,
        },
        "approval_boundaries": {
            "sdk_installation_allowed": False,
            "paid_api_call_allowed": False,
            "shadow_or_canary_allowed": False,
            "production_routing_allowed": False,
            "destructive_operation_allowed": False,
        },
    }


def _surface(
    surface_id: str,
    kind: str,
    status: str,
    evidence_level: str,
    secret_exposure: str,
    live_check_status: str,
) -> dict:
    return {
        "surface_id": surface_id,
        "display_name": surface_id,
        "kind": kind,
        "manifest_ref": "k8s/awoooi-prod/example.yaml",
        "status": status,
        "risk_level": "high",
        "evidence_level": evidence_level,
        "runtime_binding": "example runtime binding",
        "health_contract": "example health contract",
        "secret_exposure": secret_exposure,
        "live_check_status": live_check_status,
        "evidence_refs": ["k8s/awoooi-prod/example.yaml"],
        "next_action": "只讀確認。",
    }
