#!/usr/bin/python


import gtk
import gtk.glade
import os
import sys
import pwd
import re

moiraClientName = "xmoira"
if os.path.exists("xmoira.glade"):
    gladeFile = "xmoira.glade"
else:
    gladeFile = "/usr/share/debathena-moira-gui/xmoira.glade"

import moira
from _moira import MoiraException
import mrclient

class XMoira():
    def __init__(self):
        self.running=False
        self.widgets = gtk.glade.XML(gladeFile)
        self.window = self.widgets.get_widget("mainWindow")
        self.widgets.signal_autoconnect(self)
        self.clientName = moiraClientName
        self.connected = False
        try:
            self.currentUser = mrclient.krb_user()
        except mrclient.MoiraClientException:
            self.errorDialog("Unable to obtain username from Kerberos.\nDo you have valid tickets?", True)
            sys.exit(255) # We're not in a main loop, don't call gtk.main_quit()
        self.window.show()
        self.widgets.get_widget("lblUserName").set_text("User: " + self.currentUser)
        self.staleTabs = {"tabChpobox": True,
                          "tabChfn": True,
                          "tabChsh": True}
        self.tabCallbacks = {"tabChpobox": self.refreshChpoboxTab,
                             "tabChfn": self.refreshChfnTab,
                             "tabChsh": self.refreshChshTab}

        self.radioBtnQueries = {"rbChpoboxPobox": ('spop', None),
                                "rbChpoboxSplit": ('spob', 'SPLIT'),
                                "rbChpoboxSmtp": ('spob', 'SMTP')}
        self.pageChanged(self.widgets.get_widget("nbMain"), None, 0)


    def errorDialog(self, errstr, fatal=False):
        button = gtk.BUTTONS_OK
        if fatal:
            button = gtk.BUTTONS_CLOSE
        msg = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL,
                                gtk.MESSAGE_ERROR, button,
                                "Error: %s" % errstr)
        msg.set_title("Error")
        msg.run()
        msg.destroy()

    def validateEmail(self, str):
        try:
            currUser = mrclient.krb_user()
        except mrclient.MoiraClientException, e:
            self.errorDialog(e.args[1])
            return None
        try:
            validatedStr = mrclient.validate_pobox_smtp(currUser, str)
        except mrclient.MoiraClientException, e:
            self.errorDialog(e.args[1])
            return None
        return validatedStr

    def applyChsh(self, button):
        print self.widgets.get_widget('cbChshUnixShell').child.get_text()
        print self.widgets.get_widget('cbChshWindowsShell').child.get_text()


    def applyChfn(self, button):
        argList = {}
        for textEntry in self.widgets.get_widget_prefix("entChfn"):
            mrfield = textEntry.name.replace('entChfn_', '')
            argList[mrfield] = textEntry.get_text()
        argList['login'] = self.currentUser
        result = None
        try: 
            result = moira.query('ufbl', None, **argList)
        except MoiraException, e:
            self.errorDialog(e.args[1])
        if result == []:
            msg = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL,
                                    gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
                                    "Your finger information has been updated.")
            msg.set_title("Confirmation")
            msg.run()
            msg.destroy()
            
        self.refreshChfnTab()
        
    def applyChpobox(self, button):
        for radioButton in self.widgets.get_widget_prefix("rbChpobox"):
            if radioButton.get_active():
                (query, type) = self.radioBtnQueries[radioButton.name]
                textEntry = self.widgets.get_widget(radioButton.name.replace("rb", "ent"))
                if type == None:
                    self.query(query, mrclient.krb_user())
                else:
                    if textEntry and not textEntry.get_text():
                        self.errorDialog("You did not enter an e-mail address")
                        return
                    validated = self.validateEmail(textEntry.get_text())
                    if not validated:
                        return
                    self.query(query, self.currentUser, type, validated)
                self.refreshChpoboxTab()


    def chpoboxToggleHandler(self, button):
        textEntry = self.widgets.get_widget(button.name.replace("rb", "ent"))
        if textEntry != None:
            textEntry.set_property("visible", button.get_active())

    def refreshChfnTab(self):
        gfbl = self.query('gfbl', self.currentUser)[0]
        for textEntry in self.widgets.get_widget_prefix("entChfn"):
            textEntry.set_text(gfbl[textEntry.name.replace('entChfn_', '')])
        self.widgets.get_widget('lblChfnLastUpdated').set_text("Last modified %s by %s" % (gfbl['modtime'], gfbl['modby'].replace('@ATHENA.MIT.EDU', '')))

    def refreshChshTab(self):
        gual = self.query('gual', self.currentUser)[0]
        self.widgets.get_widget('cbChshUnixShell').child.set_text(gual['shell'])
        self.widgets.get_widget('cbChshWindowsShell').child.set_text(gual['winconsoleshell'])


    def refreshChpoboxTab(self):
        gpob = self.query('gpob', self.currentUser)[0]
        english = " ".join((gpob['type'], gpob['address']))
        if gpob['type'] == "IMAP" or gpob['type'] == "EXCHANGE":
            english = "Your mail is not forwarded."
            self.widgets.get_widget("rbChpoboxPobox").set_active(True)
        if gpob['type'] == "SMTP":
            english = "Your mail is being forwarded to %s." % gpob['box']
            self.widgets.get_widget("rbChpoboxSmtp").set_active(True)
            self.widgets.get_widget("entChpoboxSmtp").set_text(gpob['box'])
        if gpob['type'] == "SPLIT":
            english = "Your mail is being split between your MIT account\nand %s." % gpob['box']
            self.widgets.get_widget("rbChpoboxSplit").set_active(True)
            self.widgets.get_widget("entChpoboxSplit").set_text(gpob['box'])
        self.widgets.get_widget("lblChpoboxCurrentSetting").set_text(english)

    def pageChanged(self, notebook, page, page_num):
        tabName = notebook.get_nth_page(page_num).name
        if not self.staleTabs[tabName]:
            return
        self.tabCallbacks[tabName]()
        self.staleTabs[tabName] = False

    def connect(self):
        if self.connected:
            return
        moira.connect()
        try:
            moira.auth(self.clientName)
        except moira.MoiraException, e:
            self.errorDialog("Unable to authenticate to Moira: %s" % (e.args[1]), True)
            if self.running:
                self.quit()
            else:
                sys.exit(255)
        self.connected = True

    def query(self, query, *argList):
        if not self.connected:
            self.connect()
        result = []
        try: 
            result = moira.query(query, *argList)
        except MoiraException, e:
            msg = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL,
                                    gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
                                    "Error: %s" % e.args[1])
            msg.set_title("Error")
            msg.run()
            msg.destroy()
        return result
            

    def run(self):
        self.running=True
        gtk.main()

    def quit(self, widget=None, event=None):
        gtk.main_quit()

if __name__ == "__main__":
    if not os.path.exists(gladeFile):
        print "Unable to load Glade file " + gladeFile
        sys.exit(255)
    xmoira = XMoira()
    xmoira.run()
