package eu.dnetlib.data.hadoop;

import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.common.collect.Iterables;

import eu.dnetlib.rmi.enabling.ISLookUpException;
import eu.dnetlib.rmi.enabling.ISLookUpService;
import eu.dnetlib.rmi.enabling.ISRegistryException;
import eu.dnetlib.rmi.enabling.ISRegistryService;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.miscutils.datetime.DateUtils;

public class ISClient {

	private static final Log log = LogFactory.getLog(ISClient.class); // NOPMD by marko on 11/24/08 5:02 PM

	@Resource
	private UniqueServiceLocator serviceLocator;

	public String getJobProfile(final String jobName) throws ISLookUpException {
		return serviceLocator.getService(ISLookUpService.class).getResourceProfileByQuery(
				"/RESOURCE_PROFILE[.//RESOURCE_TYPE/@value = 'HadoopJobConfigurationDSResourceType' and .//HADOOP_JOB/@name='" + jobName + "']");
	}

	public String queryForServiceProperty(final String key) throws ISLookUpException {
		return getServiceConfigValue("for $x in /RESOURCE_PROFILE[.//RESOURCE_TYPE/@value='HadoopServiceResourceType'] return $x//SERVICE_PROPERTIES/PROPERTY[./@ key='"
				+ key + "']/@value/string()");
	}

	public void updateCountElement(final String jobName, final String element, final String delta) {
		final String xquery =
				"let $x := //RESOURCE_PROFILE[" + ".//RESOURCE_TYPE/@value='HadoopJobConfigurationDSResourceType' and .//HADOOP_JOB/@name='" + jobName
						+ "'], $tot := $x//STATUS/" + element + "/@value/number() " + delta + " return update replace $x//STATUS/" + element + " with <"
						+ element + " value='{$tot}' />";

		executeXUpdate(xquery);
	}

	public void updateDate(final String jobName) {
		log.info("increment last submission date for job: " + jobName);
		executeXUpdate("for $x in collection('')/RESOURCE_PROFILE["
				+ ".//RESOURCE_TYPE/@value='HadoopJobConfigurationDSResourceType' and .//HADOOP_JOB/@name='"
				+ jobName + "'] " + " return update value $x//LAST_SUBMISSION_DATE/@value with '" + DateUtils.now_ISO8601() + "' ");
	}

	private String getServiceConfigValue(final String xquery) throws ISLookUpException {
		log.debug("quering for service property: " + xquery);
		final List<String> urls = serviceLocator.getService(ISLookUpService.class).quickSearchProfile(xquery);
		if ((urls == null) || (urls.size() != 1))
			throw new IllegalStateException("unable to find unique service property, xquery: " + xquery);
		return Iterables.getOnlyElement(urls);
	}

	private boolean executeXUpdate(final String xupdate) {
		try {
			log.debug("running xupdate: " + xupdate);
			return serviceLocator.getService(ISRegistryService.class).executeXUpdate(xupdate);
		} catch (final ISRegistryException e) {
			log.error("unable to run xupdate: " + xupdate, e);
			return false;
		}
	}
}
