package eu.dnetlib.msro.workflows.nodes.mdstore;

import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;
import javax.xml.ws.wsaddressing.W3CEndpointReference;

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

import com.google.common.base.Function;
import com.google.common.collect.Iterables;

import eu.dnetlib.data.mdstore.MDStoreService;
import eu.dnetlib.data.mdstore.MDStoreServiceException;
import eu.dnetlib.enabling.locators.UniqueServiceLocator;
import eu.dnetlib.enabling.resultset.client.ResultSetClientFactory;

// TODO: Auto-generated Javadoc
/**
 * The Class MultipleMdStoreIterator.
 */
public class MultipleMdStoreIterator implements Iterator<String> {

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

	/** The service locator. */
	@Resource
	private UniqueServiceLocator serviceLocator;

	/** The current iterator. */
	private Iterator<String> currentIterator;

	/** The result set client factory. */
	@Autowired
	private ResultSetClientFactory resultSetClientFactory;

	/**
	 * Instantiates a new multiple md store iterator.
	 *
	 * @param mdstoreLocator
	 *            the mdstore locator
	 * @param mdIds
	 *            the md ids
	 */
	public MultipleMdStoreIterator(final UniqueServiceLocator serviceLocator, final List<String> mdIds, final ResultSetClientFactory resultSetClientFactory) {
		this.serviceLocator = serviceLocator;
		this.resultSetClientFactory = resultSetClientFactory;

		log.info(String.format("iterating over mdIds: '%s'", mdIds));

		this.currentIterator = Iterables.concat(Iterables.transform(mdIds, new Function<String, Iterable<String>>() {

			@Override
			public Iterable<String> apply(final String mdId) {

				log.debug(String.format("current mdId '%s'", mdId));
				try {
					W3CEndpointReference epr = serviceLocator.getService(MDStoreService.class, mdId).deliverMDRecords(mdId, "", "", "");
					return resultSetClientFactory.getClient(epr);
				} catch (MDStoreServiceException e) {
					log.error(e);
					throw new RuntimeException(String.format("unable to iterate over %s", mdId), e);
				}
			}
		})).iterator();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.util.Iterator#hasNext()
	 */
	@Override
	public boolean hasNext() {
		if (currentIterator == null) return false;

		return currentIterator.hasNext();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.util.Iterator#next()
	 */
	@Override
	public String next() {
		return currentIterator.next();
	}

	/*
	 * (non-Javadoc)
	 *
	 * @see java.util.Iterator#remove()
	 */
	@Override
	public void remove() {
		throw new UnsupportedOperationException("Cannot remove");
	}

}
