# -*- mode: python; coding: utf-8 -*-

"""logging handlers
.. moduleauthor:: Arco Research Group
"""

import logging
from logging.handlers import SMTPHandler


class SMTP_SSLHandler(SMTPHandler):
    """
    A handler class which sends an SMTP email for each logging event.
    """
    def __init__(self, mailhost, fromaddr, toaddrs,
                 subject, credentials=None, ssl=False):

        SMTPHandler.__init__(self, mailhost, fromaddr, toaddrs,
                             subject, credentials)
        self.ssl = ssl

    def emit(self, record):
        """
        Emit a record.

        Format the record and send it to the specified addressees.
        """
        try:
            import smtplib
            from email.utils import formatdate

            port = self.mailport
            if not port:
                port = smtplib.SMTP_PORT

            smtp = smtplib.SMTP(self.mailhost, port)
            msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\nDate: %s\r\n\r\n%s" % (
                            self.fromaddr,
                            str.join(",", self.toaddrs),
                            self.getSubject(record),
                            formatdate(),
                            self.format(record))

            if self.ssl:
                smtp.ehlo()
                smtp.starttls()
                smtp.ehlo()

            if self.username:
                smtp.login(self.username, self.password)

            smtp.sendmail(self.fromaddr, self.toaddrs, msg.encode('utf-8'))
            smtp.close()
        except (KeyboardInterrupt, SystemExit):
            raise
        except:
            self.handleError(record)


class JabberHandler(logging.Handler):
     def __init__(self, account, to_id, log=None, lazy=True):
        ''' log: is a creator logger '''

        self.from_id, self.password = account
        self.to_id = to_id
        self.log = log if log is not None else logging.getLogger("JabberHandler")
        self.connected = False

        logging.Handler.__init__(self)

        if not lazy:
            self.connect()


     def connect(self):
         if self.connected:
             return

         self.xmpp = __import__('xmpp')

         jid = self.xmpp.protocol.JID(self.from_id)
         self.user = jid.getNode()
         self.server = jid.getDomain()

         self.log.debug("Connecting %s@%s" % (self.user, self.server))

         self.conn = self.xmpp.Client(self.server, debug=[])
         conres = self.conn.connect()

         if not conres:
             self.log.error("Unable to connect to server %s!" % self.server)
             return

         if conres != 'tls':
             self.log.warning("Unable to estabilish secure connection - TLS failed!")

         authres = self.conn.auth(self.user, self.password, resource=self.server)

         if not authres:
             self.log.error("Unable to authorize on %s - check login/password." % self.server)
             return

         if authres != 'sasl':
             self.log.warning("Unable to perform SASL auth os %s. Old authentication method used!" % self.server)

         self.conn.sendInitPresence(requestRoster=0)
         self.connected = True

     def emit(self, record):
         if not self.connected:
             self.connect()

#        try:
         self.conn.send(\
             self.xmpp.protocol.Message(
                 to   = self.to_id,
                 body = self.format(record)))
#        except:
#            self.handleError(record)


class NotifyHandler(logging.Handler):
    'A logging Handler to show using notification daemon'
    ICONS = {
        logging.CRITICAL: 'gtk-cancel',
        logging.ERROR:    'gtk-dialog-error',
        logging.WARNING:  'gtk-dialog-warning',
        logging.INFO:     'gtk-dialog-info',
        logging.DEBUG:    'gtk-execute',
        }


    def emit(self, record):
        import pynotify

        summary, message = record.getMessage().split('\n',1)
        icon = NotifyHandler.ICONS.get(record.levelno, 'gtk-dialog-question')

        notification = pynotify.Notification(summary, message, icon=icon)
        notification.show()


class ColorFormatter(logging.Formatter):
    "A formatter wich add support on logging for colors."

    codes = {\
        None:       (0, 0,   0), # default
        'DEBUG':    (0, 0,   2), # gray
        'INFO':     (0, 0,   0), # normal
        'WARNING':  (38,5, 208), # orange
        'ERROR':    (0, 1,  31), # red
        'CRITICAL': (0, 1, 101), # black with red background
        }

    def color(self, level=None):
        return (chr(27)+'[%d;%d;%dm') % self.codes[level]


    def format(self, record):
        retval = logging.Formatter.format(self, record)
        return self.color(record.levelname) + retval + self.color()


class CapitalLoggingFormatter(logging.Formatter):
    '''
    define variable "levelcapital" for message formating. You can do things like:
    [EE] foo bar
    '''

    def format(self, record):
        record.levelcapital = record.levelname[0]*2
        return logging.Formatter.format(self, record)
