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 eu.dnetlib.enabling.is.registry.rmi.ISRegistryException;
import eu.dnetlib.enabling.is.registry.rmi.ISRegistryService;
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.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;

	/**
	 * {@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) {
		final String querySize = "for $x in collection('')/RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '"+idxId+"']" +
		" return update value $x//INDEX_SIZE with $x//INDEX_SIZE + 1";

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

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

	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;
	}


}
