import smtplib
import socket

from email.MIMEText import MIMEText
from email.MIMEMultipart import MIMEMultipart
from email.Header import Header

try:
    import docutils
    import docutils.core
except ImportError:
    docutils = None

from quixote import get_request, get_publisher

import errors
import misc
import logger

def email(subject, mail_body, email_rcpt, replyto = None, bcc = None,
        exclude_current_user = False, email_type = None, want_html = True):
    get_publisher().reload_cfg()
    emails_cfg = get_publisher().cfg.get('emails', {})

    mail_body = str(mail_body)
    htmlmail = None
    if want_html:
        try:
            htmlmail = docutils.core.publish_string(mail_body, writer_name="html",
                    settings_overrides = {'input_encoding': 'iso-8859-15',
                        'output_encoding': 'iso-8859-15'})
        except:
            pass

    msg = MIMEMultipart(_charset = 'iso-8859-15', _subtype = 'alternative')
    msg['Subject'] = Header(subject, 'iso-8859-15')
    if type(email_rcpt) is list:
        msg['To'] = ', '.join(email_rcpt)
    else:
        msg['To'] = email_rcpt
    msg['From'] = emails_cfg.get('from', 'noreply@entrouvert.com')
    if emails_cfg.get('reply_to'):
        msg['Reply-To'] = emails_cfg.get('reply_to')
    if replyto:
        msg['Reply-To'] = replyto

    msg.preamble = ''
    msg.epilogue = ''
    msg.attach(MIMEText(mail_body, _charset = 'iso-8859-15'))

    if htmlmail:
        msg.attach(MIMEText(htmlmail, _subtype = 'html', _charset = 'iso-8859-15'))

    if type(email_rcpt) is list:
        rcpts = email_rcpt[:]
    else:
        rcpts = [msg['To']]
    if bcc:
        rcpts += bcc

    if exclude_current_user:
        user = get_request().user
        if user and user.email and user.email in rcpts:
            rcpts.remove(user.email)

    if len(rcpts) == 0:
        return

    try:
        s = smtplib.SMTP(emails_cfg.get('smtp_server', None) or 'localhost')
    except socket.error:
        # XXX: write message in a queue somewhere?
        logger.error('Failed to connect to SMTP server')
        raise errors.EmailError()
    if not s.sock:
        logger.error('Failed to connect to SMTP server')
        raise errors.EmailError()

    if emails_cfg.get('bounce_handler'):
        server_name = get_request().environ.get('SERVER_NAME').strip()
        token = tokens.Token(7 * 86400)
        token.type = 'email-bounce'
        token.email_rcpts = rcpts
        token.email_message = msg.as_string()
        token.email_type = email_type
        token.store()
        msg_from = '%s-bounces+%s@%s' % (get_publisher().APP_NAME, token.id, server_name)
    else:
        msg_from = msg['From']
    try:
        s.sendmail(msg_from, rcpts, msg.as_string())
    except smtplib.SMTPRecipientsRefused:
        logger.error('Failed to send mail to %s' % ', '.join(rcpts))
    s.close()
