# WMT Device Configuration Tool
# Reads/writes data/config.txt (INI format).
# On save, bumps [meta] last_synced to NOW so app.py will push an
# update-request to Server_Monitorizare_v2 on next startup.

import os
import time
import socket
import subprocess
import configparser
from datetime import datetime

import FreeSimpleGUI as sg

CONFIG_PATH = "./data/config.txt"


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _get_os_version():
    try:
        with open("/etc/os-release") as f:
            for line in f:
                if line.startswith("PRETTY_NAME="):
                    return line.split("=", 1)[1].strip().strip('"')
    except Exception:
        pass
    return "unknown"


def _get_local_ip():
    try:
        h = socket.gethostname()
        return socket.gethostbyname(h)
    except Exception:
        return "127.0.0.1"


def _read_config():
    """Return a dict with all device-relevant fields from config.txt."""
    p = configparser.ConfigParser()
    p.read(CONFIG_PATH)
    return {
        "device_name":     p.get("device",  "work_place",       fallback="notconfig"),
        "hostname":        p.get("device",  "hostname",         fallback=socket.gethostname()),
        "device_ip":       p.get("device",  "ip",               fallback=_get_local_ip()),
        "location":        p.get("device",  "location",         fallback=""),
        "card_presence":   p.get("device",  "card_presence",    fallback="enable"),
        "info_reviewed_at":p.get("device",  "info_reviewed_at", fallback="1970-01-01T00:00:00"),
        # preserve other sections verbatim
        "chrome_url":           p.get("chrome",    "chrome_url",           fallback=""),
        "chrome_local_url":     p.get("chrome",    "chrome_local_url",     fallback=""),
        "chrome_insecure_origin":p.get("chrome",   "chrome_insecure_origin",fallback=""),
        "card_api_base_url":    p.get("card_api",  "base_url",             fallback=""),
        "server_log_url":       p.get("server",    "log_url",              fallback=""),
        "update_host":          p.get("server",    "update_host",          fallback=""),
        "update_user":          p.get("server",    "update_user",          fallback=""),
        "internet_check_host":  p.get("server",    "internet_check_host",  fallback=""),
        "last_synced":          p.get("meta",      "last_synced",          fallback="1970-01-01T00:00:00"),
    }


def _write_config(cfg):
    """Write all fields back to config.txt and bump last_synced to NOW."""
    p = configparser.ConfigParser()

    p.add_section("chrome")
    p.set("chrome", "chrome_url",            cfg.get("chrome_url", ""))
    p.set("chrome", "chrome_local_url",      cfg.get("chrome_local_url", ""))
    p.set("chrome", "chrome_insecure_origin",cfg.get("chrome_insecure_origin", ""))

    p.add_section("card_api")
    p.set("card_api", "base_url", cfg.get("card_api_base_url", ""))

    p.add_section("server")
    p.set("server", "log_url",             cfg.get("server_log_url", ""))
    p.set("server", "update_host",         cfg.get("update_host", ""))
    p.set("server", "update_user",         cfg.get("update_user", ""))
    p.set("server", "internet_check_host", cfg.get("internet_check_host", ""))

    p.add_section("device")
    p.set("device", "work_place",       cfg["device_name"])
    p.set("device", "hostname",         cfg["hostname"])
    p.set("device", "ip",               cfg["device_ip"])
    p.set("device", "location",         cfg.get("location", ""))
    p.set("device", "card_presence",    cfg.get("card_presence", "enable"))
    p.set("device", "info_reviewed_at", cfg.get("info_reviewed_at", "1970-01-01T00:00:00"))

    # Bump last_synced → tells app.py local config is newer → push update request
    now_ts = datetime.now().isoformat(timespec="seconds")
    p.add_section("meta")
    p.set("meta", "last_synced", now_ts)

    os.makedirs("./data", exist_ok=True)
    with open(CONFIG_PATH, "w") as f:
        f.write("# WMT Application Configuration\n")
        f.write(f"# Last updated by config.py: {now_ts}\n\n")
        p.write(f)

    print(f"✓ config.txt saved (last_synced={now_ts})")


def _set_printer(device_name):
    """Configure CUPS printer to match the device/masa name."""
    try:
        import cups
        conn = cups.Connection()
        printers = conn.getPrinters()
        if device_name in printers:
            print(f"Printer '{device_name}' is already configured.")
            return
        print(f"Installing printer '{device_name}' ...")
        cmd = (f"sudo /usr/sbin/lpadmin -p {device_name} -E "
               f"-v usb://CITIZEN/CT-S310II?serial=00000000 -m CTS310II.ppd")
        os.popen(cmd)
        time.sleep(2)
        print(f"Printer '{device_name}' installed.")
    except Exception as e:
        print(f"Printer setup skipped: {e}")


def _update_hostname(new_hostname):
    """Change system hostname if it differs from the current one."""
    current = socket.gethostname()
    if current == new_hostname:
        print(f"Hostname unchanged: {new_hostname}")
        return
    print(f"Updating hostname: {current} → {new_hostname}")
    subprocess.run(["sudo", "hostnamectl", "set-hostname", new_hostname], check=False)
    print("Hostname updated. A reboot is recommended.")


