#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from PyQt5.QtGui import QGuiApplication, QIcon, QScreen
from PyQt5.QtQuick import QQuickView
from PyQt5.QtCore import QUrl, QLocale, QTranslator, QLibraryInfo,  QVariant, QAbstractListModel, \
    QModelIndex, Qt, QObject, pyqtSlot, pyqtSignal, QCoreApplication
from PyQt5.QtNetwork import QNetworkConfigurationManager, QNetworkConfiguration
import sys
import os
import subprocess
from helpers import get_desktop_name, get_desktop_name2, is_installed
import pwd
# Workaround for opengl lib selection
from OpenGL import GL

translate = QCoreApplication.translate

class ConfList(QAbstractListModel):
    NameRole = Qt.UserRole + 1
    def __init__(self, parent=None):
        super().__init__(parent)
        # Changing working directory
        abspath = os.path.abspath(__file__)
        dname = os.path.dirname(abspath)
        os.chdir(dname)

        #collect sys info
        release = subprocess.getoutput('lsb_release -sd')
        release = release[1:-1]
        release_nb = subprocess.getoutput('lsb_release -sr')
        release_nb = release_nb.strip()
        kernel = subprocess.getoutput('uname -r')
        if os.uname()[4] == 'x86_64':
          arch = '64-bit'
        else:
          arch = '32-bit'
        try:
            desktop = get_desktop_name(os.path.basename(os.getenv("DESKTOP_SESSION")))
        except:
            desktop = 'Other'

        if desktop == 'Other':
          desktop = get_desktop_name2(os.getenv("XDG_CURRENT_DESKTOP"))
          if desktop == 'unknown':
              desktop = os.getenv("XDG_CURRENT_DESKTOP")
        self.screen_factor = 0.0
        if desktop == 'Gnome Wayland':            
            import gi
            gi.require_version('Gdk', '3.0')
            from gi.repository.Gdk import Display
            # pre-3.22, otherwise deprecated
            #factor = Gdk.Screen.get_default().get_monitor_scale_factor(0)
            self.screen_factor = Display.get_default().get_monitor(0).get_scale_factor()

        # Search active network connections
        net = QNetworkConfigurationManager()
        first = True
        if net.isOnline():
              confs = net.allConfigurations(QNetworkConfiguration.Active)
              for conf in confs:
                  if first:
                      netconfs = conf.name()
                      first = False
                  else:
                      netconfs += ", " + conf.name()

        self.configuration = [
            {'name': translate('ConfList',"<b>Congratulations!</b><BR />You are now running {}").format(release)},
            {'name': translate('ConfList',"You are using linux kernel: {}").format(kernel)},
            {'name': translate('ConfList',"Your system architecture is: {}").format(arch)},
            {'name': translate('ConfList',"You are now using the Desktop: {}").format(desktop)},
            {'name': translate('ConfList',"Your user id is: {}").format(os.getuid())},
        ]
        if net.isOnline():
            self.configuration.append({'name': translate('ConfList',"You are connected to a network through {}").format(netconfs)})
        else:
            self.configuration.append({'name': translate('ConfList',"You have no network connection")})

    def factor(self, app):
        '''
        Determine screen factor
        Can be specific for Gnome Wayland
        '''
        if self.screen_factor == 0 :
            screen = app.primaryScreen()
            self.screen_factor = screen.devicePixelRatio()
        return self.screen_factor

    def data(self, index, role=Qt.DisplayRole):
        row = index.row()
        return self.configuration[row]["name"]

    def rowCount(self, parent=QModelIndex()):
        return len(self.configuration)

    def roleNames(self):
        return {
            ConfList.NameRole: b'name',
        }

class Callbrowser(QObject):
    def __init__(self):
        QObject.__init__(self)

    @pyqtSlot(str)
    def weblink(self, link):
        subprocess.Popen(["xdg-open", link])

