#!/usr/bin/python

import dbus
import dbus.mainloop.glib 
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 
import dbus.service
import glib
import gobject
import logging
import os
import os.path
import re
import shutil
import string
import subprocess
import sys
import tempfile

import LanguageSelector.macros
import LanguageSelector.FontConfig

from LanguageSelector.utils import *

DATADIR="/usr/share/language-selector/"

class LanguageSelectorServer(dbus.service.Object):
    def __init__(self, bus=dbus.SystemBus(), datadir=DATADIR):
	    bus_name = dbus.service.BusName('com.ubuntu.LanguageSelector',
					    bus=bus)
	    dbus.service.Object.__init__(self, bus_name, '/')
            self._datadir = "/usr/share/language-selector/"
            self._re_locale = re.compile(r'^[\w.@:-]+$')

    def _authWithPolicyKit(self, sender, connection, priv):
        logging.debug("_authWithPolicyKit")
        system_bus = dbus.SystemBus()
        obj = system_bus.get_object("org.freedesktop.PolicyKit1",
                                    "/org/freedesktop/PolicyKit1/Authority",
                                    "org.freedesktop.PolicyKit1.Authority")
        policykit = dbus.Interface(obj, "org.freedesktop.PolicyKit1.Authority")
        info = dbus.Interface(connection.get_object('org.freedesktop.DBus',
                                              '/org/freedesktop/DBus/Bus',
                                              False),
                              'org.freedesktop.DBus')
        pid = info.GetConnectionUnixProcessID(sender)
        subject = ('unix-process',
                   { 'pid' : dbus.UInt32(pid, variant_level=1),
                     'start-time' : 0,
                   }
                  )
        details = { '' : '' }
        flags = dbus.UInt32(1) #   AllowUserInteraction = 0x00000001
        cancel_id = ''
        (ok, notused, details) = policykit.CheckAuthorization(
            subject, priv, details, flags, cancel_id)
        return ok

    @dbus.service.method(dbus_interface='com.ubuntu.LanguageSelector',
			 in_signature="s", 
			 out_signature="b",
                         connection_keyword='connection',
			 sender_keyword='sender')
    def SetSystemDefaultLanguageEnv(self, sysLanguage, sender, connection):
        """ 
        sysLanguage - the default system LANGUAGE (e.g. de)
        """
        logging.debug("SetSystemDefaultLanguage")
        if not self._re_locale.search(sysLanguage):
            logging.error('SetSystemDefaultLanguage: Invalid locale "%s", rejecting', sysLanguage)
            return False
        if not self._authWithPolicyKit(sender, connection, "com.ubuntu.languageselector.setsystemdefaultlanguage"):
            return False
        conffiles = ["/etc/default/locale", "/etc/environment"]
        findString = "LANGUAGE="
        setString = "LANGUAGE=\"%s\"\n" % sysLanguage
        find_string_and_replace(findString, setString, conffiles)
        # update fontconfig voodoo
        fc = LanguageSelector.FontConfig.FontConfigHack()
        defaultLanguageCode = sysLanguage.split(':')[0]
        if defaultLanguageCode in fc.getAvailableConfigs():
            subprocess.call(["fontconfig-voodoo", "-f",
                             "--set=%s" % defaultLanguageCode])
        else:
            subprocess.call(["fontconfig-voodoo","-f","--remove-current"])
        return True

    @dbus.service.method(dbus_interface='com.ubuntu.LanguageSelector',
			 in_signature="s", 
			 out_signature="b",
                         connection_keyword='connection',
			 sender_keyword='sender')
    def SetSystemDefaultLangEnv(self, sysLang, sender, connection):
        """ 
        sysLang: the default LANG (de_DE.UTF-8)
        """
        logging.debug("SetSystemDefaultLangEnv")
        if not self._re_locale.search(sysLang):
            logging.error('SetSystemDefaultLangEnv: Invalid locale "%s", rejecting', sysLang)
            return False
        if not self._authWithPolicyKit(sender, connection, "com.ubuntu.languageselector.setsystemdefaultlanguage"):
            return False
        conffiles = ["/etc/default/locale", "/etc/environment"]
        macr = LanguageSelector.macros.LangpackMacros(self._datadir, sysLang)
        findString = "LANG="
        setString = "LANG=\"%s\"\n" % macr["SYSLOCALE"]
        find_string_and_replace(findString, setString, conffiles)
        return True

    def _get_missing_pkgs(self, language):
        from LanguageSelector.CheckLanguageSupport import CheckLanguageSupport
        cl = CheckLanguageSupport(DATADIR)
        pkgs = cl.getMissingPackages(language, all=True)
        return pkgs

    @dbus.service.method(dbus_interface='com.ubuntu.LanguageSelector',
			 in_signature="s", 
			 out_signature="as",
                         connection_keyword='connection',
			 sender_keyword='sender')
    def GetMissingPackages(self, language, sender, connection):
        """ 
        Get the missing packages
        """
        logging.debug("GetMissingPackages")
        return self._get_missing_pkgs(language)

    @dbus.service.method(dbus_interface='com.ubuntu.LanguageSelector',
			 in_signature="s", 
			 out_signature="as",
                         connection_keyword='connection',
			 sender_keyword='sender')
    def GetMissingPackagesAsync(self, language, sender, connection):
        """ 
        Get the missing packages
        """
        logging.debug("GetMissingPackagesAsync")
        glib.timeout_add(10, self._get_missing_pkgs_async, language)

    def _get_missing_pkgs_async(self, language):
        pkgs = self._get_missing_pkgs(language)
        self.MissingLanguagePackages(pkgs)

    @dbus.service.signal(dbus_interface='com.ubuntu.LanguageSelector',
                         signature='as')
    def MissingLanguagePackages(self, missing_pkgs):
        pass

if __name__ == "__main__":
        # FIXME: use argparse
        if len(sys.argv) > 1 and sys.argv[1] == "--debug":
            logging.basicConfig(level=logging.DEBUG)
	server = LanguageSelectorServer()
	gobject.MainLoop().run()

