#!/usr/bin/env python3
from __future__ import annotations

import os
import subprocess
from pathlib import Path


ROOT = Path(__file__).resolve().parents[2]
INSTALLER = ROOT / "ops/runner/install-awoooi-non110-runner-user-service.sh"


def _write_fake_bin(path: Path, name: str, body: str) -> None:
    target = path / name
    target.write_text(body, encoding="utf-8")
    target.chmod(0o755)


def _runner_env(tmp_path: Path) -> dict[str, str]:
    fake_bin = tmp_path / "bin"
    fake_bin.mkdir()
    systemctl_log = tmp_path / "systemctl.log"
    _write_fake_bin(
        fake_bin,
        "systemctl",
        f"""#!/usr/bin/env bash
set -euo pipefail
if [ "${{1:-}}" = "--user" ]; then shift; fi
cmd="${{1:-}}"
shift || true
printf '%s %s\\n' "$cmd" "$*" >> "{systemctl_log}"
case "$cmd" in
  daemon-reload|enable|start|stop|disable|reset-failed)
    exit 0
    ;;
  show)
    printf 'LoadState=loaded\\nActiveState=inactive\\nUnitFileState=disabled\\nMainPID=0\\n'
    exit 0
    ;;
esac
exit 0
""",
    )
    _write_fake_bin(
        fake_bin,
        "loginctl",
        """#!/usr/bin/env bash
printf 'Linger=yes\\n'
""",
    )
    runner_home = tmp_path / "home"
    runner_dir = runner_home / "act-runner-awoooi"
    unit_dir = runner_home / ".config/systemd/user"
    runner_dir.mkdir(parents=True)
    unit_dir.mkdir(parents=True)
    (runner_dir / "act_runner").write_text("#!/usr/bin/env bash\n", encoding="utf-8")
    (runner_dir / "act_runner").chmod(0o755)
    (runner_dir / "config.yaml").write_text(
        "runner:\n  capacity: 1\n  labels: []\n",
        encoding="utf-8",
    )
    (runner_dir / ".runner").write_text(
        "secret-token-like-content-not-printed\n",
        encoding="utf-8",
    )
    return {
        **os.environ,
        "PATH": f"{fake_bin}:{os.environ['PATH']}",
        "RUNNER_HOME": str(runner_home),
        "RUNNER_DIR": str(runner_dir),
        "USER_SERVICE_DIR": str(unit_dir),
        "SYSTEMCTL_LOG": str(systemctl_log),
    }


def _run_installer(tmp_path: Path, *args: str, enable: bool = False) -> subprocess.CompletedProcess[str]:
    env = _runner_env(tmp_path)
    if enable:
        env["AWOOOI_NON110_ENABLE"] = "1"
    return subprocess.run(
        ["bash", str(INSTALLER), *args],
        check=False,
        env=env,
        text=True,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
    )


def test_apply_with_existing_registration_does_not_start_runner(tmp_path: Path) -> None:
    result = _run_installer(tmp_path, "--apply")
    assert result.returncode == 0, result.stdout + result.stderr
    assert "AUTOSTART_PATH_ENABLE_PERFORMED=0 reason=registration_ready_requires_explicit_enable" in result.stdout
    assert "SERVICE_START_PERFORMED=0" in result.stdout
    assert "secret-token-like-content" not in result.stdout

    unit_dir = tmp_path / "home/.config/systemd/user"
    pressure_guard = tmp_path / "home/.local/bin/awoooi-wait-host-web-build-pressure.sh"
    service = unit_dir / "awoooi-non110-runner.service"
    rollback = unit_dir / "awoooi-non110-runner-rollback.service"
    autostart = unit_dir / "awoooi-non110-runner-autostart.service"
    keepalive_service = unit_dir / "awoooi-non110-runner-keepalive.service"
    keepalive_timer = unit_dir / "awoooi-non110-runner-keepalive.timer"
    service_text = service.read_text(encoding="utf-8")
    assert f"ExecStartPre=/usr/bin/test -x {pressure_guard}" in service_text
    assert "HOST_WEB_BUILD_PRESSURE_ATTEMPTS=1" in service_text
    assert "HOST_WEB_BUILD_PRESSURE_SLEEP_SECONDS=0" in service_text
    rollback_text = rollback.read_text(encoding="utf-8")
    assert "stop awoooi-non110-runner-keepalive.timer" in rollback_text
    assert "disable awoooi-non110-runner-keepalive.timer" in rollback_text
    assert "stop awoooi-non110-runner-keepalive.service" in rollback_text
    assert "rm -f" in rollback_text
    assert "ConditionPathExists=!" in autostart.read_text(encoding="utf-8")
    assert "enable --now awoooi-non110-runner-keepalive.timer" in autostart.read_text(
        encoding="utf-8"
    )
    keepalive_service_text = keepalive_service.read_text(encoding="utf-8")
    assert f"ExecStart=/usr/bin/test -x {pressure_guard}" in keepalive_service_text
    assert "HOST_WEB_BUILD_PRESSURE_ATTEMPTS=1" in keepalive_service_text
    assert "HOST_WEB_BUILD_PRESSURE_SLEEP_SECONDS=0" in keepalive_service_text
    assert "ExecStart=/usr/bin/systemctl --user daemon-reload" in keepalive_service_text
    assert (
        "ExecStart=-/usr/bin/systemctl --user reset-failed awoooi-non110-runner.service"
        in keepalive_service_text
    )
    assert "OnUnitInactiveSec=15s" in keepalive_timer.read_text(encoding="utf-8")
    assert f"pressure_guard={pressure_guard}" in result.stdout

    log = (tmp_path / "systemctl.log").read_text(encoding="utf-8")
    assert "enable --now awoooi-non110-runner-autostart.path" not in log
    assert "start awoooi-non110-runner.service" not in log


def test_enable_starts_runner_and_keepalive_without_printing_registration(
    tmp_path: Path,
) -> None:
    result = _run_installer(tmp_path, "--enable", enable=True)
    assert result.returncode == 0, result.stdout + result.stderr
    assert "SERVICE_ENABLE_PERFORMED=1" in result.stdout
    assert "SERVICE_START_PERFORMED=1" in result.stdout
    assert "KEEPALIVE_TIMER_ENABLE_PERFORMED=1" in result.stdout
    assert "secret-token-like-content" not in result.stdout

    runner_dir = tmp_path / "home/act-runner-awoooi"
    assert (runner_dir / ".awoooi-non110-runner-enabled").exists()
    pressure_guard = tmp_path / "home/.local/bin/awoooi-wait-host-web-build-pressure.sh"
    service_text = (
        tmp_path / "home/.config/systemd/user/awoooi-non110-runner.service"
    ).read_text(encoding="utf-8")
    assert f"ExecStartPre=/usr/bin/test -x {pressure_guard}" in service_text
    assert "HOST_WEB_BUILD_PRESSURE_ATTEMPTS=1" in service_text
    log = (tmp_path / "systemctl.log").read_text(encoding="utf-8")
    assert "enable --now awoooi-non110-runner-keepalive.timer" in log
    assert "enable awoooi-non110-runner.service" in log
    assert "start awoooi-non110-runner.service" in log
