package eu.dnetlib.functionality.index;

import javax.xml.ws.Endpoint;

import org.antlr.stringtemplate.StringTemplate;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Required;

import com.google.common.collect.Iterables;

import eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
import eu.dnetlib.enabling.tools.AbstractBaseService;
import eu.dnetlib.enabling.tools.ServiceLocator;
import eu.dnetlib.enabling.tools.blackboard.NotificationHandler;
import eu.dnetlib.functionality.index.rmi.IndexService;
import eu.dnetlib.miscutils.datetime.DateUtils;
import eu.dnetlib.soap.EndpointReferenceBuilder;

public class IndexServiceMockImpl extends AbstractBaseService implements IndexService {
	/**
	 * logger.
	 */
	private static final Log log = LogFactory.getLog(IndexServiceMockImpl.class); // NOPMD by marko on 11/24/08 5:02 PM

	/**
	 * registry locator
	 */
	private ServiceLocator<ISRegistryService> registryLocator;

	/**
	 * notification handler.
	 */
	private NotificationHandler notificationHandler;

	/**
	 * index ds template.
	 */
	private StringTemplate indexDsTemplate;

	/**
	 * service endpoint.
	 */
	private Endpoint endpoint;

	/**
	 * endpoint builder.
	 */
	private EndpointReferenceBuilder<Endpoint> eprBuilder;

	/**
	 * Used to consume resultsets.
	 */
	private ResultSetClientFactory resultSetClientFactory;

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.tools.AbstractBaseService#notify(java.lang.String, java.lang.String, java.lang.String,
	 *      java.lang.String)
	 */
	@Override
	public void notify(final String subscriptionId, final String topic, final String isId, final String message) {
		log.info("mock index: " + message);

		getNotificationHandler().notified(subscriptionId, topic, isId, message);

	}

	/**
	 * Create a mock index and registers its service profile
	 * 
	 * @param format
	 *            md format
	 * @param interpretation
	 *            md interpretation
	 * @param layout
	 *            index layout
	 * @return service profile id
	 */
	public String createIndex(final String format, final String interpretation, final String layout) {

		// XXX: mini hack
		final StringTemplate template = new StringTemplate(indexDsTemplate.getTemplate());
		template.setAttribute("serviceUri", eprBuilder.getAddress(endpoint));
		template.setAttribute("format", format);
		template.setAttribute("interpretation", interpretation);
		template.setAttribute("layout", layout);

		try {
			return registryLocator.getService().registerProfile(template.toString());
		} catch (final ISRegistryException e) {
			throw new IllegalStateException(e);
		}
	}

	/**
	 * feed index.
	 * 
	 * @param idxId
	 *            index id
	 * @param epr
	 *            epr
	 */
	public void feedIndex(final String idxId, final String epr) {

		log.info("FEEDING index " + idxId + " with epr " + epr);

		Iterable<String> items = resultSetClientFactory.getClient(epr);
		dumpStore(items);

		int size = Iterables.size(items);
		final String now = DateUtils.now_ISO8601();

		final String querySize = "for $x in collection('')/RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + idxId + "']"
				+ " return update value $x//INDEX_SIZE with " + size;

		final String queryDate = "for $x in collection('')/RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + idxId + "']"
				+ " return update value $x//INDEX_LAST_UPDATE with '" + now + "'";

		try {
			registryLocator.getService().executeXUpdate(querySize);
			registryLocator.getService().executeXUpdate(queryDate);
		} catch (ISRegistryException e) {
			throw new IllegalStateException(e);
		}
	}

	private void dumpStore(Iterable<String> items) {

		log.info("FAKE indexing records");
		for (String record : items) {
			if (log.isDebugEnabled()) {
				log.debug("record: " + record);
			}
		}
		log.info("FAKE indexing done");

	}

	public NotificationHandler getNotificationHandler() {
		return notificationHandler;
	}

	@Required
	public void setNotificationHandler(final NotificationHandler notificationHandler) {
		this.notificationHandler = notificationHandler;
	}

	public ServiceLocator<ISRegistryService> getRegistryLocator() {
		return registryLocator;
	}

	@Required
	public void setRegistryLocator(final ServiceLocator<ISRegistryService> registryLocator) {
		this.registryLocator = registryLocator;
	}

	public StringTemplate getIndexDsTemplate() {
		return indexDsTemplate;
	}

	@Required
	public void setIndexDsTemplate(final StringTemplate indexDsTemplate) {
		this.indexDsTemplate = indexDsTemplate;
	}

	public Endpoint getEndpoint() {
		return endpoint;
	}

	@Required
	public void setEndpoint(final Endpoint endpoint) {
		this.endpoint = endpoint;
	}

	public EndpointReferenceBuilder<Endpoint> getEprBuilder() {
		return eprBuilder;
	}

	@Required
	public void setEprBuilder(final EndpointReferenceBuilder<Endpoint> eprBuilder) {
		this.eprBuilder = eprBuilder;
	}

	public ResultSetClientFactory getResultSetClientFactory() {
		return resultSetClientFactory;
	}

	@Required
	public void setResultSetClientFactory(ResultSetClientFactory resultSetClientFactory) {
		this.resultSetClientFactory = resultSetClientFactory;
	}

}