class Launcher(QObject):
    installed = pyqtSignal()
    def __init__(self):
        QObject.__init__(self)

    @pyqtSlot(QVariant)
    def command(self, app):
        if app.isArray():
            cmd = []
            for i in range(0,app.property("length").toInt()):
                cmd.append(app.property(i).toString())
            proc = subprocess.Popen(cmd)
            if cmd[0] == "gurpmi":
                proc.wait()
                print(proc.returncode)
                # Give the signal to reload the applist
                self.installed.emit()

class Norun(QObject):
    def __init__(self):
        QObject.__init__(self)
        self.home = os.getenv("HOME")
        self.conffile = self.home + "/.config/mageiawelcome/norun.flag"

    @pyqtSlot(bool)
    def setRunAtLaunch(self, checked):
        print("Setting",checked)
        if checked:
            if os.path.exists(self.conffile):
                os.remove( self.conffile)
        else:
            os.makedirs(self.home + "/.config/mageiawelcome", exist_ok=True)
            with open( self.conffile, 'w') :
                pass

    @pyqtSlot(result=bool)
    def startupcheck(self):
        return not os.path.exists(self.conffile)

class Installable(QObject):
    def __init__(self):
        QObject.__init__(self)

    @pyqtSlot(str, str, result=bool)
    def installable(self, app,repo):
        is_app_installed, inst_repo = is_installed(app)
        installable = (not is_app_installed) or (repo != inst_repo and inst_repo == "")
        return installable

    @pyqtSlot(str, str, result=bool)
    def other(self, app, repo):
        is_app_installed, inst_repo = is_installed(app)
        return (is_app_installed and repo == '' and inst_repo != "")


def username():
    user = pwd.getpwuid(os.getuid())[4]  # pw_gecos, i e the real name
    if user == "":
        user = pwd.getpwuid(os.getuid())[0] # login
    return user

if __name__ == '__main__':
    app = QGuiApplication(sys.argv)
    locale = QLocale.system().name()
    qtTranslator = QTranslator()
    if qtTranslator.load("qt_" + locale,QLibraryInfo.location(QLibraryInfo.TranslationsPath)):
        app.installTranslator(qtTranslator)
    appTranslator = QTranslator()
    if appTranslator.load(QLocale(),"mageiawelcome","_", '/usr/share/mageiawelcome/translations'):
        app.installTranslator(appTranslator)
    app.setOrganizationName("Mageia")
    app.setApplicationName("Mageiawelcome")
    view = QQuickView()
    view.setResizeMode(QQuickView.SizeRootObjectToView)
    view.setTitle(app.translate('app',"Welcome to Mageia"))
    app.setWindowIcon(QIcon("/usr/share/icons/hicolor/32x32/apps/mageiawelcome.png"))
    cb = Callbrowser()
    la = Launcher()
    us = username()
    ins = Installable()
    cl = ConfList()
    nr = Norun()
    sc =  nr.startupcheck()
    factor = cl.factor(app)
    screen = app.primaryScreen()
    # if density is high, use at least factor 2 to scale the initial window. Considering high is more than 190 px/inches.
    if screen.logicalDotsPerInch() > 190 :
        factor = max(2.0, factor)
    defaultHeight = min(700 * factor, screen.availableGeometry().height())
    defaultWidth = min(1000 * factor, screen.availableGeometry().width())
    centerPoint = screen.availableGeometry().center()
    view.setGeometry(centerPoint.x() -defaultWidth/2, centerPoint.y() - defaultHeight/2, defaultWidth,defaultHeight)
    view.rootContext().setContextProperty('link', cb)
    view.rootContext().setContextProperty('launch', la)
    view.rootContext().setContextProperty('user', us)
    view.rootContext().setContextProperty('ConfList', cl)
    view.rootContext().setContextProperty('pyinstallable', ins)
    view.rootContext().setContextProperty('startupcheck', sc)
    view.rootContext().setContextProperty('norun', nr)
    current_path = os.path.abspath(os.path.dirname(__file__))
    qml_file = os.path.join(current_path, 'mw-ui.qml')
    view.setSource(QUrl.fromLocalFile(qml_file))
    if view.status() == QQuickView.Error:
        for error in view.errors():
            print(error.description())
        sys.exit(-1)
    view.show()
    res = app.exec_()
    del view
    sys.exit(res)