package eu.dnetlib.oai.init.mongo;

import java.util.List;

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

import eu.dnetlib.data.information.DataSinkSourceException;
import eu.dnetlib.data.information.DataSource;
import eu.dnetlib.data.information.DataSourceResolver;
import eu.dnetlib.data.information.MDStoreDataSinkSourceDescriptorGenerator;
import eu.dnetlib.data.information.oai.publisher.conf.OAIStoreInitializer;
import eu.dnetlib.data.information.oai.publisher.info.MDFInfo;
import eu.dnetlib.data.information.oai.publisher.store.MongoPublisherStore;
import eu.dnetlib.data.information.oai.publisher.store.MongoPublisherStoreDAO;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpException;
import eu.dnetlib.enabling.is.lookup.rmi.ISLookUpService;
import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;
import eu.dnetlib.enabling.tools.ServiceLocator;

/**
 * Schedulable class for the automatic configuration of the OAI publisher.
 * <p>
 * It reads the configuration profile and properly initializes all the needed stores and relative indices with content from a mongo mdstore.
 * </p>
 * 
 * @author alessia
 * 
 */
public class PublisherInitializerMongo extends OAIStoreInitializer {

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

	private DataSourceResolver dataSourceResolver;
	private ServiceLocator<ISLookUpService> lookupLocator;
	private ResultSetClientFactory resultSetClientFactory;

	@Override
	protected void synchronizeContent(final MongoPublisherStore store) {
		PublisherInitializerMongo.log.info("Synchronizing content for stores: \n\tformat:" + getMdfInfo().getSourceFormatName() + " \n\tinterpretation: "
				+ getMdfInfo().getSourceFormatInterpretation() + " \n\tlayout: " + getMdfInfo().getSourceFormatLayout());

		final String query = "//RESOURCE_PROFILE[.//RESOURCE_TYPE/@value = 'MDStoreDSResourceType' and .//METADATA_FORMAT = '"
				+ getMdfInfo().getSourceFormatName() + "' and  .//METADATA_FORMAT_INTERPRETATION ='" + getMdfInfo().getSourceFormatInterpretation()
				+ "' and .//METADATA_FORMAT_LAYOUT = '" + getMdfInfo().getSourceFormatLayout() + "']//RESOURCE_IDENTIFIER/@value/string()";

		MDStoreDataSinkSourceDescriptorGenerator storeDescriptorGenerator = new MDStoreDataSinkSourceDescriptorGenerator();
		try {
			List<String> mdStoreIds = lookupLocator.getService().quickSearchProfile(query);
			for (String mdStoreId : mdStoreIds) {
				DataSource source = dataSourceResolver.resolve(storeDescriptorGenerator.generateDataSourceDescriptor(mdStoreId));
				final Iterable<String> records = resultSetClientFactory.getClient(source.retrieve());
				store.feed(records, mdStoreId);
			}
		} catch (ISLookUpException e) {
			PublisherInitializerMongo.log.fatal("Can't synchronize content for stores: \n\tformat:" + getMdfInfo().getSourceFormatName()
					+ " \n\tinterpretation: " + getMdfInfo().getSourceFormatInterpretation() + " \n\tlayout: " + getMdfInfo().getSourceFormatLayout());
			PublisherInitializerMongo.log.fatal(e.getMessage());
		} catch (DataSinkSourceException e) {
			PublisherInitializerMongo.log.fatal("Can't synchronize content for stores: \n\tformat:" + getMdfInfo().getSourceFormatName()
					+ " \n\tinterpretation: " + getMdfInfo().getSourceFormatInterpretation() + " \n\tlayout: " + getMdfInfo().getSourceFormatLayout());
			PublisherInitializerMongo.log.fatal(e.getMessage());
		}
	}

	public PublisherInitializerMongo() {
		super();
		// TODO Auto-generated constructor stub
	}

	public PublisherInitializerMongo(final MDFInfo mdfInfo, final MongoPublisherStoreDAO oaiStoreDao, final boolean forceContentSyncronization,
			final DataSourceResolver dataSourceResolver, final ServiceLocator<ISLookUpService> lookupLocator,
			final ResultSetClientFactory resultSetClientFactory) {
		super(mdfInfo, oaiStoreDao, forceContentSyncronization);
		this.dataSourceResolver = dataSourceResolver;
		this.lookupLocator = lookupLocator;
		this.resultSetClientFactory = resultSetClientFactory;
	}

	public DataSourceResolver getDataSourceResolver() {
		return dataSourceResolver;
	}

	public void setDataSourceResolver(final DataSourceResolver dataSourceResolver) {
		this.dataSourceResolver = dataSourceResolver;
	}

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

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

	public ResultSetClientFactory getResultSetClientFactory() {
		return resultSetClientFactory;
	}

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

}
