package eu.dnetlib.functionality.modular.ui.workflows.controllers;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

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

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.google.common.collect.Maps;
import com.google.gson.Gson;

import eu.dnetlib.msro.workflows.util.ValidNodeValuesFetcher;
import eu.dnetlib.msro.workflows.util.ValidNodeValuesFetcher.DnetParamValue;

@Controller
public class DnetParamValuesController {

	@Resource
	private List<ValidNodeValuesFetcher> validNodesFetchers;

	private static final Log log = LogFactory.getLog(DnetParamValuesController.class);

	@RequestMapping("/ui/**/wf_obtainValidValues.list")
	public void obtainValidValues(final HttpServletRequest request,
			final HttpServletResponse response,
			@RequestParam(value = "bean", required = true) final String bean) throws IOException {

		final ValidNodeValuesFetcher fetcher = findValidNodeValuesFetcher(bean);

		if (fetcher == null) {
			log.error("ValidNodeValuesFetcher not found: " + bean);
			sendResponse(response, new ArrayList<ValidNodeValuesFetcher.DnetParamValue>());
		} else {
			final Map<String, String> params = findParams(request);
			sendResponse(response, fetcher.evaluate(params));
		}
	}

	private ValidNodeValuesFetcher findValidNodeValuesFetcher(final String bean) {
		for (ValidNodeValuesFetcher fetcher : validNodesFetchers) {
			if (fetcher.getName().equals(bean)) { return fetcher; }
		}
		return null;
	}

	private Map<String, String> findParams(final HttpServletRequest request) {
		final Map<String, String> params = Maps.newHashMap();

		final Enumeration<?> e = request.getParameterNames();
		while (e.hasMoreElements()) {
			final String name = (String) e.nextElement();
			params.put(name, request.getParameter(name));
		}
		return params;
	}

	private void sendResponse(final HttpServletResponse response, final List<DnetParamValue> values) throws IOException {
		Collections.sort(values);
		
		response.setContentType("application/json;charset=UTF-8");
		
		IOUtils.copy(new StringReader(new Gson().toJson(values)), response.getOutputStream());
	}
}
