/*
 * Copyright 2011 gitblit.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.gitblit.service;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Queue;
import java.util.UUID;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.regex.Pattern;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.SendFailedException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gitblit.IStoredSettings;
import com.gitblit.Keys;
import com.gitblit.models.Mailing;
import com.gitblit.utils.StringUtils;

/**
 * The mail service handles sending email messages asynchronously from a queue.
 *
 * @author James Moger
 *
 */
public class MailService implements Runnable {

	private final Logger logger = LoggerFactory.getLogger(MailService.class);

	private final Queue<Message> queue = new ConcurrentLinkedQueue<Message>();

	private final Session session;

	private final IStoredSettings settings;

	public MailService(IStoredSettings settings) {
		this.settings = settings;

		final String mailUser = settings.getString(Keys.mail.username, null);
		final String mailPassword = settings.getString(Keys.mail.password, null);
		final boolean smtps = settings.getBoolean(Keys.mail.smtps, false);
		final boolean starttls = settings.getBoolean(Keys.mail.starttls, false);
		boolean authenticate = !StringUtils.isEmpty(mailUser) && !StringUtils.isEmpty(mailPassword);
		String server = settings.getString(Keys.mail.server, "");
		if (StringUtils.isEmpty(server)) {
			session = null;
			return;
		}
		int port = settings.getInteger(Keys.mail.port, 25);
		boolean isGMail = false;
		if (server.equals("smtp.gmail.com")) {
			port = 465;
			isGMail = true;
		}

		Properties props = new Properties();
		props.setProperty("mail.smtp.host", server);
		props.setProperty("mail.smtp.port", String.valueOf(port));
		props.setProperty("mail.smtp.auth", String.valueOf(authenticate));
		props.setProperty("mail.smtp.auths", String.valueOf(authenticate));
		props.setProperty("mail.smtp.starttls.enable", String.valueOf(starttls));

		if (isGMail || smtps) {
			props.setProperty("mail.smtp.starttls.enable", "true");
			props.put("mail.smtp.socketFactory.port", String.valueOf(port));
			props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
			props.put("mail.smtp.socketFactory.fallback", "false");
		}

		if (!StringUtils.isEmpty(mailUser) && !StringUtils.isEmpty(mailPassword)) {
			// SMTP requires authentication
			session = Session.getInstance(props, new Authenticator() {
				@Override
				protected PasswordAuthentication getPasswordAuthentication() {
					PasswordAuthentication passwordAuthentication = new PasswordAuthentication(
							mailUser, mailPassword);
					return passwordAuthentication;
				}
			});
		} else {
			// SMTP does not require authentication
			session = Session.getInstance(props);
		}
	}

	/**
	 * Indicates if the mail executor can send emails.
	 *
	 * @return true if the mail executor is ready to send emails
	 */
	public boolean isReady() {
		return session != null;
	}

