"""What the auto-update installer writes into the systemd user unit.

The unit is generated by an *unquoted* heredoc, so every backtick and ``$`` in it
is live shell syntax. The launcher path has to interpolate — that is the whole
point of the heredoc — while the prose around it must not, and the two are one
character apart. A comment that silently executes is the mild failure; the loud
one is an ``ExecStart`` that no longer names a file, which is exactly what a
timer firing at 6AM into a moved launcher looks like: nothing, every day, until
someone reads the journal.
"""

from __future__ import annotations

import os
import subprocess
from pathlib import Path

import pytest

INSTALL = (
    Path(__file__).resolve().parents[1] / "install" / "install-autoupdate.sh"
)


@pytest.fixture
def written(tmp_path: Path) -> str:
    """Run the installer against a throwaway HOME and return the unit it wrote."""
    # systemctl is stubbed out: the script enables the timer, which would reach the
    # real user manager (XDG_RUNTIME_DIR, not HOME) and fail under `set -e` because
    # the unit it names lives in this tmp_path instead of the real search path.
    bin_dir = tmp_path / "bin"
    bin_dir.mkdir()
    stub = bin_dir / "systemctl"
    stub.write_text("#!/bin/sh\nexit 0\n")
    stub.chmod(0o755)

    env = {
        **os.environ,
        "HOME": str(tmp_path),
        "XDG_CONFIG_HOME": str(tmp_path / ".config"),
        "PATH": f"{bin_dir}{os.pathsep}{os.environ['PATH']}",
    }
    proc = subprocess.run(
        ["bash", str(INSTALL)], env=env, capture_output=True, text=True
    )
    assert proc.returncode == 0, proc.stderr
    # A heredoc that runs what it meant to quote says so on stderr and carries on.
    assert "command not found" not in proc.stderr, proc.stderr

    unit = tmp_path / ".config" / "systemd" / "user" / "diplomat-update.service"
    assert unit.exists(), sorted(p.name for p in (tmp_path / ".config").rglob("*"))
    return unit.read_text()


def test_execstart_names_the_launcher_that_exists(written: str) -> None:
    """The path is interpolated, absolute, and points at a runnable launcher."""
    line = next(
        ln for ln in written.splitlines() if ln.startswith("ExecStart=")
    )
    launcher = Path(line.split("/bin/bash ", 1)[1])
    assert launcher.is_absolute()
    assert launcher == INSTALL.parent.parent / "diplomat"
    assert launcher.exists(), f"unit points at a launcher that is not there: {launcher}"
    assert os.access(launcher, os.X_OK)


def test_prose_is_not_executed_on_its_way_into_the_unit(written: str) -> None:
    """Backticked words in the comments survive as text, not as command output."""
    assert "the daily timer's `start` a no-op" in written


def test_the_relaunched_tray_outlives_the_oneshot(written: str) -> None:
    """Without this the update swap kills the tray it just launched."""
    directives = [ln for ln in written.splitlines() if not ln.startswith("#")]
    assert "KillMode=process" in directives
    assert "Environment=DIPLOMAT_SELF_UPDATE=1" in directives
    # Only ever discussed in the comments: setting it strands the oneshot in
    # 'active (exited)', where the daily start is a no-op.
    assert not any(ln.startswith("RemainAfterExit") for ln in directives)
