package eu.dnetlib.functionality.modular.ui.repositories;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Required;
import org.springframework.ui.ModelMap;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.gson.Gson;

import eu.dnetlib.data.collector.rmi.CollectorService;
import eu.dnetlib.data.collector.rmi.ProtocolDescriptor;
import eu.dnetlib.data.collector.rmi.ProtocolParameter;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.functionality.modular.ui.ModuleEntryPoint;
import eu.dnetlib.functionality.modular.ui.repositories.objects.VocabularyEntry;

public class AddRepoApiEntryPointController extends ModuleEntryPoint {

	private String datasourceTypeVocabulary;
	private String complianceVocabulary;
	private String contentDescriptionsVocabulary;
	private String protocolsVocabulary;

	@Resource
	private UniqueServiceLocator serviceLocator;

	@Resource
	private RepoUIUtils repoUIUtils;

	@Override
	protected void initialize(final ModelMap map, final HttpServletRequest request, final HttpServletResponse response) throws Exception {
		final Gson gson = new Gson();
		map.addAttribute("types", gson.toJson(repoUIUtils.fetchVocabularyTerms(datasourceTypeVocabulary)));
		map.addAttribute("compliances", gson.toJson(repoUIUtils.fetchVocabularyTerms(complianceVocabulary)));
		map.addAttribute("contentDescriptions", gson.toJson(repoUIUtils.fetchVocabularyTerms(contentDescriptionsVocabulary)));
		map.addAttribute("protocols", gson.toJson(listProtocols()));
	}

	private List<ProtocolDescriptor> listProtocols() throws ISLookUpException {
		final Map<String, List<ProtocolParameter>> mapParams = Maps.newHashMap();
		for (ProtocolDescriptor pd : serviceLocator.getService(CollectorService.class).listProtocols()) {
			mapParams.put(pd.getName().trim().toLowerCase(), pd.getParams());
		}

		return Lists.transform(repoUIUtils.fetchVocabularyTerms(protocolsVocabulary), new Function<VocabularyEntry, ProtocolDescriptor>() {

			@Override
			public ProtocolDescriptor apply(final VocabularyEntry e) {
				final ProtocolDescriptor pd = new ProtocolDescriptor();
				pd.setName(e.getName());
				if (mapParams.containsKey(e.getName().toLowerCase().trim())) {
					pd.setParams(mapParams.get(e.getName().toLowerCase().trim()));
				} else {
					pd.setParams(new ArrayList<ProtocolParameter>());
				}
				return pd;
			}

		});
	}

	public String getDatasourceTypeVocabulary() {
		return datasourceTypeVocabulary;
	}

	@Required
	public void setDatasourceTypeVocabulary(final String datasourceTypeVocabulary) {
		this.datasourceTypeVocabulary = datasourceTypeVocabulary;
	}

	public String getComplianceVocabulary() {
		return complianceVocabulary;
	}

	@Required
	public void setComplianceVocabulary(final String complianceVocabulary) {
		this.complianceVocabulary = complianceVocabulary;
	}

	public String getContentDescriptionsVocabulary() {
		return contentDescriptionsVocabulary;
	}

	@Required
	public void setContentDescriptionsVocabulary(final String contentDescriptionsVocabulary) {
		this.contentDescriptionsVocabulary = contentDescriptionsVocabulary;
	}

	public String getProtocolsVocabulary() {
		return protocolsVocabulary;
	}

	@Required
	public void setProtocolsVocabulary(final String protocolsVocabulary) {
		this.protocolsVocabulary = protocolsVocabulary;
	}

}
