package eu.dnetlib.dlms.benchmark;

import org.openrdf.model.URI;
import org.openrdf.query.Binding;
import org.openrdf.query.BindingSet;
import org.openrdf.query.QueryEvaluationException;
import org.openrdf.query.TupleQueryResult;

import eu.dnetlib.dlms.lowlevel.LowLevelException;
import eu.dnetlib.dlms.lowlevel.objects.structures.Structure;
import eu.dnetlib.dlms.lowlevel.objects.structures.StructureDAO;

/**
 * This class wraps an org.openrdf.query.TupleQueryResult to get Structures only when the caller asks for it. Please
 * call close() when users ends their work with a TripleStoreQueryResult.
 * 
 * @author alessia
 */
public class TripleStoreQueryResult implements DorotyQueryResult {

	/** TupleQueryResult instance used to generate the Doroty result of the query. */

	private TupleQueryResult tripleStoreResult;
	/** DAO for Structures. */
	private StructureDAO structDAO;

	public TupleQueryResult getTripleStoreResult() {
		return this.tripleStoreResult;
	}

	public void setTripleStoreResult(final TupleQueryResult tripleStoreResult) {
		this.tripleStoreResult = tripleStoreResult;
	}

	public StructureDAO getStructDAO() {
		return this.structDAO;
	}

	public void setStructDAO(final StructureDAO structDAO) {
		this.structDAO = structDAO;
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.util.Iterator#hasNext()
	 */
	public boolean hasNext() {
		try {
			return this.tripleStoreResult.hasNext();
		} catch (QueryEvaluationException e) {
			throw new LowLevelException(e);
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.util.Iterator#next()
	 */
	public Structure next() {
		BindingSet bs;
		try {
			bs = this.tripleStoreResult.next();
			// need to take the binding with name contesto:
			Binding c = bs.getBinding("contesto");
			URI contextValue = (URI) c.getValue();
			long contextId = Long.parseLong(contextValue.getLocalName());
			return this.structDAO.getByID(contextId);
		} catch (QueryEvaluationException e) {
			throw new LowLevelException(e);
		}
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see java.util.Iterator#remove()
	 */
	@Override
	public void remove() {
		throw new UnsupportedOperationException();
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.dlms.benchmark.DorotyQueryResult#close()
	 */
	public void close() {
		try {
			this.tripleStoreResult.close();
		} catch (QueryEvaluationException e) {
			throw new LowLevelException(e);
		}
	}

}
