#!/usr/bin/python3
# mambatray - tray icon for openmamba
# Copyright (C) 2011-2025 by Silvan Calarco
# Copyright (C) 2011 by michiamophil
# Distributed under the terms of the GPL version 3 FLOSS License
#
import sys
import os
import gettext
import distro

from PyQt6.QtCore import Qt, QTimer, QProcess
from PyQt6.QtGui import QIcon, QCursor
from PyQt6.QtWidgets import (
    QApplication, QSystemTrayIcon, QMenu, QMessageBox
)

DATADIR = os.path.dirname(os.path.realpath(__file__)) + "/"


class SystemTrayIcon(QSystemTrayIcon):

    menu = None
    contatore = 0
    NetsrpmsArg = "-c"
    lista = []
    nOre = 2
    srpm = [
        "skype", "win32codecs", "msttcorefonts", "b43-firmware",
        "virtualbox-extension-pack", "chromium-widevine", "spotify"
    ]
    desktop_session = 'default'
    xdg_session_type = 'x11'

    refreshPackagesTimer = None
    checkSRPMSUpdatesTimer = None
    refreshPackagesCacheProcess = None
    SRPMUpdateProcess = None

    softwareManagerProcess = None
    softwareCheckUpgradesProcess = None
    softwareBaseInstallsProcess = None

    networkOnlineProcess = None
    networkFirewallDisableProcess = None
    networkFirewallEnableProcess = None
    networkFirewallConfigureProcess = None
    networkProxyProcess = None

    def __init__(self, icon):
        super().__init__(icon)
        self.menu = QMenu()

        self.desktop_session = os.getenv('DESKTOP_SESSION') or 'default'
        self.xdg_session_type = os.getenv('XDG_SESSION_TYPE') or 'x11'

        if self.desktop_session == 'default':
            self.desktop_session = 'plasma'
        elif self.desktop_session[:3] == 'kde':
            self.desktop_session = 'kde'

        # Processi e Timer
        self.refreshPackagesTimer = QTimer(self)
        self.checkSRPMSUpdatesTimer = QTimer(self)
        self.refreshPackagesCacheProcess = QProcess(self)
        self.SRPMUpdateProcess = QProcess(self)
        self.networkOnlineProcess = QProcess(self)

        self.refreshPackagesTimer.timeout.connect(self.refreshPackagesCache)
        self.refreshPackagesCacheProcess.finished.connect(self.restartRefreshPackagesTimer)
        self.checkSRPMSUpdatesTimer.timeout.connect(self.SRPMSCheckUpgradeList)

        # Software
        self.softwareManagerProcess = QProcess(self)
        self.softwareCheckUpgradesProcess = QProcess(self)
        self.softwareBaseInstallsProcess = QProcess(self)

        self.softwareMenu = self.menu.addMenu(QIcon.fromTheme("applications-system"), _("Software"))

        self.softwareManageAction = self.softwareMenu.addAction(
            QIcon.fromTheme("applications-other"), _("Add/Remove software packages..."))
        self.softwareManageAction.triggered.connect(self.softwareManager)

        self.softwareCheckUpgradesAction = self.softwareMenu.addAction(
            QIcon.fromTheme("system-software-update"), _("Check for updates now..."))
        self.softwareCheckUpgradesAction.triggered.connect(self.softwareCheckUpgrades)

        self.softwareBaseInstallsAction = self.softwareMenu.addAction(
            QIcon.fromTheme("mambabase"), _("{} components...").format(distro.name()))
        self.softwareBaseInstallsAction.triggered.connect(self.softwareBaseInstalls)

        # Network
        self.networkFirewallDisableProcess = QProcess(self)
        self.networkFirewallEnableProcess = QProcess(self)
        self.networkFirewallConfigureProcess = QProcess(self)
        self.networkProxyProcess = QProcess(self)

        self.networkMenu = self.menu.addMenu(QIcon.fromTheme("preferences-system-network"), _("Network"))

        self.networkFirewallMenu = self.networkMenu.addMenu(QIcon.fromTheme("security-medium"), _("Firewall"))

        self.networkFirewallDisableAction = self.networkFirewallMenu.addAction(
            QIcon.fromTheme("security-low"), _("Disable"))
        self.networkFirewallDisableAction.triggered.connect(self.networkFirewallDisable)
        self.networkFirewallDisableProcess.finished.connect(self.networkFirewallDisableMessage)

        self.networkFirewallEnableAction = self.networkFirewallMenu.addAction(
            QIcon.fromTheme("security-high"), _("Enable"))
        self.networkFirewallEnableAction.triggered.connect(self.networkFirewallEnable)
        self.networkFirewallEnableProcess.finished.connect(self.networkFirewallEnableMessage)

        self.networkFirewallConfigureAction = self.networkFirewallMenu.addAction(
            QIcon.fromTheme("security-medium"), _("Configure..."))
        self.networkFirewallConfigureAction.triggered.connect(self.networkFirewallConfigure)

        self.networkProxyAction = self.networkMenu.addAction(QIcon.fromTheme("network-server"), _("Proxy..."))
        self.networkProxyAction.triggered.connect(self.networkProxy)

        self.SRPMUpdateProcess.finished.connect(self.SRPMSCheckUpgrade)

        # About
        self.menu.addSeparator()
        self.aboutAction = self.menu.addAction(QIcon.fromTheme("system-logo"), _("About"))
        self.aboutAction.triggered.connect(self.about)

        self.setToolTip(_("{} control center").format(distro.name()))
        self.activated.connect(self.iconActivated)
        self.setContextMenu(self.menu)

        # Avvio
        self.refreshPackagesTimer.start(5 * 60000)
        self.checkSRPMSUpdatesTimer.start(4 * 60000)

    def iconActivated(self, reason):
        if reason in (
            QSystemTrayIcon.ActivationReason.Trigger,
            QSystemTrayIcon.ActivationReason.DoubleClick,
            QSystemTrayIcon.ActivationReason.Context
        ):
            if self.xdg_session_type != 'wayland':
                self.contextMenu().popup(QCursor.pos())

    def about(self):
        aboutBox = QMessageBox(self.menu)
        aboutBox.setWindowIcon(QIcon.fromTheme("mambatray"))
        aboutBox.setWindowTitle(_("About"))
        home_url = distro.os_release_info().get('home_url', '')
        aboutBox.setTextFormat(Qt.TextFormat.RichText)
        aboutBox.setText(
            f"<center><b>{_('{} control center').format(distro.name())}</b>"
            f"<br/><br/>{distro.name(pretty=True)}"
            f"<br/><br/><a href=\"{home_url}\">{home_url}</a></center>"
        )
        aboutBox.setIconPixmap(QIcon.fromTheme("system-logo").pixmap(32))
        aboutBox.setWindowModality(Qt.WindowModality.NonModal)
        aboutBox.exec()

    def networkOnline(self):
        return self.networkOnlineProcess.execute("/usr/bin/nm-online", ['-q', '-x'])

    def softwareManager(self):
        if os.path.exists("/usr/bin/plasma-discover"):
            self.softwareManagerProcess.execute("/usr/bin/plasma-discover")
        elif os.path.exists("/usr/bin/dnfdragora"):
            self.softwareManagerProcess.execute("/usr/bin/dnfdragora")
        else:
            QMessageBox.warning(
                self.menu,
                _("Software Manager"),
                _("No supported software manager found (plasma-discover or dnfdragora).")
            )

    def softwareCheckUpgrades(self):
        self.softwareCheckUpgradesProcess.start("/usr/bin/pkcon", ['refresh', 'force'])

    def refreshPackagesCache(self):
        self.refreshPackagesTimer.stop()
        self.refreshPackagesCacheProcess.start("/usr/bin/pkcon", ['refresh', 'force'])

    def restartRefreshPackagesTimer(self, status):
        self.refreshPackagesTimer.start((4 * 60 + 31) * 60000)

    def softwareBaseInstalls(self):
        self.softwareBaseInstallsProcess.start("/usr/bin/mambabase")

    def networkFirewallDisable(self):
        self.networkFirewallDisableProcess.start("sudo", ['/usr/sbin/ufw', 'disable'])

    def networkFirewallDisableMessage(self, status):
        if status == QProcess.ExitStatus.NormalExit:
            self.showMessage("Firewall", _("Firewall disabled in current session"))
        else:
            self.showMessage("Firewall", _("Could not disable firewall"))

    def networkFirewallEnable(self):
        self.networkFirewallEnableProcess.start("sudo", ['/usr/sbin/ufw', 'enable'])

    def networkFirewallEnableMessage(self, status):
        if status == QProcess.ExitStatus.NormalExit:
            self.showMessage("Firewall", _("Firewall enabled in current session"))
        else:
            self.showMessage("Firewall", _("Could not enable firewall"))

    def networkFirewallConfigure(self):
        if self.desktop_session == 'kde' or self.desktop_session.startswith('plasma'):
            self.networkFirewallConfigureProcess.execute("/usr/bin/kcmshell6", ['firewall'])
        else:
            self.networkFirewallConfigureProcess.execute("/usr/bin/gufw")

    def networkProxy(self):
        if self.desktop_session.startswith('plasma'):
            self.networkProxyProcess.execute("/usr/bin/kcmshell6", ['kcm_proxy'])
        elif self.desktop_session == 'gnome':
            self.networkProxyProcess.execute("/usr/bin/gnome-control-center", ["network"])

    def SRPMSCheckUpgradeList(self):
        self.checkSRPMSUpdatesTimer.stop()
        if self.networkOnline() == 0:
            try:
                self.SRPMUpdateProcess.start("/usr/bin/openmamba-netsrpms", [self.NetsrpmsArg, self.srpm[self.contatore]])
            except Exception:
                self.contatore = 0
                if self.NetsrpmsArg == '-c':
                    self.SRPMSAskAndInstall()
                else:
                    self.lista = []
                    self.NetsrpmsArg = '-c'
                    self.checkSRPMSUpdatesTimer.start((self.nOre * 60) * 60000)

    def SRPMSCheckUpgrade(self, status):
        if status == 1:
            self.lista.append(self.srpm[self.contatore])
        self.contatore += 1
        self.SRPMSCheckUpgradeList()

    def SRPMSAskAndInstall(self):
        if self.lista:
            self.Lista = self.PrintLista()
            msg = QMessageBox.question(
                self.menu,
                _("Not Open Source {} components").format(distro.name()),
                _("The following components are available for update: ") +
                "\n\n" + self.Lista + "\n\n" + _("Ok to proceed?"),
                QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
                QMessageBox.StandardButton.Yes
            )
            if msg == QMessageBox.StandardButton.Yes:
                self.NetsrpmsArg = '-u'
                self.SRPMSCheckUpgradeList()
            else:
                self.lista = []
                self.checkSRPMSUpdatesTimer.start((self.nOre * 60) * 60000)
        else:
            self.checkSRPMSUpdatesTimer.start((self.nOre * 60) * 60000)

    def PrintLista(self):
        return ', '.join(self.lista)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setDesktopFileName("mambatray")

    if app.isSessionRestored():
        app.exit(1)
    else:
        app.setQuitOnLastWindowClosed(False)
        gettext.install('mambatray', '/usr/share/locale')
        trayIcon = SystemTrayIcon(QIcon.fromTheme("mambatray"))
        trayIcon.show()
        sys.exit(app.exec())