	/**
	 * Create a message.
	 *
	 * @param mailing
	 * @return a message
	 */
	public Message createMessage(Mailing mailing) {
		if (mailing.subject == null) {
			mailing.subject = "";
		}

		if (mailing.content == null) {
			mailing.content = "";
		}

		Message message = new MailMessageImpl(session, mailing.id);
		try {
			String fromAddress = settings.getString(Keys.mail.fromAddress, null);
			if (StringUtils.isEmpty(fromAddress)) {
				fromAddress = "gitblit@gitblit.com";
			}
			InternetAddress from = new InternetAddress(fromAddress, mailing.from == null ? "Gitblit" : mailing.from);
			message.setFrom(from);

			Pattern validEmail = Pattern
					.compile("^([a-zA-Z0-9_\\-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([a-zA-Z0-9\\-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$");

			// validate & add TO recipients
			List<InternetAddress> to = new ArrayList<InternetAddress>();
			for (String address : mailing.toAddresses) {
				if (StringUtils.isEmpty(address)) {
					continue;
				}
				if (validEmail.matcher(address).find()) {
					try {
						to.add(new InternetAddress(address));
					} catch (Throwable t) {
					}
				}
			}

			// validate & add CC recipients
			List<InternetAddress> cc = new ArrayList<InternetAddress>();
			for (String address : mailing.ccAddresses) {
				if (StringUtils.isEmpty(address)) {
					continue;
				}
				if (validEmail.matcher(address).find()) {
					try {
						cc.add(new InternetAddress(address));
					} catch (Throwable t) {
					}
				}
			}

			if (settings.getBoolean(Keys.web.showEmailAddresses, true)) {
				// full disclosure of recipients
				if (to.size() > 0) {
					message.setRecipients(Message.RecipientType.TO,
							to.toArray(new InternetAddress[to.size()]));
				}
				if (cc.size() > 0) {
					message.setRecipients(Message.RecipientType.CC,
							cc.toArray(new InternetAddress[cc.size()]));
				}
			} else {
				// everyone is bcc'd
				List<InternetAddress> bcc = new ArrayList<InternetAddress>();
				bcc.addAll(to);
				bcc.addAll(cc);
				message.setRecipients(Message.RecipientType.BCC,
						bcc.toArray(new InternetAddress[bcc.size()]));
			}

			message.setSentDate(new Date());
			// UTF-8 encode
			message.setSubject(MimeUtility.encodeText(mailing.subject, "utf-8", "B"));

			MimeBodyPart messagePart = new MimeBodyPart();
			messagePart.setText(mailing.content, "utf-8");
			//messagePart.setHeader("Content-Transfer-Encoding", "quoted-printable");

			if (Mailing.Type.html == mailing.type) {
				messagePart.setHeader("Content-Type", "text/html; charset=\"utf-8\"");
			} else {
				messagePart.setHeader("Content-Type", "text/plain; charset=\"utf-8\"");
			}

			MimeMultipart multiPart = new MimeMultipart();
			multiPart.addBodyPart(messagePart);

			// handle attachments
			if (mailing.hasAttachments()) {
				for (File file : mailing.attachments) {
					if (file.exists()) {
						MimeBodyPart filePart = new MimeBodyPart();
						FileDataSource fds = new FileDataSource(file);
						filePart.setDataHandler(new DataHandler(fds));
						filePart.setFileName(fds.getName());
						multiPart.addBodyPart(filePart);
					}
				}
			}

			message.setContent(multiPart);

		} catch (Exception e) {
			logger.error("Failed to properly create message", e);
		}
		return message;
	}

	/**
	 * Returns the status of the mail queue.
	 *
	 * @return true, if the queue is empty
	 */
	public boolean hasEmptyQueue() {
		return queue.isEmpty();
	}

	/**
	 * Queue's an email message to be sent.
	 *
	 * @param message
	 * @return true if the message was queued
	 */
	public boolean queue(Message message) {
		if (!isReady()) {
			return false;
		}
		try {
			message.saveChanges();
		} catch (Throwable t) {
			logger.error("Failed to save changes to message!", t);
		}
		queue.add(message);
		return true;
	}

	@Override
	public void run() {
		if (!queue.isEmpty()) {
			if (session != null) {
				// send message via mail server
				List<Message> failures = new ArrayList<Message>();
				Message message = null;
				while ((message = queue.poll()) != null) {
					try {
						if (settings.getBoolean(Keys.mail.debug, false)) {
							logger.info("send: '" + StringUtils.trimString(message.getSubject(), 60)
									    + "' to:" + StringUtils.trimString(Arrays.toString(message.getAllRecipients()), 300));
						}
						Transport.send(message);
					} catch (SendFailedException sfe) {
						if (settings.getBoolean(Keys.mail.debug, false)) {
							logger.error("Failed to send message: {}", sfe.getMessage());
							logger.info("   Invalid addresses: {}", Arrays.toString(sfe.getInvalidAddresses()));
							logger.info("   Valid sent addresses: {}", Arrays.toString(sfe.getValidSentAddresses()));
							logger.info("   Valid unset addresses: {}", Arrays.toString(sfe.getValidUnsentAddresses()));
							logger.info("", sfe);
						}
						else {
							logger.error("Failed to send message: {}", sfe.getMessage(), sfe.getNextException());
						}
						failures.add(message);
					} catch (Throwable e) {
						logger.error("Failed to send message", e);
						failures.add(message);
					}
				}

				// push the failures back onto the queue for the next cycle
				queue.addAll(failures);
			}
		}
	}

	public void sendNow(Message message) throws Exception {
		Transport.send(message);
	}

	private static class MailMessageImpl extends MimeMessage {

		final String id;

		MailMessageImpl(Session session, String id) {
			super(session);
			this.id = id;
		}

		@Override
		protected void updateMessageID() throws MessagingException {
			if (!StringUtils.isEmpty(id)) {
				String hostname = "gitblit.com";
				String refid = "<" + id + "@" + hostname + ">";
				String mid = "<" + UUID.randomUUID().toString() + "@" + hostname + ">";
				setHeader("References", refid);
				setHeader("In-Reply-To", refid);
				setHeader("Message-Id", mid);
			}
		}
	}
}
