pragma Singleton

// A QR code for a saved Wi-Fi network, so a guest can join by pointing a phone
// at the screen. GNOME's Wi-Fi panel has this and it is the most-used thing in
// it; reading a passphrase aloud is the alternative.
//
// The generated image contains the network password in machine-readable form,
// so the helper writes it under XDG_RUNTIME_DIR -- 0700, on tmpfs, gone at
// logout -- rather than anywhere persistent. Nothing here ever holds the
// passphrase itself; this service only ever sees a file path.
//
// Generated on demand. Producing a QR for every saved network up front would
// mean writing images of passwords nobody asked to see.

import Quickshell
import Quickshell.Io
import QtQuick

Singleton {
    id: root

    readonly property string helperPath: Quickshell.shellDir + "/scripts/panama-wifi-qr"

    // [{ name, ssid, shareable }]
    property var networks: []
    property bool scanned: false
    property string lastError: ""

    // The network whose code is on screen, and where its image is. Empty when
    // nothing is being shared.
    property string sharing: ""
    property string imagePath: ""

    readonly property var shareable: root.networks.filter(n => n.shareable)

    function refresh(): void {
        if (!list.running)
            list.running = true;
    }

    function share(name: string): void {
        if (generate.running)
            return;
        // Cache-bust: the helper reuses one file per network, so a QML Image
        // pointed at the same path would keep showing the previous render.
        root.imagePath = "";
        root.sharing = name;
        generate.command = [root.helperPath, "qr", name];
        generate.running = true;
    }

    function stopSharing(): void {
        root.sharing = "";
        root.imagePath = "";
    }

    Process {
        id: list
        command: [root.helperPath, "list"]
        stdout: StdioCollector {
            onStreamFinished: {
                try {
                    const parsed = JSON.parse(this.text);
                    root.networks = Array.isArray(parsed.networks) ? parsed.networks : [];
                    root.lastError = String(parsed.error ?? "");
                } catch (error) {
                    root.networks = [];
                    root.lastError = "Could not read the Wi-Fi helper's output.";
                    console.warn("WifiShare: could not parse helper output:", error);
                }
                root.scanned = true;
            }
        }
    }

    Process {
        id: generate
        stdout: StdioCollector {
            onStreamFinished: {
                try {
                    const parsed = JSON.parse(this.text);
                    const path = String(parsed.path ?? "");
                    const error = String(parsed.error ?? "");
                    if (error !== "" || path === "") {
                        root.lastError = error !== "" ? error : "No QR code was produced.";
                        root.sharing = "";
                        return;
                    }
                    root.lastError = "";
                    root.imagePath = path;
                } catch (error) {
                    root.lastError = "Could not read the generated QR code's path.";
                    root.sharing = "";
                    console.warn("WifiShare: could not parse helper output:", error);
                }
            }
        }
    }
}
