from django.conf import settings
from django.core import mail
from email.MIMEText import MIMEText
from email.Header import Header
import smtplib, rfc822
from pycon.features.decorators import feature
from pycon.core import safe_utf8_encode, safe_ascii_encode

## email package will roll over to a different encoding if the default
## doesnt work.
DEFAULT_EMAIL_CHARSET = getattr(settings, 'DEFAULT_EMAIL_CHARSET',
                                settings.DEFAULT_CHARSET)
DEFAULT_EMAIL_SUBJECT_CHARSET = getattr(settings,
                                        'DEFAULT_EMAIL_SUBJECT_CHARSET',
                                        DEFAULT_EMAIL_CHARSET)
setattr(settings, 'DEFAULT_EMAIL_CHARSET', DEFAULT_EMAIL_CHARSET)
setattr(settings, 'DEFAULT_EMAIL_SUBJECT_CHARSET',
                  DEFAULT_EMAIL_SUBJECT_CHARSET)

class SafeMIMEText(mail.SafeMIMEText):
    def __setitem__(self, name, val):
        "Forbids multi-line headers, to prevent header injection."
        if name == "Subject":
            val = Header(val, DEFAULT_EMAIL_SUBJECT_CHARSET)
            return MIMEText.__setitem__(self, name, val)
        return mail.SafeMIMEText.__setitem__(self, name, val)


#mail.SafeMIMEText = SafeMIMEText

class EmailMessage(mail.EmailMessage):
    def __init__(self, replyto_email=None, *args, **kwdargs):
        super(EmailMessage, self).__init__(*args, **kwdargs)
        self.replyto_email=replyto_email
    def message(self):
        encoding = self.encoding or DEFAULT_EMAIL_CHARSET
        body = ''
        try:
            body = mail.smart_str(self.body, DEFAULT_EMAIL_CHARSET)
        except:
            ## RED_FLAG: massive hack!!!
            body = safe_utf8_encode(self.body)
        msg = SafeMIMEText(body, self.content_subtype, encoding)
        if self.attachments:
            body_msg = msg
            msg = mail.SafeMIMEMultipart(_subtype=self.multipart_subtype)
            if self.body:
                msg.attach(body_msg)
            for attachment in self.attachments:
                if isinstance(attachment, mail.MIMEBase):
                    msg.attach(attachment)
                else:
                    msg.attach(self._create_attachment(*attachment))
        msg['Subject'] = self.subject
        msg['From'] = self.from_email
        msg['To'] = ', '.join(self.to)
        msg['Date'] = mail.formatdate()
        msg['Message-ID'] = mail.make_msgid()
        if hasattr(settings, 'CONFERENCE_NAME'):
            msg['X-Conference-Name'] = getattr(settings, 'CONFERENCE_NAME')
        if self.bcc:
            msg['Bcc'] = ', '.join(self.bcc)
        if self.replyto_email:
            msg['Reply-To'] = self.replyto_email
        for name, value in self.extra_headers.items():
            msg[name] = value
        return msg

@feature('SendMassMail', disabled_func=0, auto_create_feat=True)
def send_mass_mail(datadicts, fail_silently=False,
                   auth_user=getattr(settings,'EMAIL_HOST_USER',None),
                   auth_password=getattr(settings,'EMAIL_HOST_PASSWORD',None)):
    """
    Given a datatuple of (subject, message, from_email, recipient_list), sends
    each message to each recipient list. Returns the number of e-mails sent.

    If from_email is None, the DEFAULT_FROM_EMAIL setting is used.
    If auth_user and auth_password are set, they're used to log in.
    """
    connection = mail.SMTPConnection(username=auth_user, password=auth_password,
                                     fail_silently=fail_silently)
    messages = [EmailMessage(**ddict) for ddict in datadicts]
    return connection.send_messages(messages)


@feature('SendMail', disabled_func=0, auto_create_feat=True)
def send_mail(subject='', message='', from_email=None, recipient_list=[],
              bcc=None, replyto_email=None, headers=None, fail_silently=False,
              auth_user=getattr(settings,'EMAIL_HOST_USER',None),
              auth_password=getattr(settings,'EMAIL_HOST_PASSWORD',None)):
    """
    Easy wrapper for sending a single message to a recipient list. All members
    of the recipient list will see the other recipients in the 'To' field.
    """
    connection = mail.SMTPConnection(username=auth_user, password=auth_password,
                                     fail_silently=fail_silently)
    return EmailMessage(replyto_email, subject, message, from_email,
                        recipient_list, connection=connection).send()

mail_admins = feature('MailAdmins', disabled_func=None,
                      auto_create_feat=True)(mail.mail_admins)

mail_managers = feature('MailManagers', disabled_func=None,
                        auto_create_feat=True)(mail.mail_managers)

#mail.mail_admins = mail_admins
#mail.mail_managers = mail_managers
