/*
 * Copyright 2009-2010 The MICE Project Team.
 * Licensed under the MICE s.r.l.
 * End User License Agreement
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.micegroup.it/voila/license.html
 */
package it.mice.voila.runtime.mail.beans;

import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import it.mice.voila.runtime.mail.utils.MailUtils;
import it.mice.voila.runtime.util.VelocityContextUtils;

/**
 * Definisce un selettore di possibili desinatari di una mail.
 */
public final class MailSelector extends MailBaseBean {
	/**
	 * Serial version UID.
	 */
	private static final long serialVersionUID = 835688545L;
	/**
	 * Default logger.
	 */
	@SuppressWarnings("unused")
	private static Log logger = LogFactory.getLog(MailSelector.class);
	//
	// Declare entity attributes with accessor methods
	//
	/**
	 * String data type.
	 */
	private String mailSelectorId;
	/**
	 * String data type.
	 */
	private String mailSelectorDescription;
	/**
	 * String data type.
	 */
	private String mailSelectorScript;
	//
	// entity child attribute declarations
	//
	/**
	 * Riferimento all'entity list: SelectorPerTemplate. Associazione tra
	 * template e mail selectors
	 */
	private Collection<SelectorPerTemplate> theSelectorPerTemplate = new ArrayList<SelectorPerTemplate>();

	//
	// Constructor declaration
	//
	/**
	 * Costruttore vuoto per MailSelector. Istanzia un nuovo MailSelector
	 * completamente vuoto.
	 */
	public MailSelector() {
		super();
	}

	//
	// getters and setters
	//

	/**
	 * @return the mailSelectorId
	 */
	public String getMailSelectorId() {
		return mailSelectorId;
	}

	/**
	 * @param mailSelectorId the mailSelectorId to set
	 */
	public void setMailSelectorId(String mailSelectorId) {
		this.mailSelectorId = mailSelectorId;
	}

	/**
	 * @return the mailSelectorDescription
	 */
	public String getMailSelectorDescription() {
		return mailSelectorDescription;
	}

	/**
	 * @param mailSelectorDescription the mailSelectorDescription to set
	 */
	public void setMailSelectorDescription(String mailSelectorDescription) {
		this.mailSelectorDescription = mailSelectorDescription;
	}

	/**
	 * @return the mailSelectorScript
	 */
	public String getMailSelectorScript() {
		return mailSelectorScript;
	}

	/**
	 * @param mailSelectorScript the mailSelectorScript to set
	 */
	public void setMailSelectorScript(String mailSelectorScript) {
		this.mailSelectorScript = mailSelectorScript;
	}

	/**
	 * @return the theSelectorPerTemplate
	 */
	public Collection<SelectorPerTemplate> getTheSelectorPerTemplate() {
		return theSelectorPerTemplate;
	}

	/**
	 * @param theSelectorPerTemplate the theSelectorPerTemplate to set
	 */
	public void setTheSelectorPerTemplate(
			Collection<SelectorPerTemplate> theSelectorPerTemplate) {
		this.theSelectorPerTemplate = theSelectorPerTemplate;
	}
	
	//
	// other methods
	//

	public void afterPropertiesSet() throws Exception {
		setMailSelectorId(getBeanName());
		setMailSelectorScript(StringUtils.trimToEmpty(getMailSelectorScript()));
		if (logger.isInfoEnabled()) {
			logger.info("Defined mail selector: " + this);
		}
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	@Override
	public String toString() {
		return "MailSelector [mailSelectorId=" + mailSelectorId
				+ ", mailSelectorDescription=" + mailSelectorDescription
				+ ", mailSelectorScript=" + mailSelectorScript + "]";
	}

	/** Restituisce tutte le emails della sola parte istante principale.
	 * @param dataObject the dataObject.
	 * @param velocityEngine the velocityEngine.
	 * @return the result. 
	 */
	public Set<String> getSelectedEmails(Object dataObject, VelocityEngine velocityEngine) {
		VelocityContext context = new VelocityContext(VelocityContextUtils.getVelocityContextToolsMap());
		try {
			context.put("currentUser", MailUtils.getCurrentUserDetail());
		} catch (Exception e) {
			//There is no current user details, probably an anonymous user...
		}
		context.put("dataObject", dataObject);
		context.put("theSelectorPerTemplate", theSelectorPerTemplate);
		
		if (dataObject instanceof Map) {
			for (Iterator iterator = ((Map) dataObject).entrySet().iterator(); iterator.hasNext();) {
				Map.Entry<String, Object> entry = (Map.Entry<String, Object>) iterator.next();
				context.put(entry.getKey(), entry.getValue());
			}
		}
		String logString = "";
		StringWriter output = new StringWriter();

		try {
			velocityEngine.evaluate(context, output, logString, getMailSelectorScript());
		} catch (Exception e) {
			throw new RuntimeException("Errore durante la valutazione dello script del selector "
					+ this + ". L'errore è il seguente: "
					+ e.getLocalizedMessage());
		}
		String out = StringUtils.trimToEmpty(output.toString());
		String[] resultString = StringUtils.split(out, "\n;,");
		
		Set<String> result = new HashSet<String>();
		for (int i = 0; i < resultString.length; i++) {
			resultString[i] = StringUtils.trimToNull(resultString[i]);
			if (resultString[i] != null) {
				result.add(resultString[i]);
			}
		}
		return result;
	}

}
