#!/usr/bin/env python3
"""astal-menu — a touch-friendly GTK4 popup control centre (Location, Weather,
Bluetooth, Network) plus an application drawer, replacing nwg-dock/nwg-drawer.

Single-instance: the first launch builds the (hidden) window and holds. Later
invocations forward their arguments to it over D-Bus, so `main.py --toggle`
toggles the running instance without spawning a new process.

  main.py            run the resident instance (stays hidden until toggled)
  main.py --toggle   toggle visibility
  main.py --show     show     |  --hide  hide  |  --appdrawer  show with drawer open
"""

from __future__ import annotations

import os
import sys
from pathlib import Path

# astal-menu-start.sh LD_PRELOADs libgtk4-layer-shell so it loads before
# libwayland-client (a load-ordering requirement of the layer-shell library). That
# only matters at *this* process's exec: the library is already resident now, so the
# variable is never read again. Drop it here so the GUI apps we launch via
# AstalApps.launch() (and the backend subprocesses) don't inherit it — Firefox, for
# one, aborts at startup with libgtk4-layer-shell preloaded.
os.environ.pop("LD_PRELOAD", None)

# Make sibling modules importable no matter the CWD.
sys.path.insert(0, str(Path(__file__).resolve().parent))

import gi  # noqa: E402

gi.require_version("Gtk", "4.0")
from gi.repository import Gio, GLib, Gtk  # noqa: E402

import theme  # noqa: E402
from appservices import Services  # noqa: E402
from paths import APP_ID, ensure_dirs  # noqa: E402
from settings import Settings  # noqa: E402
from window import MenuWindow  # noqa: E402


class AstalMenuApp(Gtk.Application):
    def __init__(self) -> None:
        super().__init__(application_id=APP_ID,
                         flags=Gio.ApplicationFlags.HANDLES_COMMAND_LINE)
        self.window: MenuWindow | None = None

    def do_startup(self) -> None:
        Gtk.Application.do_startup(self)
        ensure_dirs()
        theme.load_css()
        settings = Settings()
        services = Services()
        self.window = MenuWindow(self, settings, services)
        self.hold()  # stay alive with no visible window

    def do_command_line(self, cmdline: Gio.ApplicationCommandLine) -> int:
        args = cmdline.get_arguments()[1:]
        # No args = start (or keep) the resident instance hidden. Only explicit
        # verbs change visibility, so the autostart launch never pops the menu.
        action = args[0] if args else "--daemon"
        if self.window is None:
            return 0
        if action == "--show":
            self.window.show_menu()
        elif action == "--hide":
            self.window.hide_menu()
        elif action == "--appdrawer":
            self.window.show_menu(focus_appdrawer=True)
        elif action == "--toggle":
            self.window.toggle()
        # --daemon and anything else: no-op (stay as-is)
        return 0

    def do_activate(self) -> None:
        # Resident instance: nothing to do on plain activate.
        pass


def main() -> int:
    GLib.set_prgname("astal-menu")
    return AstalMenuApp().run(sys.argv)


if __name__ == "__main__":
    raise SystemExit(main())
