"""Linux systemd service backend.

Writes user-level unit files to ``~/.config/systemd/user/`` so no root is
required.  Konstant handles restarts itself, so ``Restart=no`` in the unit.
"""

from __future__ import annotations

import shlex
import subprocess
import sys
import textwrap
from pathlib import Path
from typing import Optional

from konstant.config import ServiceConfig

_UNIT_DIR = Path.home() / ".config" / "systemd" / "user"


def _unit_name(service_name: str) -> str:
    return f"konstant_{service_name}.service"


def _unit_path(service_name: str) -> Path:
    return _UNIT_DIR / _unit_name(service_name)


def _effective_config_path(config: ServiceConfig, config_path: Optional[Path]) -> Path:
    if config_path is not None:
        return config_path.resolve()
    return (config.resolved_cwd / "konstant.toml").resolve()


def _build_unit(config: ServiceConfig, config_path: Optional[Path]) -> str:
    cwd = config.resolved_cwd
    cfg_path = _effective_config_path(config, config_path)
    exec_argv = [
        sys.executable,
        "-m",
        "konstant.cli",
        "start",
        config.name,
        "--fg",
        "--config",
        str(cfg_path),
    ]
    exec_line = " ".join(shlex.quote(arg) for arg in exec_argv)

    return textwrap.dedent(f"""\
        [Unit]
        Description=konstant — {config.name}
        After=network.target

        [Service]
        Type=simple
        ExecStart={exec_line}
        WorkingDirectory={cwd}
        Restart=no
        StandardOutput=journal
        StandardError=journal

        [Install]
        WantedBy=default.target
    """)


def _systemctl(*args: str) -> None:
    subprocess.run(
        ["systemctl", "--user", *args],
        check=True,
        capture_output=True,
    )


def install_service(
    config: ServiceConfig,
    user: Optional[str] = None,
    password: Optional[str] = None,
    config_path: Optional[Path] = None,
) -> None:
    """Write a systemd user unit and enable it."""
    _UNIT_DIR.mkdir(parents=True, exist_ok=True)
    unit = _build_unit(config, config_path)
    _unit_path(config.name).write_text(unit, encoding="utf-8")
    _systemctl("daemon-reload")
    _systemctl("enable", _unit_name(config.name))


def uninstall_service(service_name: str) -> None:
    """Disable and remove a systemd user unit."""
    name = _unit_name(service_name)
    try:
        _systemctl("disable", name)
    except subprocess.CalledProcessError:
        pass  # may already be disabled
    path = _unit_path(service_name)
    if path.exists():
        path.unlink()
    _systemctl("daemon-reload")
