from __future__ import annotations

import json
import os
import stat
import subprocess
from pathlib import Path

MODULE = Path(__file__).resolve().parents[1]
INSTALL = MODULE / "bin" / "install-tailnet-edge"


def test_installer_stages_immutable_edge_and_exact_config(tmp_path):
    env = os.environ.copy()
    env["OVERDECK_SUBROUTER_EDGE_TEST_ROOT"] = str(tmp_path)
    result = subprocess.run(
        [str(INSTALL), "--allow-host", "debian1"], env=env, text=True, capture_output=True, check=True
    )
    assert "Approved hosts: 1" in result.stdout
    runtime = tmp_path / "var/lib/overdeck/subrouter-edge"
    current = runtime / "current"
    assert current.is_symlink()
    release = current.resolve()
    edge = release / "tailnet_edge.py"
    assert edge.is_file() and not edge.is_symlink()
    assert stat.S_IMODE(edge.stat().st_mode) == 0o555
    config = tmp_path / "etc/overdeck/subrouter-edge.json"
    data = json.loads(config.read_text())
    assert data == {
        "allowed_hosts": ["debian1"],
        "listen_port": 31416,
        "schema": "overdeck-subrouter-tailnet-edge/v1",
        "upstream_host": "127.0.0.1",
        "upstream_port": 31415,
    }
    assert stat.S_IMODE(config.stat().st_mode) == 0o640
    unit = (tmp_path / "etc/systemd/system/overdeck-subrouter-edge.service").read_text()
    assert "User=overdeck-subrouter" in unit
    assert "ProtectHome=yes" in unit
    assert "ProtectSystem=strict" in unit
    assert "RestrictAddressFamilies=AF_INET AF_UNIX" in unit
    assert "0.0.0.0" not in unit


def test_installer_rejects_missing_or_unsafe_allow_host(tmp_path):
    env = os.environ.copy(); env["OVERDECK_SUBROUTER_EDGE_TEST_ROOT"] = str(tmp_path)
    for argv in ([], ["--allow-host", "../debian1"]):
        result = subprocess.run([str(INSTALL), *argv], env=env, text=True, capture_output=True)
        assert result.returncode != 0


def test_installer_restarts_edge_after_config_rewrite():
    source = INSTALL.read_text(encoding="utf-8")
    assert "systemctl enable overdeck-subrouter-edge.service" in source
    assert "systemctl restart overdeck-subrouter-edge.service" in source
    assert "systemctl enable --now overdeck-subrouter-edge.service" not in source
