"""Locale + Tastatur-Layout via localectl (systemd).

UI-frei — von TUI und GTK-Frontend nutzbar. Lese-Funktionen laufen
unprivilegiert; die Schreib-Aktionen liefern nur das ARGV (wie bei
core.bootloader), das der Aufrufer privilegiert über den Helper ausführt.
core eskaliert NIE selbst.
"""
from __future__ import annotations

import subprocess
from dataclasses import dataclass


def _run(args: list[str], timeout: int = 5) -> str:
    try:
        r = subprocess.run(
            args, capture_output=True, text=True, check=False, timeout=timeout,
        )
        return r.stdout if r.returncode == 0 else ""
    except (FileNotFoundError, subprocess.TimeoutExpired):
        return ""


@dataclass
class LocaleStatus:
    locale: str          # LANG-Wert, z.B. "de_DE.UTF-8"
    vc_keymap: str       # Konsolen-Keymap, z.B. "de-latin1"
    x11_layout: str      # XKB-Layout, z.B. "de"
    x11_variant: str     # XKB-Variante, z.B. "nodeadkeys"


def status() -> LocaleStatus:
    """Parst `localectl status`."""
    out = _run(["localectl", "status"])
    fields = {"locale": "", "vc_keymap": "", "x11_layout": "", "x11_variant": ""}
    for line in out.splitlines():
        line = line.strip()
        if line.startswith("System Locale:"):
            val = line.split(":", 1)[1].strip()
            # "LANG=de_DE.UTF-8" (evtl. mehrere, durch Whitespace getrennt)
            for part in val.split():
                if part.startswith("LANG="):
                    fields["locale"] = part.split("=", 1)[1]
        elif line.startswith("VC Keymap:"):
            fields["vc_keymap"] = line.split(":", 1)[1].strip()
        elif line.startswith("X11 Layout:"):
            fields["x11_layout"] = line.split(":", 1)[1].strip()
        elif line.startswith("X11 Variant:"):
            fields["x11_variant"] = line.split(":", 1)[1].strip()
    return LocaleStatus(**fields)


def list_locales() -> list[str]:
    """Verfügbare (generierte) Locales. Fallback auf `locale -a`."""
    out = _run(["localectl", "list-locales"])
    if not out:
        out = _run(["locale", "-a"])
    return [l.strip() for l in out.splitlines() if l.strip()]


def current_timezone() -> str:
    """Aktuelle System-Zeitzone, z.B. "Europe/Zurich". '' bei Fehler."""
    return _run(["timedatectl", "show", "-p", "Timezone", "--value"]).strip()


def list_timezones() -> list[str]:
    """Alle bekannten Zeitzonen (timedatectl list-timezones)."""
    out = _run(["timedatectl", "list-timezones"])
    return [l.strip() for l in out.splitlines() if l.strip()]


def ntp_enabled() -> bool:
    """Ob NTP-Zeitsynchronisation (systemd-timesyncd o.ä.) aktiv ist."""
    return _run(["timedatectl", "show", "-p", "NTP", "--value"]).strip() == "yes"


def local_time() -> str:
    """Kurze, lesbare lokale Zeit inkl. Zeitzonen-Kürzel (reiner Read)."""
    return _run(["date", "+%Y-%m-%d %H:%M %Z"]).strip()


def list_x11_layouts() -> list[str]:
    out = _run(["localectl", "list-x11-keymap-layouts"])
    return [l.strip() for l in out.splitlines() if l.strip()]


def list_x11_variants(layout: str) -> list[str]:
    """XKB-Varianten für ein Layout (z.B. nodeadkeys, dvorak). '' = Standard."""
    out = _run(["localectl", "list-x11-keymap-variants", layout])
    return [""] + [l.strip() for l in out.splitlines() if l.strip()]


# ---- Schreib-Aktionen: nur ARGV liefern (Aufrufer führt privilegiert aus) ----


def set_locale_argv(lang: str) -> list[str]:
    return ["localectl", "set-locale", f"LANG={lang}"]


def set_x11_keymap_argv(layout: str, variant: str = "") -> list[str]:
    # Syntax: set-x11-keymap LAYOUT [MODEL [VARIANT [OPTIONS]]].
    # Variante ohne Model -> leeres Model als Platzhalter durchreichen.
    if variant:
        return ["localectl", "set-x11-keymap", layout, "", variant]
    return ["localectl", "set-x11-keymap", layout]


def set_keymap_argv(keymap: str) -> list[str]:
    return ["localectl", "set-keymap", keymap]


def set_timezone_argv(tz: str) -> list[str]:
    return ["timedatectl", "set-timezone", tz]


def set_ntp_argv(on: bool) -> list[str]:
    return ["timedatectl", "set-ntp", "true" if on else "false"]
