"""Printers: CUPS-Druckerverwaltung (read + argv für Schreib-Aktionen).

Read kommt aus den CUPS-Clienttools (lpstat). Schreib-Aktionen werden NICHT
hier ausgeführt — wir liefern nur das argv, das der GUI-Aufrufer (privilegiert
via Helper oder unprivilegiert) selbst startet. So bleibt das Modul UI-frei.

Drucker HINZUFÜGEN (Treiberauswahl) ist bewusst nicht enthalten — das gehört
in ein dediziertes System-Tool.
"""
from __future__ import annotations

import re
import shutil
import subprocess
from dataclasses import dataclass


def available() -> bool:
    """True, wenn die CUPS-Clienttools (lpstat) vorhanden sind."""
    return shutil.which("lpstat") is not None


@dataclass
class Printer:
    name: str
    info: str          # Location o.ä., leer wenn unbekannt
    state: str         # "idle" / "printing" / "stopped"
    enabled: bool
    is_default: bool


def _run(argv: list[str]) -> str:
    """Führt ein read-only Kommando aus, gibt stdout zurück (leer bei Fehler)."""
    try:
        out = subprocess.run(
            argv, capture_output=True, text=True, timeout=10, check=False
        )
    except (OSError, subprocess.SubprocessError):
        return ""
    return out.stdout


def _info_map() -> dict[str, str]:
    """Location pro Drucker aus `lpstat -l -p` (optional, best effort)."""
    info: dict[str, str] = {}
    name: str | None = None
    for line in _run(["lpstat", "-l", "-p"]).splitlines():
        m = re.match(r"printer (\S+) ", line)
        if m:
            name = m.group(1)
            continue
        stripped = line.strip()
        if name and stripped.lower().startswith("location:"):
            info[name] = stripped.split(":", 1)[1].strip()
    return info


def printers() -> list[Printer]:
    """Parst `lpstat -p -d`.

    Zeilen sehen so aus:
        printer Brother is idle.  enabled since …
        printer HP_LaserJet disabled since … -  (stopped, …)
        system default destination: Brother
    """
    out = _run(["lpstat", "-p", "-d"])
    default = ""
    result: list[Printer] = []

    for line in out.splitlines():
        m = re.match(r"system default destination:\s*(\S+)", line)
        if m:
            default = m.group(1)
            continue
        m = re.match(r"printer (\S+) (?:is )?(\S+)", line)
        if not m:
            continue
        name = m.group(1)
        word = m.group(2).rstrip(".").lower()
        if word == "disabled":
            state, enabled = "stopped", False
        elif word == "printing":
            state, enabled = "printing", True
        else:
            state, enabled = "idle", True
        result.append(Printer(name=name, info="", state=state,
                              enabled=enabled, is_default=False))

    locations = _info_map()
    for p in result:
        p.info = locations.get(p.name, "")
        p.is_default = (p.name == default)
    return result


def queue() -> list[str]:
    """Job-Zeilen aus `lpstat -o`. Leere Liste, wenn nichts in der Queue."""
    return [ln for ln in _run(["lpstat", "-o"]).splitlines() if ln.strip()]


# ----------------------------------------------------------- argv (Aufrufer führt aus)

def set_default_argv(name: str) -> list[str]:
    """Default-Drucker setzen (root → via Helper)."""
    return ["lpadmin", "-d", name]


def enable_argv(name: str) -> list[str]:
    """Drucker freigeben (root → via Helper)."""
    return ["cupsenable", name]


def disable_argv(name: str) -> list[str]:
    """Drucker anhalten (root → via Helper)."""
    return ["cupsdisable", name]


def remove_argv(name: str) -> list[str]:
    """Drucker entfernen (root → via Helper)."""
    return ["lpadmin", "-x", name]


def cancel_all_argv() -> list[str]:
    """Gesamte Druck-Queue leeren (unprivilegiert)."""
    return ["cancel", "-a"]
