# -*- coding: utf-8 -*-
from __future__ import unicode_literals

import os
import random
from unittest import TestCase
from email.mime.text import MIMEText
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from gramex.services.emailer import message, recipients, SMTPMailer
from nose.tools import eq_, assert_raises

folder = os.path.dirname(os.path.abspath(__file__))


class TestEmailer(TestCase):
    def eq(self, msg1, msg2):
        '''Compare 2 messages ensuring random boundary values are the same'''
        random.seed(0)
        msg1 = msg1.as_string()
        random.seed(0)
        msg2 = msg2.as_string()
        eq_(msg1, msg2)

    def test_recipients(self):
        def msg_eq(src, result):
            eq_(set(src), set(result))
        msg_eq(recipients(to='a@z'), ['a@z'])
        msg_eq(recipients(to='a@z,b@z'), ['a@z', 'b@z'])
        msg_eq(recipients(to=['a@z', 'b@z']), ['a@z', 'b@z'])
        msg_eq(recipients(to=['a@z,b@z', 'c@z']), ['a@z', 'b@z', 'c@z'])
        msg_eq(recipients(to='A <a@z>'), ['A <a@z>'])
        msg_eq(recipients(to='A <a@z>, B <b@z>'), ['A <a@z>', 'B <b@z>'])
        msg_eq(recipients(to='a@z,b@z', Cc='c@z'), ['a@z', 'b@z', 'c@z'])
        msg_eq(recipients(to='a@z', Cc='b@z,c@z'), ['a@z', 'b@z', 'c@z'])
        msg_eq(recipients(To='a@z', Bcc='b@z,c@z'), ['a@z', 'b@z', 'c@z'])
        msg_eq(recipients(TO='a@z', CC='b@z', BCC='c@z'), ['a@z', 'b@z', 'c@z'])

    def test_message(self):
        text = 'This is some text: 高兴'
        html = '<h1>Heading</h1>\n<p>This is a paragraph: 高兴</p>'
        msg = message(body=text)
        self.eq(message(body=text), MIMEText(text.encode('utf-8'), 'plain', 'utf-8'))
        self.eq(message(html=html), MIMEText(html.encode('utf-8'), 'html', 'utf-8'))

        msg = MIMEMultipart('alternative')
        msg.attach(MIMEText(text.encode('utf-8'), 'plain', 'utf-8'))
        msg.attach(MIMEText(html.encode('utf-8'), 'html', 'utf-8'))
        self.eq(message(body=text, html=html), msg)

    def test_attachment(self):
        img = os.path.join(folder, 'small-image.jpg')
        self.check_attachment(img)

        with open(img, 'rb') as handle:
            contents = handle.read()
        self.check_attachment({'content_type': 'image/jpeg', 'body': contents})
        self.check_attachment({'filename': img, 'body': contents})

    def check_attachment(self, img):
        msg = message(body='text', attachments=[img])
        img_part = list(msg.walk())[-1]
        eq_(img_part.get_content_type(), 'image/jpeg')
        if 'filename' in img:
            eq_(img_part.get_filename(), os.path.basename(img['filename']))

    def test_images(self):
        html = '高兴: <img src="cid:logo">'
        img = os.path.join(folder, 'small-image.jpg')
        msg = MIMEMultipart('related')
        msg.attach(MIMEText(html.encode('utf-8'), 'html', 'utf-8'))
        with open(img, 'rb') as handle:
            img_part = MIMEImage(handle.read())
            img_part.add_header('Content-ID', '<logo>')
            msg.attach(img_part)
        self.eq(message(html=html, images={'logo': img}), msg)

    def test_smtpmailer(self):
        with assert_raises(ValueError):
            SMTPMailer(type='any')          # unknown type
        with assert_raises(ValueError):
            SMTPMailer(type='smtp')         # no host
        with assert_raises(ValueError):
            SMTPMailer(type='smtps')        # no host
        # These do not raise an error
        SMTPMailer(type='gmail', email='', password='')
        SMTPMailer(type='yahoo', email='', password='')
        SMTPMailer(type='live', email='', password='')
        SMTPMailer(type='mandrill', email='', password='')
        SMTPMailer(type='smtp', host='hostname')
        SMTPMailer(type='smtps', host='hostname')

        # TODO: using stubs, test that:
        # - the email is sent to the correct host, port, email, password in above cases
        # - test SMTP with and without password as well
        # - test SMTPS, custom ports
