import random

from quixote import get_publisher, get_request, get_response, redirect
from quixote.directory import Directory

from menu import *

from qommon import logger

import authentic
from authentic import misc
from authentic.form import *
from authentic import identities


class ByIdentityDirectory(Directory):
    def _q_lookup(self, component):
        return ByIdentityPages(component)


class LoggerDirectory(Directory):
    _q_exports = ['', 'download', 'by_identity']

    by_identity = ByIdentityDirectory()

    def _q_traverse(self, path):
        get_response().breadcrumb.append(('logger/', _('Logs')))
        return Directory._q_traverse(self, path)

    def _q_index [html] (self):
        html_top('logger', title = _('Logs'))

        request = get_request()
        logfile = request.get_field('logfile', 'authentic.log')
        if not logfile.startswith(str('authentic.log')) or str('/') in str(logfile):
            return error_page('logger', _('Bad log file: %s') % logfile)
        logfilename = str(os.path.join(get_publisher().app_dir, logfile))

        if not os.path.exists(logfilename):
            _('Nothing to show')
        else:
            if logfile:
                '<a href="download?logfile=%s">%s</a>' % (logfile, _('Download Raw Log File'))
            else:
                '<a href="download">%s</a>' % _('Download Raw Log File')

            ids = {}
            store = identities.get_store()
            if hasattr(store, str('get_identity_for_log')):
                get_identity_for_log = store.get_identity_for_log
            else:
                get_identity_for_log = store.get_identity

            user_color_keys = {}
            last_date = None
            '<table id="logs">'
            '<thead> <tr>'
            ' <th>%s</th>' % _('Time')
            ' <th>%s</th>' % _('User')
            ' <th>%s</th>' % _('Message')
            '<tr></thead>'
            '<tbody>'
            for d in logger.parse_logstream(file(logfilename)):
                if not d:
                    continue
                user_color_key = d['user_id']
                if user_color_key == 'anonymous':
                    user_color_key += d['ip']
                if not user_color_keys.has_key(user_color_key):
                    user_color_keys[user_color_key] = ''.join(
                        ['%x' % random.randint(0xc, 0xf) for x in range(3)])
                '<tr class="level-%s" style="background: #%s;">' % (
                        d['level'].lower(), user_color_keys[user_color_key])
                if (last_date != d['date']):
                    ' <td class="time">%s&nbsp;%s</td>' % (d['date'], d['hour'][:-4])
                    last_date = d['date']
                else:
                    ' <td class="time">%s</td>' % (d['hour'][:-4])
                ip = d.get('ip', '')
                if d['user_id'] ==  'anonymous':
                    userlabel = _('Anonymous')
                elif d['user_id'] == 'unlogged':
                    userlabel = _('Unlogged')
                else:
                    if not ids.get(str(d['user_id'])):
                        try:
                            ids[str(d['user_id'])] = get_identity_for_log(d['user_id'])
                        except (KeyError, identities.IdentityStoreException):
                            ids[str(d['user_id'])] = _('Unknown') + ': ' + str(d['user_id'])
                    userlabel = htmltext(str(ids.get(str(d['user_id']), _('Unknown'))).replace(
                                str(' '), str('&nbsp;')))
                ' <td><span title=\'%s\'>%s</span></td>' % (ip, userlabel)
                ' <td class="message">%s</td>' % d['message']
                '</tr>'
            '</tbody>'
            '</table>'

        logfiles = [x for x in os.listdir(get_publisher().app_dir) \
                if x.startswith(str('authentic.log'))]
        if len(logfiles) > 1:
            options = []
            for lfile in logfiles:
                firstline = file(os.path.join(get_publisher().app_dir, lfile)).readline()
                d = logger.readline(firstline)
                if not d:
                    continue
                if logfile == lfile:
                    selected = 'selected="selected" '
                else:
                    selected = ''
                options.append({'selected': selected, 'lfile': lfile,
                        'date': '%s %s' % (d['date'], d['hour'])})

            '<form id="other-log-select">'
            _('Select another logfile:')
            '<select name="logfile">'
            options.sort(lambda x,y: cmp(x['date'], y['date']))
            options.reverse()
            for option in options:
                option['since'] = str(_('Since: %s') % option['date'])[:-4]
                '<option value="%(lfile)s"%(selected)s>%(since)s</option>' % option
            '</select>'
            '<input type="submit" value="%s" />' % _('Submit')

    def download(self):
        response = get_response()
        response.set_content_type('text/x-log', 'iso-8859-1')
        return open(get_publisher().get_app_logger_filename()).read()


class ByIdentityPages(Directory):
    _q_exports = ['']

    def __init__(self, component):
        try:
            self.identity = identities.get_store().get_identity(component)
        except KeyError:
            raise TraversalError()

    def _q_index [html] (self):
        html_top('logger', title = _('Logs'))
        '<h2>%s - %s</h2>' % (_('Identity'), self.identity)

        last_date = None
        '<table id="logs">'
        '<thead> <tr>'
        ' <th>%s</th>' % _('Time')
        ' <th>%s</th>' % _('Message')
        '<tr></thead>'
        '<tbody>'
        logfile = get_publisher().get_app_logger_filename()
        if logfile and os.path.exists(logfile):
            for d in logger.parse_logstream(file(logfile)):
                if not d:
                    continue
                if d['user_id'] != str(self.identity.id):
                    continue
                '<tr>'
                if (last_date != d['date']):
                    ' <td class="time">%s&nbsp;%s</td>' % (d['date'], d['hour'][:-4])
                    last_date = d['date']
                else:
                    ' <td class="time">%s</td>' % (d['hour'][:-4])
                ' <td><a href="%s">%s</a></td>' % (d['url'], d['message'])
                '</tr>'
        '</tbody>'
        '</table>'

