package eu.dnetlib.data.mdstore;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.common.collect.Lists;

/**
 * This DAO handles mdstore data structures which are created dynamically during program execution but are backed by a
 * MockMDStore provided by a mock MDStoreDao.
 *
 * <p>
 * This is useful when we want to test mdstore creation as in the real world but we want to have them already filled
 * with data.
 * </p>
 *
 * Only a given number of wrappers can be created, up to the number of existing mock mdstores.
 *
 * @author marko
 *
 */
public class WrappedMockMDStoreDao implements MDStoreDao {

	/**
	 * mock dao.
	 */
	private MDStoreDao mockDao;

	/**
	 * last used mdstore id.
	 */
	private transient int lastId = 1;

	/**
	 * a mapping between the wrapped mock mdstores and the mock mdstores is maintained here.
	 */
	private final Map<String, String> mdToMock = new HashMap<String, String>();

	/**
	 * {@inheritDoc}
	 *
	 * @see eu.dnetlib.data.mdstore.MDStoreDao#getMDStore(java.lang.String)
	 */
	public MDStore getMDStore(final String mdId) {
		// if we don't handle this md id, return null in order to pass to the next dao in the chain
		if (!mdToMock.containsKey(mdId))
			return null;
		return mockDao.getMDStore(mdToMock.get(mdId));
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see eu.dnetlib.data.mdstore.MDStoreDao#createMDStore(java.lang.String)
	 */
	public boolean createMDStore(final String mdId) {
		mdToMock.put(mdId, mockDao.listMDStores().get(lastId++ % mockDao.listMDStores().size()));
		return true;
	}

	/**
	 * {@inheritDoc}
	 *
	 * @see eu.dnetlib.data.mdstore.MDStoreDao#listMDStores()
	 */
	public List<String> listMDStores() {
		return Lists.newArrayList(mdToMock.keySet());
	}

	public MDStoreDao getMockDao() {
		return mockDao;
	}

	public void setMockDao(final MDStoreDao mockDao) {
		this.mockDao = mockDao;
	}

}
