#!/usr/bin/python3
from optparse import OptionParser
import dbus
from dbus.mainloop.glib import DBusGMainLoop
from gi.repository import GLib
from threading import Event 
from gettext import gettext as _
import gettext
import threading

ACTION_INSTALL = 1
ACTION_CHECK_RESOLVER = 3
ACTION_DOWNLOADONLY = 4

class SystemUpdater:
    def __init__(self) -> None:
        self.update_detect_status = False
        self.update_detect_event = Event()
        self.update_list = []
        self.resolve_depend_status = False
        self.resolve_depend_status_event = Event()
        self.remove_pkgs = []
        self.install_finish_status = False
        self.install_finish_status_event = Event()
        self.install_finish_group = []
        self.download_finish_status = False
        self.download_finish_status_event = Event()
        DBusGMainLoop(set_as_default=True)
        self.loop = GLib.MainLoop()
        self.system_bus = dbus.SystemBus()
        self.update_proxy = self.system_bus.get_object('com.kylin.systemupgrade','/com/kylin/systemupgrade',follow_name_owner_changes=True)
        self.update_interface = dbus.Interface(self.update_proxy,dbus_interface='com.kylin.systemupgrade.interface')
        self.update_proxy.connect_to_signal('UpdateDetectFinished',self.update_detect_finished_handler)                                        
        self.update_proxy.connect_to_signal('UpdateFixBrokenStatus',self.update_fix_broken_status)
        self.update_proxy.connect_to_signal('UpdateDependResloveStatus',self.update_depend_resolve_status)                                           
        self.update_proxy.connect_to_signal('UpdateDloadAndInstStaChanged',self.update_download_install_status)
        self.update_proxy.connect_to_signal('UpdateInstallFinished',self.update_install_finished)                                        
        self.update_proxy.connect_to_signal('UpdateDownloadFinished',self.update_download_finished) 

    
    def update_detect_finished_handler(self,success,updatelist,error_status,error_cause):
        print(_("update detect finished:sucess:%s,updatelist:%s,error_status:%s,error_cause:%s")\
            %(success,",".join(updatelist),error_status,error_cause))
        self.update_detect_status = success
        self.update_list = updatelist
        self.update_detect_event.set()
        self.Quit()
    
    def update_fix_broken_status(self,resolver_status,remove_status,remove_pkgs,pkg_raw_description,delete_desc,error_string,error_desc):
        print(_("update fix broken status:resolver_status:%s,remove_status:%s,error_string:%s,error_desc:%s")%(resolver_status,remove_status,error_string,error_desc))
        #logging.info(remove_pkgs,pkg_raw_description,delete_desc)
        self.update_detect_status = False
        self.update_list = []
        self.update_detect_event.set() 
        self.Quit()    
        
    def update_depend_resolve_status(self,resolver_status,remove_status,remove_pkgs,pkg_raw_description,delete_description,error_string,error_desc):
        print(_("update depend resove status:%s,remove status:%s,remove pkgs:%s,pkg raw description:%s,delete_descrition:%s,error string:%s,error desc:%s")\
            %(resolver_status,remove_status,",".join(remove_pkgs),",".join(pkg_raw_description),",".join(delete_description),error_string,error_desc))
        self.resolve_depend_status = resolver_status
        self.remove_pkgs = remove_pkgs
        self.resolve_depend_status_event.set()
        self.Quit()
    
    def update_download_install_status(self,group,progress,status,details):
        print(_("%s update progress:%d,status:%s,details:%s")%(",".join(group),progress,status,details))
        
    def update_install_finished(self,success,group,error_string,error_desc):
        print(_("update install finisih success:%s,group:%s,error string:%s,error desc:%s")\
            %(success,",".join(group),error_string,error_desc))
        self.install_finish_status = success
        self.install_finish_group=group
        self.install_finish_status_event.set()
        self.Quit()
        
    def update_download_finished(self,success,group,error_string,error_desc):
        print(_("update download finisih success:%s,group:%s,error string:%s,error desc:%s")\
            %(success,",".join(group),error_string,error_desc))
        self.download_finish_status = success    
        self.download_finish_group = group
        self.download_finish_status_event.set()
        self.Quit()
    
    def download(self):
        print(_("start download"))
        self.update_detect_event.clear()
        self.UpdateDetect()
        self.loop.run()
        self.update_detect_event.wait()
        print(_("update detect finish:%s,%s")%(self.update_detect_status,",".join(self.update_list)))
        if self.update_detect_status and len(self.update_list)>0:
            pass
        elif not self.update_detect_status and 'kylin-system-updater' in self.update_list:
            print(_("self update finished"))
        else:
            return
        self.resolve_depend_status_event.clear()
        self.DistUpgradeForAuto(ACTION_CHECK_RESOLVER)
        self.loop.run()
        self.resolve_depend_status_event.wait()
        print(_("resolve dependency status:%s,%s")%(self.resolve_depend_status,",".join(self.remove_pkgs)))
        if self.resolve_depend_status and len(self.remove_pkgs)==0:
            pass
        else:
            return
        self.download_finish_status_event.clear()
        self.DistUpgradeForAuto(ACTION_DOWNLOADONLY)
        self.loop.run()
        self.download_finish_status_event.wait()
        print(_("download finish status:%s,%s")%(self.download_finish_status,",".join(self.download_finish_group)))
        return
            
    def install(self):
        print(_("start install"))
        self.update_detect_event.clear()
        self.UpdateDetect()
        self.loop.run()
        self.update_detect_event.wait()
        print(_("update detect finish:%s,%s")%(self.update_detect_status,",".join(self.update_list)))
        if self.update_detect_status and len(self.update_list)>0:
            pass
        elif not self.update_detect_status and 'kylin-system-updater' in self.update_list:
            print(_("self update finished"))
        else:
            self.Quit()
        self.resolve_depend_status_event.clear()
        self.DistUpgradeForAuto(ACTION_CHECK_RESOLVER)
        self.loop.run()
        self.resolve_depend_status_event.wait()
        print(_("resolve dependency status:%s,%s")%(self.resolve_depend_status,",".join(self.remove_pkgs)))
        if self.resolve_depend_status and len(self.remove_pkgs)==0:
            pass
        else:
            self.Quit()   
        self.install_finish_status_event.clear()
        self.DistUpgradeForAuto(ACTION_INSTALL)
        self.loop.run()
        self.install_finish_status_event.wait()        
        print(_("install finish status:%s,%s")%(self.install_finish_status,",".join(self.install_finish_group)))
        return     
    
    def UpdateDetect(self):
        return self.update_interface.UpdateDetect()
    
    def DistUpgradeForAuto(self,mode):
        return self.update_interface.DistUpgradeForAuto(mode)
          
    def Quit(self):
        self.loop.quit()
        
if __name__ == "__main__":
    gettext.bindtextdomain("unattended-upgrades","/usr/share/locale")
    gettext.textdomain("unattended-upgrades")
    parser = OptionParser()
    parser.add_option("", "--download-only",
                      action="store_true", dest="download_only",
                      default=False,help="only download without install")
    parser.add_option("", "--install-only",
                      action="store_true", dest="install_only",
                      default=False,help="only install without download")
    (options, args) = parser.parse_args()
    print(options,args)
    systemupdater = SystemUpdater()
    if options.download_only:
        systemupdater.download()
    elif options.install_only:
        systemupdater.install()
    else:
        pass