#!/usr/bin/env python3
"""
Einfacher HTTP-Server zum Steuern der Bildschirmhelligkeit (und Farbtemperatur)
über wl-gammarelay-rs.

Aufruf-Beispiele (z. B. aus Home Assistant per rest_command):
    GET /set?b=0.5            -> Helligkeit auf 50 %
    GET /set?b=0.3&t=4000     -> Helligkeit 30 %, Farbtemperatur 4000 K
    GET /get                  -> aktuelle Helligkeit als Zahl (z. B. 0.5)
    GET /                     -> kurze Hilfe / Status

Laeuft als Benutzer 'kiosk' INNERHALB der labwc-Sitzung, damit 'busctl --user'
den Daemon direkt erreicht (XDG_RUNTIME_DIR ist dann korrekt gesetzt).

Optional: einfacher Schutz per Token. Wenn unten TOKEN gesetzt ist, muss jede
Anfrage ?token=... mitschicken. Standard: aus (leer).
"""

import os
import subprocess
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from urllib.parse import urlparse, parse_qs

# ----- Einstellungen (bei Bedarf anpassen) -----
HOST = "0.0.0.0"     # 0.0.0.0 = im ganzen LAN erreichbar
PORT = 8080
TOKEN = ""           # z. B. "geheim123" setzen, dann ?token=geheim123 noetig
DBUS_DEST = "rs.wl-gammarelay"
DBUS_PATH = "/"
DBUS_IFACE = "rs.wl.gammarelay"

# Falls XDG_RUNTIME_DIR aus irgendeinem Grund fehlt, sinnvollen Default setzen
# (1001 ist die UID des kiosk-Users auf diesem Geraet).
os.environ.setdefault("XDG_RUNTIME_DIR", "/run/user/1001")


def busctl(*args):
    """Ruft busctl --user auf und gibt (ok, ausgabe) zurueck."""
    cmd = ["busctl", "--user", *args]
    try:
        out = subprocess.run(
            cmd, capture_output=True, text=True, timeout=5
        )
        if out.returncode != 0:
            return False, (out.stderr or out.stdout).strip()
        return True, out.stdout.strip()
    except Exception as e:
        return False, str(e)


def set_brightness(value):
    value = max(0.0, min(1.0, float(value)))
    return busctl("set-property", DBUS_DEST, DBUS_PATH, DBUS_IFACE,
                  "Brightness", "d", f"{value:.3f}")


def set_temperature(kelvin):
    kelvin = int(max(1000, min(10000, int(kelvin))))
    return busctl("set-property", DBUS_DEST, DBUS_PATH, DBUS_IFACE,
                  "Temperature", "q", str(kelvin))


def get_brightness():
    ok, out = busctl("get-property", DBUS_DEST, DBUS_PATH, DBUS_IFACE,
                     "Brightness")
    if not ok:
        return ok, out
    # Ausgabe sieht aus wie:  d 0.5
    parts = out.split()
    return True, parts[-1] if parts else out


class Handler(BaseHTTPRequestHandler):
    def _reply(self, code, text):
        body = (text + "\n").encode()
        self.send_response(code)
        self.send_header("Content-Type", "text/plain; charset=utf-8")
        self.send_header("Content-Length", str(len(body)))
        self.end_headers()
        self.wfile.write(body)

    def do_GET(self):
        u = urlparse(self.path)
        q = parse_qs(u.query)

        if TOKEN and q.get("token", [""])[0] != TOKEN:
            return self._reply(403, "forbidden")

        if u.path == "/" or u.path == "/help":
            return self._reply(
                200,
                "brightness-server\n"
                "/set?b=0.5        Helligkeit (0.0-1.0)\n"
                "/set?b=0.3&t=4000 Helligkeit + Temperatur (K)\n"
                "/get              aktuelle Helligkeit",
            )

        if u.path == "/get":
            ok, out = get_brightness()
            return self._reply(200 if ok else 500, out)

        if u.path == "/set":
            results = []
            if "b" in q:
                ok, out = set_brightness(q["b"][0])
                results.append("brightness ok" if ok else f"brightness FEHLER: {out}")
            if "t" in q:
                ok, out = set_temperature(q["t"][0])
                results.append("temp ok" if ok else f"temp FEHLER: {out}")
            if not results:
                return self._reply(400, "fehlender Parameter b oder t")
            failed = any("FEHLER" in r for r in results)
            return self._reply(500 if failed else 200, "; ".join(results))

        return self._reply(404, "unbekannter Pfad")

    # Logging in der Konsole knapp halten
    def log_message(self, fmt, *args):
        pass


if __name__ == "__main__":
    srv = ThreadingHTTPServer((HOST, PORT), Handler)
    print(f"brightness-server laeuft auf {HOST}:{PORT}")
    try:
        srv.serve_forever()
    except KeyboardInterrupt:
        pass
