package eu.dnetlib.data.download;

import java.util.Map;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;

import com.google.common.collect.Maps;

import eu.dnetlib.data.download.rmi.DownloadPlugin;
import eu.dnetlib.data.download.rmi.DownloadPluginEnumerator;
import eu.dnetlib.data.download.rmi.DownloadServiceException;

/**
 * The Class DownloadPluginEnumeratorImpl.
 */
public class DownloadPluginEnumeratorImpl implements DownloadPluginEnumerator {

	/**
	 * bean factory.
	 */
	private ListableBeanFactory beanFactory;

	/*
	 * (non-Javadoc)
	 *
	 * @see eu.dnetlib.data.download.rmi.DownloadPluginEnumerator#getAll()
	 */
	@Override
	public Map<String, DownloadPlugin> getAll() {
		return beanFactory.getBeansOfType(DownloadPlugin.class);
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see eu.dnetlib.data.download.rmi.DownloadPluginEnumerator#getByProtocols()
	 */
	@Override
	public Map<String, DownloadPlugin> getByProtocols() {
		final Map<String, DownloadPlugin> res = Maps.newHashMap();
		for (DownloadPlugin cp : getAll().values()) {
			res.put(cp.getPluginName().toLowerCase(), cp);
		}
		return res;
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory)
	 */
	@Override
	public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
		this.beanFactory = (ListableBeanFactory) beanFactory;
	}

	/**
	 * Gets the bean factory.
	 *
	 * @return the bean factory
	 */
	public ListableBeanFactory getBeanFactory() {
		return beanFactory;
	}

	/**
	 * Get given DownloadPlugin or throws exception.
	 *
	 * @param protocol
	 *            the protocol
	 * @return the download plugin
	 * @throws eu.dnetlib.data.download.rmi.DownloadServiceException
	 *             the download service exception
	 */
	public DownloadPlugin get(final String protocol) throws DownloadServiceException {
		final DownloadPlugin plugin = getByProtocols().get(protocol.toLowerCase());
		if (plugin == null) throw new DownloadServiceException("plugin not found for name: " + protocol);
		return plugin;
	}

}