def _show_result(title, lines):
    """Simple modal popup."""
    layout = [[sg.Text(line)] for line in lines] + [[sg.Button("OK")]]
    w = sg.Window(title, layout, modal=True)
    while True:
        ev, _ = w.read()
        if ev in (sg.WIN_CLOSED, "OK"):
            break
    w.close()


# ---------------------------------------------------------------------------
# Main GUI
# ---------------------------------------------------------------------------

def main():
    cfg = _read_config()
    os_ver  = _get_os_version()
    local_ip = _get_local_ip()

    sg.theme("Dark Grey 9")
    sg.set_options(font=("Arial Bold", 15))

    LABEL_W = 22
    INPUT_W = 38

    layout = [
        [sg.Text("WMT Device Configuration", font=("Arial Bold", 18),
                 justification="center", expand_x=True, pad=(0, 12))],

        # ── Editable fields ──────────────────────────────────────
        [sg.HorizontalSeparator()],
        [sg.Text("── Device Identity ──", font=("Arial Bold", 13),
                 text_color="#aaaaaa", pad=(0, 6))],

        [sg.Text("Hostname",          size=(LABEL_W, 1)),
         sg.InputText(cfg["hostname"],  key="-HOSTNAME-",    size=(INPUT_W, 1))],

        [sg.Text("Loc de Munca / Masa", size=(LABEL_W, 1)),
         sg.InputText(cfg["device_name"], key="-MASA-",       size=(INPUT_W, 1))],

        [sg.Text("Location",           size=(LABEL_W, 1)),
         sg.InputText(cfg.get("location", ""), key="-LOCATION-",
                      size=(INPUT_W, 1),
                      tooltip="Physical location, e.g. Floor 2, Line A, Masa-01")],

        [sg.Text("Card Presence",       size=(LABEL_W, 1)),
         sg.Combo(["enable", "disable"],
                  default_value=cfg.get("card_presence", "enable"),
                  key="-CARD_PRESENCE-", size=(INPUT_W - 2, 1), readonly=True,
                  tooltip="enable = card reader active; disable = no card reader")],

        # ── Read-only system info ─────────────────────────────────
        [sg.HorizontalSeparator()],
        [sg.Text("── System Info (read-only) ──", font=("Arial Bold", 13),
                 text_color="#aaaaaa", pad=(0, 6))],

        [sg.Text("OS Version",  size=(LABEL_W, 1)),
         sg.InputText(os_ver,   key="-OS-",  size=(INPUT_W, 1),
                      disabled=True, text_color="#888888")],

        [sg.Text("IP Address",  size=(LABEL_W, 1)),
         sg.InputText(local_ip, key="-IP-",  size=(INPUT_W, 1),
                      disabled=True, text_color="#888888")],

        [sg.Text("Last Synced", size=(LABEL_W, 1)),
         sg.InputText(cfg["last_synced"], key="-SYNC-", size=(INPUT_W, 1),
                      disabled=True, text_color="#888888")],

        # ── Status output ─────────────────────────────────────────
        [sg.HorizontalSeparator()],
        [sg.Multiline("", key="-OUT-", size=(62, 5), disabled=True,
                       autoscroll=True, background_color="#1a1a1a",
                       text_color="#cccccc", font=("Courier", 12))],

        # ── Buttons ───────────────────────────────────────────────
        [sg.Button("Save & Apply", key="-SAVE-", button_color=("white", "#2980b9"), size=(18, 1)),
         sg.Button("Cancel",       key="-CANCEL-",                                  size=(12, 1))],
    ]

    window = sg.Window("WMT Configuration", layout, size=(720, 540), finalize=True)

    def log(msg):
        window["-OUT-"].update(disabled=False)
        window["-OUT-"].print(msg)
        window["-OUT-"].update(disabled=True)

    while True:
        event, values = window.read()

        if event in (sg.WIN_CLOSED, "-CANCEL-"):
            break

        if event == "-SAVE-":
            new_hostname      = values["-HOSTNAME-"].strip()
            new_masa          = values["-MASA-"].strip()
            new_location      = values["-LOCATION-"].strip()
            new_card_presence = values["-CARD_PRESENCE-"]

            if not new_hostname or not new_masa:
                _show_result("Validation Error",
                             ["Hostname and Loc de Munca / Masa are required."])
                continue

            # Update cfg dict with edited values
            cfg["hostname"]      = new_hostname
            cfg["device_name"]   = new_masa
            cfg["location"]      = new_location
            cfg["card_presence"] = new_card_presence
            cfg["device_ip"]     = local_ip

            # 1. Save config.txt (bumps last_synced → triggers server update request)
            try:
                _write_config(cfg)
                log("✓ config.txt saved. last_synced updated to NOW.")
                log("  → app.py will push update request to server on next start.")
            except Exception as e:
                log(f"✗ Failed to save config.txt: {e}")

            # 2. Update hostname if changed
            try:
                _update_hostname(new_hostname)
                log(f"✓ Hostname: {new_hostname}")
            except Exception as e:
                log(f"✗ Hostname update error: {e}")

            # 3. Configure printer
            try:
                _set_printer(new_masa)
                log(f"✓ Printer check done for '{new_masa}'.")
            except Exception as e:
                log(f"  Printer: {e}")

            log("")
            log("Done. Reboot recommended if hostname changed.")

    window.close()


if __name__ == "__main__":
    main()

     
    









