#!/usr/bin/python3
import os
import shlex
import subprocess
import sys
import time
from pathlib import Path
from typing import TypedDict, Unpack

import dbus


def get_current_desktop_number() -> int:
    bus = dbus.SessionBus()
    kwin_obj = bus.get_object('org.kde.KWin', '/VirtualDesktopManager')
    props_interface = dbus.Interface(kwin_obj, 'org.freedesktop.DBus.Properties')

    current_uuid = props_interface.Get('org.kde.KWin.VirtualDesktopManager', 'current')

    all_desktops = props_interface.Get('org.kde.KWin.VirtualDesktopManager', 'desktops')
    for desktop in all_desktops:
        if desktop[1] == current_uuid:
            return desktop[0]

    return -1

def run_in_background(command: list[str]) -> subprocess.Popen:
    with open(os.devnull, "wb") as devnull:
        return subprocess.Popen(
            command,
            stdout=devnull,
            stderr=devnull,
            stdin=subprocess.DEVNULL,
            preexec_fn=os.setpgrp,  # noqa: PLW1509
        )

class KonsoleOptions(TypedDict, total = False):
    width: int
    height: int
    layout: Path
    cwd: Path

def build_konsole_command(**kwargs: Unpack[KonsoleOptions]) -> list[str]:
    command = ["/usr/bin/konsole"]
    if 'layout' in kwargs:
        command.extend(["--layout", str(kwargs['layout'])])
    elif 'width' in kwargs and 'height' in kwargs:
        command.extend(["-p", f"TerminalColumns={kwargs['width']}",
                        "-p", f"TerminalRows={kwargs['height']}"])
    if 'cwd' in kwargs:
        command.extend(["--workdir", str(kwargs['cwd'])])
    return command

def open_con(dim: list[tuple[int, int]]) -> None:
    for w, h in dim:
        run_in_background(build_konsole_command(width = w, height = h))

def open_dev() -> None:
    pid = run_in_background(build_konsole_command(layout = home / ".config/konsole/layouts/1.json")).pid
    service = f"org.kde.konsole-{pid}"
    bus = dbus.SessionBus()
    props_interface = None
    for _ in range(10):
        try:
            kwin_obj = bus.get_object(service, "/Windows/1")
            props_interface = dbus.Interface(kwin_obj, 'org.kde.konsole.Window')
            break
        except dbus.exceptions.DBusException:
            pass
        time.sleep(0.1)
    if props_interface is None:
        print("Failed to connect to Konsole DBus interface.", file=sys.stderr)
        return

    id = 2
    while True:
        layout = home / f".config/konsole/layouts/{id}.json"
        if not layout.exists():
            break
        props_interface.loadLayout(str(layout))
        id += 1

if len(sys.argv) > 1:
    home=Path.home()
    for app in sys.argv[1:]:
        match app:
            case "dev":
                open_dev()
    sys.exit(0)

match get_current_desktop_number():
    case 0:
        konsole = build_konsole_command(width = 164, height = 25, cwd = Path('~root').expanduser())
        run_in_background(['xdg-su', '-c', shlex.join(konsole)])
        open_con([(80,42), (80,25)])
    case 1 | 2:
        open_con([(80,42), (100,42), (133,25), (80,25), (150,25), (150,25)])
