#!/usr/bin/python3 

##################################################################################
# /etc/groovix/lightdm/lightdm.conf groovix specific variables:
#groovix-show-pacrez-status=1
#groovix-autologin-enable=1
#groovix-autologin-user=guest
#groovix-show-user-buttons=1
##################################################################################



import gi
gi.require_version('Gtk', '3.0')
gi.require_version('WebKit2', '4.1')
gi.require_version('LightDM', '1')
from gi.repository import GObject, Gtk, Gdk, WebKit2, LightDM, GLib
import os, sys, re
import json
from time import sleep


sys.path.append('/usr/share/pacrez/src')
import pacrez
import configparser
import pwd
import subprocess



class Greeter(object):

    window = None
    greeter = None
    view = None
    username = None
    password = None
    pacrez_old_message = "uninitialized"

    def __init__(self):

       self.greeter = LightDM.Greeter()

       main_loop = GLib.MainLoop()

       # connect signal handlers to LightDM
       self.greeter.connect('show-prompt', self.show_prompt_cb)
       self.greeter.connect('show-message', self.show_message_cb)
       self.greeter.connect('authentication-complete', self.authentication_complete_cb)


       (autologin_enabled,autologin_user)=self.getAutologinUser()
       if (autologin_enabled):
            # connect to greeter
            self.greeter.connect_sync()
            self.greeter.authenticate(autologin_user);
            main_loop.run ()
       else:

        display = Gdk.Display.get_default()
        monitor = display.get_primary_monitor()
        geometry = monitor.get_geometry()
        screen_width = geometry.width
        screen_height = geometry.height


        self.window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
        self.window.connect("destroy", Gtk.main_quit)
        self.window.app_paintable = True
        self.window.set_default_size(screen_width, screen_height)
        #self.window.realize()
        self.window.fullscreen()
        #self.window.activate_focus()
        #self.window.present()

        # because there is no window manager there is no default cursor 
        cursor = Gdk.Cursor(Gdk.CursorType.ARROW)
        self.window.realize()
        gdk_window = self.window.get_window()
        if gdk_window:
            gdk_window.set_cursor(cursor)

        self.view = WebKit2.WebView()
        settings = self.view.get_settings()
        settings.set_property('enable-developer-extras', False);

        root_web_dir = "/usr/share/groovix-lightdm-greeter"
        theme=self.getTheme()

        '''
        f = open(root_web_dir + "/index.html", 'r')
        self.view.load_html_string(
            f.read(), "file://%s/" % root_web_dir)
        f.close()
        '''

        self.view.load_uri("file://" + root_web_dir + "/"+theme+"/index.html")

        self.view.connect("decide-policy", self.navigation_cb)

        # need to wait until document is loaded before running webkit execute_script call, otherwise we get "ReferenceError: Can't find variable"
        self.view.connect("load-changed", self.webkit_document_load_finished_cb)

        self.window.add(self.view)
        self.window.show_all()
        
        #key to getting focus so blinking cursors appear without clicking somewhere first in lightdm
        self.window.present()

        # connect to greeter
        self.greeter.connect_sync()

        #self.view.execute_script('fade_out_messages();')
        #self.log("prep a")
        #self.show_prompt_cb(self.greeter, "temptext", 0)
        #self.log("prep b")
        #self.get_pacrez_status()
        #self.log("prep c")

        #can't do this too quick, must wait until webkit initialized, otherwise we get: "ReferenceError: Can't find variable" during execute_script call
        #self.init_timer_value=100
        #self.greeter.timeout_id=GObject.timeout_add(self.init_timer_value, self.get_pacrez_status, False ) 

        #let's do it every 30 seconds - not too intense on the server or client
        self.repeat_timer_value=30000
        #self.greeter.timeout_id=GObject.timeout_add(self.repeat_timer_value, self.get_pacrez_status, True ) 
        if self.showPacrezStatus():
            self.greeter.timeout_id=GObject.timeout_add(self.repeat_timer_value, self.get_pacrez_status) 


        main_loop.run()

    def getTheme(self):
        try:
            config=configparser.ConfigParser()
            config.read("/etc/groovix/lightdm/lightdm.conf")
            theme=config.get('Seat:*','groovix-theme')
            return theme

        except:
            pass
    
        return ("default");

    def getAutologinUser(self):
        try:
            config=configparser.ConfigParser()
            config.read("/etc/groovix/lightdm/lightdm.conf")
            autologin_enable=config.getboolean('Seat:*','groovix-autologin-enable')
            autologin_user=  config.get('Seat:*','groovix-autologin-user')
            
            if autologin_user=="auto-created-user":
               f=open('/var/lib/groovix/pac/userinfo/auto-created-user')
               autologin_user=f.read().rstrip('\n')
               f.close()

            #will throw exception if not valid user
            if (autologin_enable):
                autologin_user_valid=pwd.getpwnam(autologin_user);

            self.log(pwd.getpwnam(autologin_user)[2])
            self.log("debug A");
            if (autologin_enable):
                self.log("autologging in "+autologin_user);
                return (True,autologin_user);
        except:
            self.log("not doing autologin of "+autologin_user);
            return (False,"");
    
        self.log("not doing autologin of "+autologin_user);
        return (False,"");

    def showPacrezStatus(self):
        try:
            config=configparser.ConfigParser()
            config.read("/etc/groovix/lightdm/lightdm.conf")
            show_pacrez_status=config.getboolean('Seat:*','groovix-show-pacrez-status')
            if (show_pacrez_status):
                #self.log("debug a");
                return True;
        except:
            #self.log("debug b");
            return False;
    
        #self.log("debug c");
        return False;

    def showUserButtons(self):
        try:
            config=configparser.ConfigParser()
            config.read("/etc/groovix/lightdm/lightdm.conf")
            show_user_buttons=config.getboolean('Seat:*','groovix-show-user-buttons')
            if (show_user_buttons):
                #self.log("debug a");
                return True;
        except:
            #self.log("debug b");
            return False;
    
        #self.log("debug c");
        return False;

    def webkit_document_load_finished_cb(self, web_view, load_event):
       if load_event == WebKit2.LoadEvent.FINISHED:
           self.get_gx_label()
           if self.showPacrezStatus():
               self.get_pacrez_status()
           if self.showUserButtons():
               self.show_user_buttons()
       
    def get_gx_label(self):
       #from socket import gethostname;
       #hostname=gethostname()
       gx_label=subprocess.check_output(["groovix-get-parameter","GX_LABEL"]).decode('utf-8').rstrip()
       if ( ( gx_label == "" ) or ( gx_label == "auto" ) ):
           gx_label = "groovix-label-is-not-set"
       self.log("gx_label is "+gx_label+".")
       self.view.run_javascript("show_gx_label(%s);" % (json.dumps(gx_label)))

    #def get_pacrez_status(self,repeat):
    def get_pacrez_status(self):
       prrc,color,code,shortmessage,fullmessage=pacrez.get_status()

       
       #self.log('pacrez data dump start');
       #self.log(prrc)
       #self.log(color)
       #self.log(code)
       #self.log(shortmessage)
       #self.log(fullmessage)
       #self.log('pacrez data dump end');


       if ( fullmessage != self.pacrez_old_message ):
          self.log("pacrez switching message to : "+fullmessage)
          self.log("pacrez color is now : "+color)
          #self.log("show_pacrez_status('%s','%s');" % (color,fullmessage) )
          #self.log("a");
          #self.view.execute_script("fade_out_messages()")
          #self.log("b");
          self.view.run_javascript("show_pacrez_status(%s,%s);" % (json.dumps(color),json.dumps(fullmessage.replace('\n','<br />'))) )
          #self.log("c");

       self.pacrez_old_message=fullmessage
       #will execute again after timeout as long as we return true
       return True

    def show_user_buttons(self):
        self.view.run_javascript("show_user_buttons();")

    def show_prompt_cb(self, greeter, text, promptType):
        #if promptType == LightDM.PromptType.SECRET:
        self.log("show_prompt_cb "+str(promptType)+text)
        self.view.run_javascript("show_prompt(%s);" % json.dumps(text))

    def show_message_cb(self, greeter, text, type):
        wrapped_text=re.sub("reserved for another user until","reserved for another user<br>until",text)
        self.log("show_message_cb "+text)
        self.view.run_javascript("show_message(%s);" % json.dumps(wrapped_text))

    def authentication_complete_cb(self, greeter):
        self.log("Authentication complete")
        if self.greeter.get_is_authenticated():
            #session = "xubuntu"
            session = self.greeter.get_default_session_hint();
            self.log("starting session "+session)
            if self.greeter.start_session_sync(session):
                pass
            else:
                self.log("Failed to start session")
        else:
            self.log("Authentication failed")
            self.view.run_javascript("authentication_failed()")


    def navigation_cb(self, web_view, decision, decision_type):
        if decision_type == WebKit2.PolicyDecisionType.NAVIGATION_ACTION:
            uri = decision.get_request().get_uri()
            scheme, path=uri.split(':', 1)
            if scheme == 'username':
                self.username=path
                self.log("Login username is %s" % self.username)
                self.greeter.authenticate(self.username)
                decision.ignore()
                return True
            elif scheme == 'password':
                self.password=path
                self.log("Login password is %s" % self.password)
                self.greeter.respond(self.password)
                decision.ignore()
                return True
            else:
                # means that it is a true navigation request, let it go through
                decision.use()
                return True
        return False

    def log(self, text):
        print(text, file=sys.stderr)

    #self.view.connect("context-menu", self.right_click_cb)
    def right_click_cb(self, view, menu, htr, twk, data=None):
            self.log("right click")
            return True



if __name__ == '__main__':
    Greeter()
    Gtk.main()

