##############################################################################
#
# Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE
#
##############################################################################
"""SMTP mail objects for Japanese  """
__version__ = "0.3"

from email.Header import Header
from Products.MailHost import MailHost
from Products.MailHost.MailHost import MailHostError, _encode, _mungeHeaders
import rfc822, string, types
from cStringIO import StringIO
from DateTime import DateTime

def sendTemplate(trueself, self, messageTemplate,
                 statusTemplate=None, mto=None, mfrom=None,
                 encode=None, REQUEST=None):
    'render a mail template, then send it...'
    mtemplate = getattr(self, messageTemplate)
    messageText = mtemplate(self, trueself.REQUEST)
    if trueself.title:
        messageText = unicode(messageText, trueself.title, 'replace').encode('iso-2022-jp', 'replace')
        if mto:
            mto=unicode(mto, trueself.title, 'replace').encode('iso-2022-jp', 'replace')
        if mfrom:
            mfrom=unicode(mfrom, trueself.title, 'replace').encode('iso-2022-jp', 'replace')
        messageText, mto, mfrom = _jp_mungeHeaders( messageText, mto, mfrom)
    else:
        messageText, mto, mfrom = _mungeHeaders( messageText, mto, mfrom)
    messageText=_encode(messageText, encode)
    self._send(mfrom, mto, messageText)

    if not statusTemplate: return "SEND OK"

    try:
        stemplate=getattr(self, statusTemplate)
        return stemplate(self, trueself.REQUEST)
    except:
        return "SEND OK"

MailHost.MailHost.sendTemplate=sendTemplate


def send(self, messageText, mto=None, mfrom=None, subject=None,
         encode=None):

    if self.title:
        messageText = unicode(messageText, self.title, 'replace').encode('iso-2022-jp', 'replace')
        if mto:
            mto=unicode(mto, self.title, 'replace').encode('iso-2022-jp', 'replace')
        if mfrom:
            mfrom=unicode(mfrom, self.title, 'replace').encode('iso-2022-jp', 'replace')
        if subject:
            subject=unicode(subject, self.title, 'replace').encode('iso-2022-jp', 'replace')
        messageText, mto, mfrom = _jp_mungeHeaders( messageText, mto, mfrom, subject)
    else:
        messageText, mto, mfrom = _mungeHeaders( messageText, mto, mfrom, subject)
    messageText = _encode(messageText, encode)
    self._send(mfrom, mto, messageText)

MailHost.MailHost.send=send


def _jp_mungeHeaders( messageText, mto=None, mfrom=None, subject=None):
    """Sets missing message headers, and deletes Bcc.
       returns fixed message, fixed mto and fixed mfrom"""
    mfile=StringIO(messageText.strip())
    mo=rfc822.Message(mfile)

    # Parameters given will *always* override headers in the messageText.
    # This is so that you can't override or add to subscribers by adding them to
    # the message text.
    if subject:
        mo['Subject'] = subject
    elif not mo.getheader('Subject'):
        mo['Subject'] = '[No Subject]'

    if mto:
        if isinstance(mto, types.StringType):
            mto=map(lambda x:x.strip(), mto.split(','))
        if not mo.getheader('To'):
            mo['To'] = ','.join(mto)
    else:
        if not mo.getheader('To'):
            raise MailHostError,"Message missing SMTP Header 'To'"
        mto = map(lambda x:x.strip(), mo['To'].split(','))
        if mo.getheader('Cc'):
            mto = mto + map(lambda x:x.strip(), mo['Cc'].split(','))
        if mo.getheader('Bcc'):
            mto = mto + map(lambda x:x.strip(), mo['Bcc'].split(','))

    if mfrom:
        mo['From'] = mfrom
    else:
        if mo.getheader('From') is None:
            raise MailHostError,"Message missing SMTP Header 'From'"
        mfrom = mo['From']

    if mo.getheader('Bcc'):
        mo.__delitem__('Bcc')

    if not mo.getheader('Date'):
        mo['Date'] = DateTime().rfc822()

    if mo.getheader('Subject'):
        mo['Subject'] = _enc_jp_header(mo['Subject'])
    if mo.getheader('From'):
        mo['From'] =  _enc_jp_header(mo['From'])
    if mo.getheader('To'):
        mo['To'] =  _enc_jp_header(mo['To'])
    if mo.getheader('Cc'):
        mo['Cc'] =  _enc_jp_header(mo['Cc'])
    mfrom =  _enc_jp_header(mfrom)
    mto = [_enc_jp_header(s) for s in mto]

    mo.rewindbody()
    finalmessage = mo
    finalmessage = mo.__str__() + '\n' + mfile.read()
    mfile.close()
    return finalmessage, mto, mfrom

def _enc_jp_header(src):
    if string.find(src, chr(033)) < 0:
        return src
    dest = ''
    for f in string.split(src, chr(033)):
        if f[:2] == r'$@' or f[:2] == r'$B':
            dest += str(Header(chr(033) + f, 'iso-2022-jp'))
        elif f[:2] == r'(B' or f[:2] == r'(J':
            dest += f[2:]
    return dest

