package eu.dnetlib.enabling.manager.msro;

import java.util.List;

import javax.annotation.Resource;

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

import com.googlecode.sarasvati.GraphProcess;
import com.googlecode.sarasvati.env.Env;

import eu.dnetlib.data.information.MDStoreDataSinkSourceDescriptorGenerator;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpDocumentNotFoundException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.tools.ServiceLocator;

/**
 * reindex indices when the mdstores change.
 * 
 * @author marko
 * 
 */
public class ReindexNotificationHandler extends AbstractWorkflowLauncherNotificationHandler {

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

	/**
	 * Used to create data source descriptors from MDStore id.
	 */
	@Resource
	private MDStoreDataSinkSourceDescriptorGenerator sourceDescriptionGenerator;

	/**
	 * locator.
	 */
	private ServiceLocator<ISLookUpService> lookupLocator;

	/**
	 * mdformat layout for indexing.
	 */
	private String layout;

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.manager.msro.AbstractWorkflowLauncherNotificationHandler#prepareProcess(eu.dnetlib.workflow.GraphProcessRegistry,
	 *      com.googlecode.sarasvati.GraphProcess, java.lang.String, java.lang.String)
	 */
	@Override
	public void prepareProcess(final GraphProcess process, final Env env, final String rsId, final String profile) {

		// TODO: use utility method for this query because it's used in UpdateRepositorySizeJob.java too
		final String query = "//RESOURCE_PROFILE[.//MDSTORE_DS_IDENTIFIER='" + rsId + "' or contains(.//DATA_SINK, '" + rsId
				+ "')]//REPOSITORY_SERVICE_IDENTIFIER/text()";

		try {
			final String repId = lookupLocator.getService().getResourceProfileByQuery(query);
			getProcessRegistry().associateProcessWithResource(process, repId);
		} catch (final ISLookUpDocumentNotFoundException e) {
			log.warn("cannot locate the repository associated with the mdstore " + rsId, e);
		} catch (final ISLookUpException e) {
			log.warn("cannot locate the repository associated with the mdstore " + rsId, e);
		}

		final String combinedQuery = "//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + rsId + "']//METADATA_FORMAT/text(),"
				+ "//RESOURCE_PROFILE[.//RESOURCE_IDENTIFIER/@value = '" + rsId + "']//METADATA_FORMAT_INTERPRETATION/text()";
		List<String> combined;
		try {
			combined = lookupLocator.getService().quickSearchProfile(combinedQuery);

			env.setAttribute("dataSource", sourceDescriptionGenerator.generateDataSourceDescriptor(rsId));
			env.setAttribute("mdId", rsId);
			env.setAttribute("format", combined.get(0));
			env.setAttribute("interpretation", combined.get(1));
			env.setAttribute("layout", getLayout());

		} catch (final ISLookUpException e) {
			throw new IllegalStateException("cannot reindex", e);
		}
	}

	public ServiceLocator<ISLookUpService> getLookupLocator() {
		return lookupLocator;
	}

	public void setLookupLocator(final ServiceLocator<ISLookUpService> lookupLocator) {
		this.lookupLocator = lookupLocator;
	}

	public String getLayout() {
		return layout;
	}

	@Required
	public void setLayout(final String layout) {
		this.layout = layout;
	}

	public MDStoreDataSinkSourceDescriptorGenerator getSourceDescriptionGenerator() {
		return sourceDescriptionGenerator;
	}

	public void setSourceDescriptionGenerator(final MDStoreDataSinkSourceDescriptorGenerator sourceDescriptionGenerator) {
		this.sourceDescriptionGenerator = sourceDescriptionGenerator;
	}

}
