"""
Windows autostart — the analog of macOS ``launchagent.py``.

"Start at Login" is implemented with the per-user **Run** registry key
(``HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run``), which launches the
tray app at sign-in without admin rights. This module mirrors the launchagent API
(``install`` / ``uninstall`` / ``is_installed`` / ``run_at_login_enabled`` /
``keep_alive_enabled`` / ``set_keep_alive`` / ``stop`` / ``restart``) so the tray
UI can be written platform-agnostically.

> Crash-restart parity: macOS gets KeepAlive from launchd (it relaunches the whole
> process). On Windows there is no equivalent for a Run-key launch, so
> ``keep_alive`` is persisted as a *preference* here and honoured by the tray's
> in-process supervisor, which respawns the asyncio bridge thread if it dies. For
> true OS-level restart-on-crash + headless service mode, a follow-up should add a
> Windows **Scheduled Task** ("At log on", "Restart on failure") or an NSSM service
> — see installer/windows/README.md.
"""
from __future__ import annotations

import logging
import os
import subprocess
import sys
from pathlib import Path

log = logging.getLogger(__name__)

_RUN_KEY = r"Software\Microsoft\Windows\CurrentVersion\Run"
_VALUE_NAME = "LungoBridge"

# %LOCALAPPDATA%\Beacon — logs + the keep-alive preference flag.
_APP_DIR = Path(os.environ.get("LOCALAPPDATA", Path.home() / "AppData" / "Local")) / "Beacon"
_LOG_DIR = _APP_DIR / "Logs"
_KEEPALIVE_FLAG = _APP_DIR / "keepalive.on"


def _launch_command() -> str:
    """Command the Run key executes. Prefer an installed/frozen exe; fall back to
    ``pythonw -m terminull_platform.windows.main`` (no console window) for dev."""
    if getattr(sys, "frozen", False):
        return f'"{sys.executable}"'
    pyw = Path(sys.executable).with_name("pythonw.exe")
    python = f'"{pyw}"' if pyw.exists() else f'"{sys.executable}"'
    return f'{python} -m terminull_platform.windows.main'


# ── Start at Login (Run key) ─────────────────────────────────────────────────

def _winreg():
    import winreg  # Windows-only stdlib; imported lazily so this module loads anywhere
    return winreg


def is_installed() -> bool:
    try:
        winreg = _winreg()
        with winreg.OpenKey(winreg.HKEY_CURRENT_USER, _RUN_KEY) as key:
            winreg.QueryValueEx(key, _VALUE_NAME)
            return True
    except FileNotFoundError:
        return False
    except Exception:
        return False


def install() -> None:
    if is_installed():
        log.debug("Autostart already installed")
        return
    winreg = _winreg()
    with winreg.CreateKey(winreg.HKEY_CURRENT_USER, _RUN_KEY) as key:
        winreg.SetValueEx(key, _VALUE_NAME, 0, winreg.REG_SZ, _launch_command())
    log.info("Autostart installed — bridge starts on sign-in")


def uninstall() -> None:
    if not is_installed():
        return
    winreg = _winreg()
    try:
        with winreg.OpenKey(winreg.HKEY_CURRENT_USER, _RUN_KEY, 0, winreg.KEY_SET_VALUE) as key:
            winreg.DeleteValue(key, _VALUE_NAME)
        log.info("Autostart removed")
    except FileNotFoundError:
        pass


def run_at_login_enabled() -> bool:
    return is_installed()


# ── Auto-restart preference (honoured by the tray supervisor) ────────────────

def keep_alive_enabled() -> bool:
    return _KEEPALIVE_FLAG.exists()


def set_keep_alive(value: bool) -> None:
    _APP_DIR.mkdir(parents=True, exist_ok=True)
    if value:
        _KEEPALIVE_FLAG.touch()
    else:
        _KEEPALIVE_FLAG.unlink(missing_ok=True)
    log.info("Auto-restart preference set to %s", value)


# ── Lifecycle ────────────────────────────────────────────────────────────────

def stop() -> None:
    """No launchd-style job to boot out; the tray Quit handler just exits the
    process. Kept for API parity with macOS."""
    log.debug("autostart.stop() — no-op on Windows (process exits on Quit)")


def restart() -> None:
    """Relaunch the tray app, then exit the current process."""
    subprocess.Popen(_launch_command(), shell=True)
    os._exit(0)


# ── Logs ─────────────────────────────────────────────────────────────────────

def log_path() -> Path:
    _LOG_DIR.mkdir(parents=True, exist_ok=True)
    return _LOG_DIR / "bridge.log"


def err_path() -> Path:
    _LOG_DIR.mkdir(parents=True, exist_ok=True)
    return _LOG_DIR / "bridge.err"
