"""Registry schema — completeness fails closed (SPEC §7.1)."""

from __future__ import annotations

import pytest

from mgf.secrets.registry import RegistryError
from tests._fakes import write_registry

# A structurally-complete single entry we mutate to produce each failure case.
BASE = """\
[some_secret]
family = "mgf"
kind = "api-token"
purpose = "a token"
consumers = ["x"]
recovery = "re-mint"
state = "active"
policy = { allowed_repos = "*", blast_radius = "low" }
rotation = { class = "token", staged = true }
verify = { probe = "auth" }
surfaces = [ { type = "woodpecker-org-secret", events = ["push"] } ]
"""


def test_golden_minimal_and_maximal_load(tmp_path, golden_minimal, golden_maximal) -> None:
    reg = write_registry(tmp_path, golden_minimal, golden_maximal)
    assert len(reg) == 2
    assert reg.get("codeberg_ssh_clone_key").kind == "ssh-deploy-key"
    devpi = reg.get("devpi_password")
    assert devpi.has_surface("store")
    assert devpi.rotation["rotate_by"] == "2026-12-31"


@pytest.mark.parametrize(
    "field",
    [
        "family",
        "kind",
        "purpose",
        "consumers",
        "recovery",
        "state",
        "policy",
        "rotation",
        "verify",
        "surfaces",
    ],
)
def test_missing_required_field_fails_closed(tmp_path, field) -> None:
    lines = [ln for ln in BASE.splitlines() if not ln.startswith(f"{field} ")]
    with pytest.raises(RegistryError) as exc:
        write_registry(tmp_path, "\n".join(lines) + "\n")
    assert any(field in p for p in exc.value.problems)


def test_unknown_kind_fails_closed(tmp_path) -> None:
    with pytest.raises(RegistryError, match="unknown kind"):
        write_registry(tmp_path, BASE.replace('kind = "api-token"', 'kind = "quantum-key"'))


def test_unknown_state_fails_closed(tmp_path) -> None:
    with pytest.raises(RegistryError, match="unknown state"):
        write_registry(tmp_path, BASE.replace('state = "active"', 'state = "armed"'))


def test_unknown_family_fails_closed(tmp_path) -> None:
    with pytest.raises(RegistryError, match="unknown family"):
        write_registry(tmp_path, BASE.replace('family = "mgf"', 'family = "acme"'))


def test_unknown_surface_type_fails_closed(tmp_path) -> None:
    bad = BASE.replace('type = "woodpecker-org-secret"', 'type = "kubernetes-secret"')
    with pytest.raises(RegistryError, match="unknown type"):
        write_registry(tmp_path, bad)


def test_bad_event_fails_closed(tmp_path) -> None:
    with pytest.raises(RegistryError, match="unknown event"):
        write_registry(tmp_path, BASE.replace('events = ["push"]', 'events = ["shove"]'))


def test_surface_missing_required_key_fails_closed(tmp_path) -> None:
    bad = BASE.replace(
        'surfaces = [ { type = "woodpecker-org-secret", events = ["push"] } ]',
        'surfaces = [ { type = "host-file", host = "h", path = "/x" } ]',  # no mode/owner
    )
    with pytest.raises(RegistryError, match="missing required key"):
        write_registry(tmp_path, bad)


def test_bad_mode_fails_closed(tmp_path) -> None:
    bad = BASE.replace(
        'surfaces = [ { type = "woodpecker-org-secret", events = ["push"] } ]',
        'surfaces = [ { type = "local-file", repo = "mgf", path = "t.txt", mode = "rwx" } ]',
    )
    with pytest.raises(RegistryError, match="octal"):
        write_registry(tmp_path, bad)


def test_duplicate_id_across_families_fails_closed(tmp_path) -> None:
    a = BASE
    b = BASE.replace('family = "mgf"', 'family = "sooth"')
    with pytest.raises(RegistryError, match="duplicate id"):
        write_registry(tmp_path, a, b)


def test_held_entry_armed_fails_closed(tmp_path) -> None:
    held = BASE.replace('state = "active"', 'state = "held"').replace(
        'events = ["push"]', 'events = ["deployment"], armed = true'
    )
    with pytest.raises(RegistryError, match="armed"):
        write_registry(tmp_path, held)


def test_held_entry_unarmed_is_allowed(tmp_path) -> None:
    held = BASE.replace('state = "active"', 'state = "held"').replace(
        'events = ["push"]', 'events = ["deployment"]'
    )
    reg = write_registry(tmp_path, held)
    assert reg.get("some_secret").state == "held"


def test_empty_surfaces_fails_closed(tmp_path) -> None:
    with pytest.raises(RegistryError, match="non-empty"):
        write_registry(
            tmp_path,
            BASE.replace(
                'surfaces = [ { type = "woodpecker-org-secret", events = ["push"] } ]',
                "surfaces = []",
            ),
        )
