/*
 *  Copyright 2011-2014 Eric F. Savage, code@efsavage.com
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
package com.ajah.email.data;

import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import lombok.extern.java.Log;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ajah.email.EmailMessage;
import com.ajah.email.EmailRecipient;
import com.ajah.util.AjahUtils;
import com.ajah.util.StringUtils;
import com.ajah.util.config.Config;
import com.ajah.util.data.format.EmailAddress;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.simpleemail.AWSJavaMailTransport;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailService;
import com.amazonaws.services.simpleemail.AmazonSimpleEmailServiceClient;
import com.amazonaws.services.simpleemail.model.ListVerifiedEmailAddressesResult;
import com.amazonaws.services.simpleemail.model.VerifyEmailAddressRequest;

/**
 * Manages the persistance and transport of email messages.
 * 
 * @author <a href="http://efsavage.com">Eric F. Savage</a>, <a
 *         href="mailto:code@efsavage.com">code@efsavage.com</a>.
 * 
 */
@Service
@Transactional(rollbackFor = Exception.class)
@Log
public class AmazonSESTransport implements EmailTransport {

	private static boolean isVerified(final EmailAddress emailAddress, final AmazonSimpleEmailService email, final ListVerifiedEmailAddressesResult verifiedEmails) {
		if (!verifiedEmails.getVerifiedEmailAddresses().contains(emailAddress.toString())) {
			email.verifyEmailAddress(new VerifyEmailAddressRequest().withEmailAddress(emailAddress.toString()));
			return false;
		}
		return true;
	}

	/**
	 * Sends a message through Amazon's SES service.
	 * 
	 * @param message
	 *            The message to send. Subject, from and to are required.
	 * @throws AddressException
	 *             If there is a problem with one of the email addresses.
	 * @throws MessagingException
	 *             If there is a problem with the transport of the message.
	 */
	@Override
	public void send(final EmailMessage message) throws AddressException, MessagingException {
		AjahUtils.requireParam(message, "message");
		AjahUtils.requireParam(message.getSubject(), "message.subject");
		AjahUtils.requireParam(message.getFrom(), "message.from");
		AjahUtils.requireParam(message.getRecipients(), "message.recipients");

		final AWSCredentials credentials = new BasicAWSCredentials(Config.i.get("aws.accessKey", null), Config.i.get("aws.secretKey", null));
		if (Config.i.getBoolean("aws.ses.verify", false)) {
			// Verification is active so we'll need to check that first
			final AmazonSimpleEmailService email = new AmazonSimpleEmailServiceClient(credentials);
			final ListVerifiedEmailAddressesResult verifiedEmails = email.listVerifiedEmailAddresses();
			boolean verified = true;
			if (!isVerified(message.getFrom(), email, verifiedEmails)) {
				log.warning("Sender " + message.getFrom() + " is not verified");
				verified = false;
			}
			for (final EmailRecipient emailRecipient : message.getRecipients()) {
				if (!isVerified(emailRecipient.getAddress(), email, verifiedEmails)) {
					log.warning("Recipient " + emailRecipient.getAddress() + " is not verified");
					verified = false;
				}
			}
			if (!verified) {
				throw new MessagingException("Message not sent because one or more addresses need to be verified");
			}
		}
		final Properties props = new Properties();
		props.setProperty("mail.transport.protocol", "aws");
		props.setProperty("mail.aws.user", credentials.getAWSAccessKeyId());
		props.setProperty("mail.aws.password", credentials.getAWSSecretKey());

		final Session session = Session.getInstance(props);

		final MimeMessage mimeMessage = new MimeMessage(session);
		mimeMessage.setFrom(new InternetAddress(message.getFrom().toString()));
		for (final EmailRecipient emailRecipient : message.getRecipients()) {
			switch (emailRecipient.getType()) {
			case BCC:
				mimeMessage.addRecipient(Message.RecipientType.BCC, new InternetAddress(emailRecipient.toString()));
				break;
			case CC:
				mimeMessage.addRecipient(Message.RecipientType.CC, new InternetAddress(emailRecipient.toString()));
				break;
			case TO:
				mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(emailRecipient.toString()));
				break;
			default:
				mimeMessage.addRecipient(Message.RecipientType.TO, new InternetAddress(emailRecipient.toString()));
				break;
			}
		}
		mimeMessage.setSubject(message.getSubject());
		final String htmlContent = message.getHtml();
		if (StringUtils.isBlank(htmlContent)) {
			// No HTML so we'll just send a plaintext message.
			mimeMessage.setText(message.getText());
		} else {
			final Multipart multiPart = new MimeMultipart("alternative");

			final BodyPart text = new MimeBodyPart();
			text.setText(message.getText());
			multiPart.addBodyPart(text);

			final BodyPart html = new MimeBodyPart();
			html.setContent(message.getHtml(), "text/html");
			multiPart.addBodyPart(html);

			mimeMessage.setContent(multiPart);
		}
		mimeMessage.saveChanges();

		final Transport transport = new AWSJavaMailTransport(session, null);
		transport.connect();
		transport.sendMessage(mimeMessage, null);
		transport.close();

	}

}

@@ -2116,17 +2116,8 @@
  */%0A
-@Service%0A
 @Tra

Remove from scan