package eu.dnetlib.enabling.resultset;

import org.springframework.beans.factory.annotation.Required;

import eu.dnetlib.enabling.tools.UniqueIdentifierGenerator;
import eu.dnetlib.enabling.tools.UniqueIdentifierGeneratorImpl;
import eu.dnetlib.miscutils.cache.Cache;

/**
 * Implement a in memory resultset registry.
 *
 * @author marko
 *
 */
public class ResultSetRegistryImpl implements ResultSetRegistry {

	/**
	 * rsId -> ResultSet mappings are stored here.
	 */
	private Cache<String, ResultSet> cache;

	/**
	 * rsID -> initial maxIdleTime time are store here.
	 */
	private Cache<String, Integer> maxIdleTimeCache;

	/**
	 * identifier generator.
	 */
	private UniqueIdentifierGenerator idGenerator = new UniqueIdentifierGeneratorImpl("rs-");

	/**
	 * {@inheritDoc}
	 * @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet)
	 */
	@Override
	public void addResultSet(final ResultSet resultSet) {
		addResultSet(resultSet, 0);
	}

	/** 
	 * {@inheritDoc}
	 * @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, java.lang.String)
	 */
	@Override
	public void addResultSet(final ResultSet resultSet, final String identifier) {
		addResultSet(resultSet, identifier, 0);
	}
	
	/**
	 * {@inheritDoc}
	 * @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, int)
	 */
	@Override
	public void addResultSet(final ResultSet resultSet, final int maxIdleTime) {
		addResultSet(resultSet, idGenerator.generateIdentifier(), maxIdleTime);
	}
	
	/** 
	 * {@inheritDoc}
	 * @see eu.dnetlib.enabling.resultset.ResultSetRegistry#addResultSet(eu.dnetlib.enabling.resultset.ResultSet, java.lang.String, int)
	 */
	@Override
	public void addResultSet(final ResultSet resultSet, final String identifier, final int maxIdleTime) {
		resultSet.setIdentifier(identifier);
		resultSet.addObserver(this);
		cache.put(resultSet.getIdentifier(), resultSet);
		maxIdleTimeCache.put(resultSet.getIdentifier(), maxIdleTime);
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see eu.dnetlib.enabling.resultset.ResultSetRegistry#getResultSetById(java.lang.String)
	 */
	@Override
	public ResultSet getResultSetById(final String rsId) {
		return cache.get(rsId);
	}

	@Override
	public int getMaxIdleTimeById(final String rsId) {
		return maxIdleTimeCache.get(rsId);
	}


	public Cache<String, ResultSet> getCache() {
		return cache;
	}

	@Required
	public void setCache(final Cache<String, ResultSet> cache) {
		this.cache = cache;
	}

	/**
	 * {@inheritDoc}
	 * @see eu.dnetlib.miscutils.observer.Observer#update(eu.dnetlib.enabling.resultset.observer.Observable, java.lang.Object)
	 */
	@Override
	public void update(final ResultSet observed, final Object arg) {
		if (!observed.isOpen())
			cache.remove(observed.getIdentifier());
	}

	public UniqueIdentifierGenerator getIdGenerator() {
		return idGenerator;
	}

	public void setIdGenerator(final UniqueIdentifierGenerator idGenerator) {
		this.idGenerator = idGenerator;
	}

	public Cache<String, Integer> getMaxIdleTimeCache() {
		return maxIdleTimeCache;
	}

	@Required
	public void setMaxIdleTimeCache(Cache<String, Integer> maxIdleTimeCache) {
		this.maxIdleTimeCache = maxIdleTimeCache;
	}

}
