package eu.dnetlib.akka;

import org.springframework.beans.factory.FactoryBean;

import akka.dispatch.BoundedMailbox;
import akka.dispatch.Dispatchers;
import akka.dispatch.MailboxType;
import akka.dispatch.UnboundedMailbox;
import akka.util.DurationInt;

/**
 * Create an event based (thread pool) dispatcher for akka. 
 * 
 * <p>
 * This factory bean is useful to create an akka dispatcher from spring config, Until we migrate to Spring 3.0, we
 * cannot use akka-spring integration, which does the same job but better.
 * </p>
 * 
 * 
 * @author marko
 * 
 */
public class ExecutorDispatcherFactory implements FactoryBean {

	/**
	 * You can also setup the mailbox capacity size from here.
	 */
	private int mailboxCapacity = -1;

	/**
	 * Mailbox push timeout.
	 */
	private int pushTimeout = 10000;

	/**
	 * Threadpool executor parameter: corePoolSize.
	 */
	private int corePoolSize = 1;

	/**
	 * Threadpool executor parameter: maxPoolSize.
	 */
	private int maxPoolSize = 16;

	protected MailboxType getMailbox() {
		if (mailboxCapacity < 0)
			return new UnboundedMailbox(false);
		else
			return new BoundedMailbox(false, mailboxCapacity, new DurationInt(pushTimeout).milliseconds());
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.springframework.beans.factory.FactoryBean#getObject()
	 */
	@Override
	public Object getObject() throws Exception {
		return Dispatchers.newExecutorBasedEventDrivenDispatcher("single", Dispatchers.THROUGHPUT(), getMailbox()).setCorePoolSize(corePoolSize)
				.setMaxPoolSize(maxPoolSize).build();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.springframework.beans.factory.FactoryBean#getObjectType()
	 */
	@Override
	public Class<?> getObjectType() {
		return null;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see org.springframework.beans.factory.FactoryBean#isSingleton()
	 */
	@Override
	public boolean isSingleton() {
		return false;
	}

	public int getMailboxCapacity() {
		return mailboxCapacity;
	}

	public void setMailboxCapacity(int mailboxCapacity) {
		this.mailboxCapacity = mailboxCapacity;
	}

	public int getCorePoolSize() {
		return corePoolSize;
	}

	public void setCorePoolSize(int corePoolSize) {
		this.corePoolSize = corePoolSize;
	}

	public int getMaxPoolSize() {
		return maxPoolSize;
	}

	public void setMaxPoolSize(int maxPoolSize) {
		this.maxPoolSize = maxPoolSize;
	}

	public int getPushTimeout() {
		return pushTimeout;
	}

	public void setPushTimeout(int pushTimeout) {
		this.pushTimeout = pushTimeout;
	}

}
