# w.c.s. - web application for online forms
# Copyright (C) 2005-2010  Entr'ouvert
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.

import time
import email.Parser

from quixote import get_response, redirect
from quixote.directory import Directory
from quixote.html import htmltext, TemplateIO

from qommon import _
from qommon import errors
from qommon import misc
from qommon.bounces import Bounce
from qommon.backoffice.menu import html_top
from qommon.admin.menu import command_icon

from qommon.form import *
from qommon.misc import get_cfg

def get_email_type_label(type):
    from settings import EmailsDirectory
    return EmailsDirectory.emails_dict.get(type, {}).get('description')

class BouncePage(Directory):
    _q_exports = ['', 'delete']

    def __init__(self, component):
        self.bounce = Bounce.get(component)
        get_response().breadcrumb.append((component + '/', _('bounce')))


    def _q_index(self):
        html_top('bounces', title = _('Bounce'))
        r = TemplateIO(html=True)

        r += htmltext('<div class="form">')

        if self.bounce.email_type:
            r += htmltext('<div class="title">%s</div>') % _('Email Type')
            r += htmltext('<div class="StringWidget content">')
            r += _(get_email_type_label(self.bounce.email_type))
            r += htmltext('</div>')

        r += htmltext('<div class="title">%s</div>') % _('Arrival Time')
        r += htmltext('<div class="StringWidget content">')
        r += misc.localstrftime(time.localtime(self.bounce.arrival_time))
        r += htmltext('</div>')

        if self.bounce.addrs:
            r += htmltext('<div class="title">%s</div>') % _('Failed Addresses')
            r += htmltext('<div class="StringWidget content">')
            r += ', '.join(self.bounce.addrs)
            r += htmltext('</div>')

        if self.bounce.original_rcpts:
            r += htmltext('<div class="title">%s</div>') % _('Original Recipients')
            r += htmltext('<div class="StringWidget content">')
            r += ', '.join(self.bounce.original_rcpts)
            r += htmltext('</div>')

        r += htmltext('<div class="title">%s</div>') % _('Bounce Message')
        r += htmltext('<div class="StringWidget content">')
        r += htmltext('<pre style="max-height: 20em;">')
        r += self.bounce.bounce_message
        r += htmltext('</pre>')
        r += htmltext('</div>')

        if self.bounce.original_message:
            parser = email.Parser.Parser()

            msg = parser.parsestr(self.bounce.original_message)
            if msg.is_multipart():
                for m in msg.get_payload():
                    if m.get_content_type() == 'text/plain':
                        break
                else:
                    m = None
            elif msg.get_content_type() == 'text/plain':
                m = msg
            else:
                m = None

            r += htmltext('<div class="title">%s</div>') % _('Original Message')
            r += htmltext('<div class="StringWidget content">')
            r += _('Subject: ')
            subject, charset = email.Header.decode_header(msg['Subject'])[0]
            if charset:
                encoding = get_publisher().site_charset
                r += unicode(subject, charset).encode(encoding)
            else:
                r += subject
            r += htmltext('</div>')

            if m:
                r += htmltext('<div class="StringWidget content">')
                r += htmltext('<pre>')
                r += m.get_payload()
                r += htmltext('</pre>')
                r += htmltext('</div>')

        r += htmltext('</div>') # form
        return r.getvalue()


    def delete(self):
        form = Form(enctype='multipart/form-data')
        form.widgets.append(HtmlWidget('<p>%s</p>' % _(
                        'You are about to irrevocably delete this bounce.')))
        form.add_submit('delete', _('Submit'))
        form.add_submit('cancel', _('Cancel'))
        if form.get_widget('cancel').parse():
            return redirect('..')
        if not form.is_submitted() or form.has_errors():
            get_response().breadcrumb.append(('delete', _('Delete')))
            html_top('bounces', title = _('Delete Bounce'))
            r = TemplateIO(html=True)
            r += htmltext('<h2>%s</h2>') % _('Deleting Bounce')
            r += form.render()
            return r.getvalue()
        else:
            self.bounce.remove_self()
            return redirect('..')



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

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

    def is_visible(self, *args):
        return bool(get_cfg('emails', {}).get('bounce_handler') is True)

    def _q_index(self):
        html_top('bounces', title = _('Bounces'))

        bounces = Bounce.select(ignore_errors=True)
        bounces.sort(lambda x,y: cmp(x.arrival_time, y.arrival_time))

        r = TemplateIO(html=True)
        r += htmltext('<ul class="biglist">')
        for bounce in bounces:
            r += htmltext('<li>')
            r += htmltext('<strong class="label">')
            r += misc.localstrftime(time.localtime(bounce.arrival_time))
            if bounce.email_type:
                r += ' - '
                r += _(get_email_type_label(bounce.email_type))
            r += htmltext('</strong>')
            r += htmltext('<p class="details">')
            if bounce.addrs:
                r += ', '.join(bounce.addrs)
            r += htmltext('</p>')

            r += htmltext('<p class="commands">')
            r += command_icon('%s/' % bounce.id, 'view')
            r += command_icon('%s/delete' % bounce.id, 'remove', popup = True)
            r += htmltext('</p></li>')
        r += htmltext('</ul>')
        return r.getvalue()

    def _q_lookup(self, component):
        try:
            return BouncePage(component)
        except KeyError:
            raise errors.TraversalError()
