"""In-process fake surfaces + fixtures builders — no network, no real credentials.

These implement exactly the read-only API subset the doctor/probes consume, so
the incident-replay and redaction tests run whole flows offline (SPEC §7.3).
"""

from __future__ import annotations

from pathlib import Path

from mgf.secrets.forge import DeployKey
from mgf.secrets.hosts import HostStat
from mgf.secrets.registry import Registry, load
from mgf.secrets.woodpecker import RepoInfo


class FakeWoodpecker:
    """In-proc Woodpecker: org secrets, activated repos, per-repo secrets."""

    def __init__(
        self,
        *,
        org_secrets: dict[str, set[str]] | None = None,
        repos: list[tuple[int, str]] | None = None,
        repo_secrets: dict[int, dict[str, set[str]]] | None = None,
    ) -> None:
        self._org = {k: frozenset(v) for k, v in (org_secrets or {}).items()}
        self._repos = repos or []
        self._repo_secrets = {
            rid: {k: frozenset(v) for k, v in secs.items()}
            for rid, secs in (repo_secrets or {}).items()
        }

    def org_id(self) -> int:
        return 1

    def org_secrets(self) -> dict[str, frozenset[str]]:
        return dict(self._org)

    def repo_secrets(self, repo_id: int) -> dict[str, frozenset[str]]:
        return dict(self._repo_secrets.get(repo_id, {}))

    def activated_repos(self) -> list[RepoInfo]:
        return [
            RepoInfo(id=rid, name=name, full_name=f"magogi-admin/{name}", active=True)
            for rid, name in self._repos
        ]


class FakeForge:
    def __init__(self, keys_by_repo: dict[str, list[DeployKey]] | None = None) -> None:
        self._keys = keys_by_repo or {}

    def repo_deploy_keys(self, repo: str) -> list[DeployKey]:
        return list(self._keys.get(repo, []))


class FakeHost:
    def __init__(self, stats: dict[tuple[str, str], HostStat] | None = None) -> None:
        self._stats = stats or {}

    def stat(self, host: str, path: str) -> HostStat:
        return self._stats.get((host, path), HostStat("missing"))


def write_registry(tmp_path: Path, *toml_texts: str) -> Registry:
    """Write one SECRETS.toml per text and load them as a single registry."""
    paths = []
    for i, text in enumerate(toml_texts):
        p = tmp_path / f"SECRETS_{i}.toml"
        p.write_text(text, encoding="utf-8")
        paths.append(p)
    return load(paths)


def write_pipeline(fed_root: Path, repo: str, yaml_text: str) -> None:
    d = fed_root / repo
    d.mkdir(parents=True, exist_ok=True)
    (d / ".woodpecker.yml").write_text(yaml_text, encoding="utf-8")
