import logging

from django.core import mail
from django.contrib.sites.models import Site
from django.conf import settings
from django.template import loader, Context
from django.contrib.auth import get_user_model

class MassMailer(object):
    """
    This Class will send E-Mails via an SMTP Connection to multiple recipients.
    Each E-Mail will be send individually and can be personalized.
    It will be send as HTML and Plain-Text Message.
    """
    context = {}
    headers = {}
    subject = None
    txt_template = None
    html_template = None

    def __init__(self, subject=None, template=None, context=None):
        self.USER_MODEL = get_user_model()
        self.mail_queue = set()
        self.recipients = set()
        self.subject = subject
        self.template = 'email'
        self.context = context
        self.log = logging.getLogger('maillog')

    def open_smtp_connection(self):
        try:
            self.smtp_connection = mail.get_connection(fail_silently=False)
            self.smtp_connection.open()
            self.mail_counter = 0
        except:
            self.log.error('Connection to SMTP server failed. Giving up!')
            raise False
        else:
            self.log.debug('Connected to SMTP server.')
            return True

    def close_smtp_connection(self):
        self.smtp_connection.close()
        self.log.debug("closed the SMTP connection. I'm done")

    def add_recipient(self, recipient):
        if isinstance(recipient, self.USER_MODEL):
            self.recipients.add(recipient)
        else:
            self.log.warn('%s is not a User Object!', recipient)

    def add_recipients(self, user_list):
        for user in user_list:
            if isinstance(user, self.USER_MODEL):
                self.log.debug('Adding %s as Recipient' % user)
                self.recipients.add(user)
            else:
                self.log.warn('%s is not a User Object!', user)

    def process_mails(self):
        mail_context = Context(self.context)
        mail_context['site'] = Site.objects.get_current()

        self.txt_template = loader.get_template(self.txt_template)
        if self.html_template:
            self.html_template = loader.get_template(self.html_template)

        for recipient in self.recipients:
            mail_context['recipient'] = recipient
            mail_to = "%s %s <%s>" % (recipient.first_name,
                                      recipient.last_name, recipient.email)
            message = mail.EmailMultiAlternatives(
                subject=self.subject,
                body=self.txt_template.render(mail_context),
                to=(mail_to,),
                headers=self.headers
            )
            if self.html_template:
                message.attach_alternative(
                    self.html_template.render(mail_context), "text/html"
                )
            self.mail_queue.add(message)

    def set_header(self, name, value):
        self.headers[name] = value

    def send(self):
        """
        Process the E-Mails and send them
        """
        self.process_mails()
        if len(self.mail_queue) == 0:
            self.log.info('No recipients for eMail "%s", bye!', self.subject)
            return True
        else:
            self.log.info('Sending eMail "%s" to %d people', self.subject,
                          len(self.mail_queue))
            self.log.debug(self.recipients)

        self.open_smtp_connection()
        for mail in self.mail_queue:
            try:
                mail.send()
            except:
                self.log.warn("Mail failed for: %s", mail.to)
            else:
                self.log.info("Mail sent successful to: %s" % mail.to)
        self.close_smtp_connection()
