"""Contract-surface playbook (SPEC §2.4, §6.5).

An ``--apply`` that touches a cross-family contract surface (an org secret) runs the
secret-change playbook itself: a re-plan scope audit → the event-class reminder →
the sooth canary. The canary is injected here and asserted CALLED; a non-contract
apply (hosts only) never triggers it.
"""

from __future__ import annotations

from mgf.secrets.hosts import HostStat
from mgf.secrets.registry import load
from mgf.secrets.sync import CanaryResult, Reconciler
from tests._fakes import FakeHost, FakeWoodpecker

ORG = """\
[org_secret_a]
family = "mgf"
kind = "api-token"
purpose = "a shared org secret (surface-1)"
consumers = ["clone"]
recovery = "re-mint"
state = "active"
policy = { allowed_repos = "*", blast_radius = "low" }
rotation = { class = "token", staged = true }
verify = { probe = "forge-auth" }
surfaces = [ { type = "woodpecker-org-secret", events = ["push", "tag"] } ]
"""

HOST = """\
[server_env]
family = "mgf"
kind = "password"
purpose = "a root-600 server env file (not a contract surface)"
consumers = ["server"]
recovery = "reset"
state = "active"
policy = { allowed_repos = "*", blast_radius = "low" }
rotation = { class = "password", staged = true }
verify = { probe = "server-env-present" }
surfaces = [ { type = "host-file", host = "h1", path = "/opt/x/.env", mode = "0600", owner = "root" } ]
"""


def _reg(tmp_path, text):
    p = tmp_path / "SECRETS.toml"
    p.write_text(text, encoding="utf-8")
    return load([p])


class _RecordingCanary:
    def __init__(self, ok=True):
        self.calls = 0
        self._ok = ok

    def __call__(self) -> CanaryResult:
        self.calls += 1
        return CanaryResult(self._ok, "sooth canary (mock) green" if self._ok else "sooth RED")


def test_contract_surface_apply_runs_audit_and_canary(tmp_path) -> None:
    reg = _reg(tmp_path, ORG)
    wp = FakeWoodpecker(org_secrets={"org_secret_a": {"push"}}, repos=[])  # scope drift
    canary = _RecordingCanary(ok=True)
    rec = Reconciler(
        reg, fed_root=tmp_path, value_provider=lambda _id: b"v", woodpecker=wp, canary=canary
    )
    report = rec.apply(["woodpecker"])
    assert report.playbook is not None
    pb = report.playbook
    assert pb.triggered
    assert pb.audit_clean  # re-plan after the fix is empty
    assert pb.canary_ran and pb.canary_ok is True
    assert canary.calls == 1  # the canary was actually invoked
    assert "event class" in pb.reminder


def test_skip_canary_still_audits_but_does_not_call_canary(tmp_path) -> None:
    reg = _reg(tmp_path, ORG)
    wp = FakeWoodpecker(org_secrets={"org_secret_a": {"push"}}, repos=[])
    canary = _RecordingCanary()
    rec = Reconciler(
        reg, fed_root=tmp_path, value_provider=lambda _id: b"v", woodpecker=wp, canary=canary
    )
    report = rec.apply(["woodpecker"], skip_canary=True)
    assert report.playbook is not None and report.playbook.triggered
    assert report.playbook.audit_clean
    assert not report.playbook.canary_ran
    assert canary.calls == 0


def test_non_contract_surface_apply_does_not_trigger_playbook(tmp_path) -> None:
    reg = _reg(tmp_path, HOST)
    hosts = FakeHost({("h1", "/opt/x/.env"): HostStat("present", mode="644", owner="ubuntu")})
    canary = _RecordingCanary()
    rec = Reconciler(reg, fed_root=tmp_path, hosts=hosts, canary=canary)
    report = rec.apply(["hosts"])
    assert report.playbook is None  # a host chmod is not a cross-family contract surface
    assert canary.calls == 0
