import Quickshell
import Quickshell.Io
import Quickshell.Services.Pipewire
import QtQuick

import "services/AudioStreams.js" as AudioStreams
import qs.services

ShellRoot {
    readonly property int audioOutStreamFlag: 4

    property var fixtureNodes: [
        {
            id: 10,
            ready: true,
            type: audioOutStreamFlag,
            properties: {
                "application.id": "org.chromium.Chromium",
                "application.name": "Chromium",
                "application.icon_name": "chromium"
            },
            description: "Chromium audio",
            audio: { volume: 0.4, muted: false }
        },
        {
            id: 11,
            ready: true,
            type: audioOutStreamFlag,
            properties: {
                "application.id": "org.chromium.Chromium",
                "application.name": "Chromium",
                "application.icon_name": "chromium"
            },
            description: "Chromium audio",
            audio: { volume: 0.8, muted: true }
        },
        {
            id: 20,
            ready: true,
            type: audioOutStreamFlag,
            properties: {
                "application.process.binary": "spotify",
                "application.name": "Spotify"
            },
            description: "Spotify",
            audio: { volume: 0.25, muted: false }
        },
        {
            id: 30,
            ready: true,
            type: 2,
            properties: { "application.name": "Microphone capture" },
            description: "Input stream",
            audio: { volume: 0.5, muted: false }
        },
        {
            id: 40,
            ready: false,
            type: audioOutStreamFlag,
            properties: { "application.name": "Not ready" },
            description: "Unready stream",
            audio: { volume: 0.5, muted: false }
        },
        {
            id: 99,
            ready: true,
            type: audioOutStreamFlag,
            properties: {},
            description: "",
            audio: { volume: 1, muted: false }
        }
    ]

    function groups(): var {
        return AudioStreams.group(fixtureNodes, audioOutStreamFlag);
    }

    IpcHandler {
        target: "application-volume-test"

        function summary(): string {
            const applications = groups();
            const chromium = applications.find(application =>
                application.key === "org.chromium.Chromium");
            return JSON.stringify({
                groups: applications.map(application => ({
                    key: application.key,
                    label: application.label,
                    icon: application.icon,
                    count: application.nodes.length
                })),
                chromiumVolume: AudioStreams.volume(chromium),
                chromiumMuted: AudioStreams.muted(chromium)
            });
        }

        function mutateVolume(): string {
            const chromium = groups().find(application =>
                application.key === "org.chromium.Chromium");
            const changed = AudioStreams.setVolume(chromium, 0.7);
            return JSON.stringify({
                changed,
                volumes: chromium.nodes.map(node => node.audio.volume),
                muted: chromium.nodes.map(node => node.audio.muted)
            });
        }

        function mutateMute(): string {
            const chromium = groups().find(application =>
                application.key === "org.chromium.Chromium");
            const changed = AudioStreams.setMuted(chromium, true);
            return JSON.stringify({
                changed,
                muted: chromium.nodes.map(node => node.audio.muted)
            });
        }

        function serviceSummary(): string {
            const applications = AudioDevices.applications;
            return JSON.stringify({
                count: applications.length,
                validTypes: applications.every(application =>
                    application.nodes.every(node =>
                        (node.type & PwNodeType.AudioOutStream)
                            === PwNodeType.AudioOutStream))
            });
        }

        function invalidMutations(): string {
            return JSON.stringify({
                nullVolume: AudioDevices.setApplicationVolume(null, 0.5),
                emptyMute: AudioDevices.setApplicationMuted({ nodes: [] }, true)
            });
        }
    }
}
