"""TC-12: compose invariant — orchestrator-watchdog is a separate service.

It declares its own build (watchdog/Dockerfile), restart policy, mem_limit, and
mounts docker.sock read-only (:ro). Parses the real docker-compose.yml.
"""
import pathlib

import yaml

REPO_ROOT = pathlib.Path(__file__).resolve().parents[2]


def _compose():
    with open(REPO_ROOT / "docker-compose.yml") as f:
        return yaml.safe_load(f)


def test_watchdog_service_declared():
    svc = _compose()["services"]
    assert "orchestrator-watchdog" in svc


def test_watchdog_builds_from_watchdog_dockerfile():
    wd = _compose()["services"]["orchestrator-watchdog"]
    build = wd["build"]
    assert isinstance(build, dict)
    assert build["dockerfile"] == "watchdog/Dockerfile"
    assert build["context"] == "."


def test_watchdog_has_restart_and_mem_limit():
    wd = _compose()["services"]["orchestrator-watchdog"]
    assert wd["restart"] == "unless-stopped"
    assert wd["mem_limit"] == "128m"  # thin stack, not Grafana/Prometheus


def test_docker_sock_mounted_read_only():
    wd = _compose()["services"]["orchestrator-watchdog"]
    sock = [v for v in wd["volumes"] if "docker.sock" in v]
    assert sock, "docker.sock must be mounted"
    assert all(v.endswith(":ro") for v in sock), "docker.sock must be :ro"


def test_host_paths_mounted_read_only():
    wd = _compose()["services"]["orchestrator-watchdog"]
    # Every bind mount the watchdog uses is read-only (it only reads).
    for v in wd["volumes"]:
        assert v.endswith(":ro"), f"watchdog mount must be :ro: {v}"


def test_watchdog_shares_host_pid_namespace():
    # ORCH-111 (adr-0041 D6): the sidecar shares the host PID-namespace so its
    # /proc reflects the host (proc_blocking collector). `pid: host` is NOT a
    # volume, so the read-only-mounts invariant above is unaffected.
    wd = _compose()["services"]["orchestrator-watchdog"]
    assert wd.get("pid") == "host", "orchestrator-watchdog must declare `pid: host`"
    # The privilege stays on the OBSERVER only — prod orchestrator must NOT get it.
    orch = _compose()["services"]["orchestrator"]
    assert "pid" not in orch, "the prod orchestrator service must not share the host PID-namespace"


def test_env_file_is_optional():
    # A missing .env.watchdog must not break `docker compose up` (self-hosting).
    wd = _compose()["services"]["orchestrator-watchdog"]
    env_file = wd["env_file"]
    assert isinstance(env_file, list)
    assert env_file[0]["required"] is False


def test_watchdog_dockerfile_exists_and_is_stdlib_only():
    df = REPO_ROOT / "watchdog" / "Dockerfile"
    assert df.exists()
    text = df.read_text()
    # No pip install of third-party deps (stdlib-only, D1).
    assert "pip install" not in text
    assert "COPY requirements" not in text
    assert "requirements.txt" not in text
