import gi
import subprocess
import re
import sys

gi.require_version('Gtk', '4.0')
gi.require_version('Adw', '1')
from gi.repository import Gtk, Adw, GLib

class KernelRow(Adw.ActionRow):
    def __init__(self, version, is_installed, manager):
        super().__init__(title=f"Linux Kernel {version}")
        self.version = version
        self.manager = manager
        self.is_installed = is_installed

        self.button = Gtk.Button()
        self.button.set_valign(Gtk.Align.CENTER)
        self.update_status(is_installed)
        self.button.connect("clicked", self.on_button_clicked)
        self.add_suffix(self.button)

    def update_status(self, installed):
        self.is_installed = installed
        if installed:
            self.button.set_label("Entfernen")
            self.button.add_css_class("destructive-action")
            self.button.remove_css_class("suggested-action")
            self.set_subtitle(f"Installiert (inkl. linux{self.version}-headers)")
        else:
            self.button.set_label("Installieren")
            self.button.add_css_class("suggested-action")
            self.button.remove_css_class("destructive-action")
            self.set_subtitle(f"Verfügbar (headers werden automatisch mitinstalliert)")

    def on_button_clicked(self, button):
        pkg = f"linux{self.version}"
        hdr = f"linux{self.version}-headers"
        
        if self.is_installed:
            cmd = ["pkexec", "xbps-remove", "-Fy", pkg, hdr]
            action_name = "Deinstallation"
        else:
            cmd = ["pkexec", "xbps-install", "-Sy", pkg, hdr]
            action_name = "Installation"
        
        try:
            subprocess.run(cmd, check=True)
            self.manager.show_toast(f"{action_name} abgeschlossen.")
            self.manager.refresh_list()
        except subprocess.CalledProcessError:
            self.manager.show_toast("Vorgang abgebrochen.")

class KernelManagerApp(Adw.Application):
    def __init__(self):
        super().__init__(application_id="org.voidlinux.kernelmanager")

    def do_activate(self):
        self.win = Adw.ApplicationWindow(application=self)
        self.win.set_title("Void Kernel Manager")
        self.win.set_default_size(550, 700)

        # Overlay für Toasts (Benachrichtigungen)
        self.toast_overlay = Adw.ToastOverlay()
        
        box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
        self.toast_overlay.set_child(box)
        self.win.set_content(self.toast_overlay)

        # Headerbar
        header = Adw.HeaderBar()
        box.append(header)

        # vkpurge Button
        purge_btn = Gtk.Button(label="System bereinigen (vkpurge)")
        purge_btn.add_css_class("flat")
        purge_btn.connect("clicked", self.on_purge_clicked)
        header.pack_end(purge_btn)

        # INFO-BANNER
        self.banner = Adw.Banner()
        self.banner.set_title("Hinweis: Kernel-Headers für DKMS werden immer automatisch mitbehandelt.")
        # Hier war der Fehler: set_revealed statt set_reveal
        self.banner.set_revealed(True)
        box.append(self.banner)

        # Scrollbereich
        scrolled = Gtk.ScrolledWindow()
        scrolled.set_vexpand(True)
        box.append(scrolled)

        self.list_box = Gtk.ListBox()
        for m in ["start", "end", "top", "bottom"]:
            getattr(self.list_box, f"set_margin_{m}")(12)
        self.list_box.add_css_class("boxed-list")
        scrolled.set_child(self.list_box)

        self.refresh_list()
        self.win.present()

    def show_toast(self, text):
        self.toast_overlay.add_toast(Adw.Toast.new(text))

    def on_purge_clicked(self, button):
        cmd = ["pkexec", "vkpurge", "rm", "all"]
        try:
            subprocess.run(cmd, check=True)
            self.show_toast("System mit vkpurge bereinigt.")
            self.refresh_list()
        except:
            self.show_toast("Bereinigung abgebrochen.")

    def get_lts_version(self):
        try:
            lts_query = subprocess.check_output(["xbps-query", "-p", "run_depends", "-S", "linux-lts"], text=True)
            match = re.search(r"linux(\d+\.\d+)", lts_query)
            if match: return match.group(1)
        except: pass
        return "6.1"

    def refresh_list(self):
        while (child := self.list_box.get_first_child()):
            self.list_box.remove(child)

        lts_ver = self.get_lts_version()
        lts_parts = [int(p) for p in lts_ver.split('.')]

        try:
            # Installiert
            inst_out = subprocess.check_output(["xbps-query", "-l"], text=True)
            installed = set(re.findall(r"ii\s+linux(\d+\.\d+)-", inst_out))

            # Repo
            repo_out = subprocess.check_output(["xbps-query", "-Rs", "linux"], text=True)
            found_versions = set(re.findall(r"linux(\d+\.\d+)-", repo_out))

            sorted_versions = sorted(list(found_versions), 
                                     key=lambda x: [int(p) for p in x.split('.')], 
                                     reverse=True)

            count = 0
            for v in sorted_versions:
                v_parts = [int(p) for p in v.split('.')]
                if v_parts >= lts_parts:
                    row = KernelRow(v, v in installed, self)
                    self.list_box.append(row)
                    count += 1

            if count == 0:
                self.list_box.append(Gtk.Label(label="Keine passenden Kernel gefunden."))

        except Exception as e:
            self.show_toast(f"Fehler beim Laden: {str(e)}")

if __name__ == "__main__":
    app = KernelManagerApp()
    app.run(sys.argv)