package it.mice.voila.runtime.mail.senders;

import it.mice.voila.runtime.mail.beans.MailConfig;
import it.mice.voila.runtime.mail.beans.MailTemplate;
import it.mice.voila.runtime.mail.utils.MailUtils;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.StringWriter;
import java.util.Map;

import javax.mail.MessagingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
/**
 * Mime mail sender implementation used by mail managers that implement all java mail aspects and perform concrete mail send activity.
 */
public class MimeMailSenderImpl extends JavaMailSenderImpl {
	/**
	 * Action default logger
	 */
	private static Log logger = LogFactory.getLog(MimeMailSenderImpl.class);
	
	private MailConfig mailConfig;
	
	private VelocityEngine velocityEngine;
	private boolean testMode = false;
	
	private boolean useSPA = false;
	
	/**
	 * Getter per la proprietà mailConfig.
	 * @return la proprietà mailConfig
	 */
	public MailConfig getMailConfig() {
		return mailConfig;
	}
	/**
	 * Setter per la proprietà mailConfig.
	 * @param mailConfig la proprietà mailConfig da settare
	 */
	public void setMailConfig(MailConfig mailConfig) {
		this.mailConfig = mailConfig;
	}
	
	public VelocityEngine getVelocityEngine() {
		return velocityEngine;
	}
	public void setVelocityEngine(VelocityEngine velocityEngine) {
		this.velocityEngine = velocityEngine;
	}

	public boolean isTestMode() {
		return testMode;
	}
	public void setTestMode(boolean testMode) {
		this.testMode = testMode;
	}
	
	/**
	 * Getter per la proprietà useSPA.
	 * @return la proprietà useSPA
	 */
	public boolean isUseSPA() {
		return useSPA;
	}
	/**
	 * Setter per la proprietà useSPA.
	 * @param useSPA la proprietà useSPA da settare
	 */
	public void setUseSPA(boolean useSPA) {
		this.useSPA = useSPA;
	}
	public MimeMailSenderImpl() {
		super();
	}
	
	public void sendEmails(MailTemplate template, Map objectMap, Map allegati) {
		if (!getMailConfig().isEnabled()) {
			logger.warn("Sistema di mailing disabilitato. Prego configurare la sezione Configurazione->Posta elettronica->Mail Config");
			return;
		}

		MimeMessageHelper messageHelper = MailUtils.createNewMimeMessageHelper(template, this, objectMap, allegati);
		
		try {
			if (testMode) {
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				messageHelper.getMimeMessage().writeTo(baos);
				logger.info("Test mail message:\n " + baos.toString());
			} else {
				if (messageHelper.getMimeMessage().getAllRecipients() != null && messageHelper.getMimeMessage().getAllRecipients().length > 0) {
					send(messageHelper.getMimeMessage());
				} else {
					throw new RuntimeException("Nessun destinatario specificato per l'invio della mail. Invio non effettuato.");
					//logger.warn("Nessun destinatario specificato per l'invio della mail. Invio non effettuato.");
				}
			}
		} catch (Exception e) {
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			try {
				messageHelper.getMimeMessage().writeTo(baos);
				logger.warn("Unable to send email, reason: " + e.getMessage());
				logger.warn("Mail RFC output:");
				logger.warn(baos.toString());
			} catch (Exception e1) {
		    	throw new RuntimeException(e);
			}
	    	throw new RuntimeException(e);
		}
	}
}
