package eu.dnetlib.index;

import java.util.Map;

import com.google.common.collect.Maps;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;

/**
 * The Class IndexBackendEnumerator.
 */
public class IndexBackendEnumerator implements BeanFactoryAware {

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

	/**
	 * Gets the all.
	 *
	 * @return the all
	 */
	public Map<String, IndexBackendDescriptor> getAll() {
		return beanFactory.getBeansOfType(IndexBackendDescriptor.class);
	}

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

	/**
	 * {@inheritDoc}
	 *
	 * @see BeanFactoryAware#setBeanFactory(BeanFactory)
	 */
	@Override
	public void setBeanFactory(final BeanFactory beanFactory) throws BeansException {
		this.beanFactory = (ListableBeanFactory) beanFactory;

	}

	/**
	 * Gets the all protocols.
	 *
	 * @return the all protocols
	 */
	public Map<String, String> getAllProtocols() {
		final Map<String, String> res = Maps.newHashMap();
		for (IndexBackendDescriptor desc : getAll().values()) {
			String id = desc.getEndpoint().get(IndexBackendDescriptor.ID);
			String address = desc.getEndpoint().get(IndexBackendDescriptor.ADDRESS);
			res.put(id, address);
		}
		return res;
	}

	/**
	 * Gets the all service properties.
	 *
	 * @return the all service properties
	 */
	public Map<String, String> getAllServiceProperties() {
		final Map<String, String> res = Maps.newHashMap();
		for (IndexBackendDescriptor desc : getAll().values()) {
			String name = desc.getEndpoint().get(IndexBackendDescriptor.ID);
			if (name == null) throw new IllegalStateException("Missing field name");
			Map<String, String> currentProp = desc.getServiceProperties();
			for (String key : currentProp.keySet()) {
				// Append Prefix Name to each property key
				res.put(name + ":" + key, currentProp.get(key));
			}
		}
		return res;
	}

	@SuppressWarnings("unchecked")
	public <T extends IndexBackendDescriptor> T getDescriptor(final String identifier) {
		// TODO implement a faster access to the IndexBackendDescriptor
		for (IndexBackendDescriptor desc : getAll().values()) {
			String name = desc.getEndpoint().get(IndexBackendDescriptor.ID);
			if (name.equals(identifier)) return (T) desc;
		}
		return null;
	}

}
