package eu.dnetlib.enabling.is.sn.resourcestate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * 
 * dummy implementation of the resource state subscription DAO layer, using an in-memory map.
 * 
 * @author marko
 * 
 */
public class MemoryResourceStateSubscriptionDAOImpl implements ResourceStateSubscriptionDAO {

	/**
	 * by id.
	 */
	private Map<String, ResourceStateSubscription> byId = new HashMap<String, ResourceStateSubscription>();

	/**
	 * groups subscriptions with the same prefix and type.
	 */
	private Map<String, Collection<ResourceStateSubscription>> byPrefixAndType = new HashMap<String, Collection<ResourceStateSubscription>>();

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.is.sn.resourcestate.ResourceStateSubscriptionDAO#listSubscriptions(java.lang.String,
	 *      java.lang.String, java.lang.String)
	 */
	@Override
	public Collection<ResourceStateSubscription> listSubscriptions(final String prefix, final String resourceType, final String resourceId) {
		return orDefault(getByPrefixAndType().get(prefix + "/" + resourceType + "/" + resourceId));
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.is.sn.SubscriptionDAO#addSubscription(java.lang.Object)
	 */
	@Override
	public void addSubscription(final ResourceStateSubscription subscription) {
		getById().put(subscription.getSubscriptionId(), subscription);

		final String key = subscription.getPrefix() + "/" + subscription.getType() + "/" + subscription.getResourceId();
		final Collection<ResourceStateSubscription> prefTypeList = getByPrefixAndType().get(key);
		if (prefTypeList == null)
			getByPrefixAndType().put(key, new ArrayList<ResourceStateSubscription>());
		getByPrefixAndType().get(key).add(subscription);

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.is.sn.SubscriptionDAO#getSubscription(java.lang.String)
	 */
	@Override
	public ResourceStateSubscription getSubscription(final String subscriptionId) {
		return getById().get(subscriptionId);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.is.sn.SubscriptionDAO#listSubscriptions()
	 */
	@Override
	public Collection<ResourceStateSubscription> listSubscriptions() {
		return orDefault(getById().values());
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.is.sn.SubscriptionDAO#listSubscriptions(java.lang.String)
	 */
	@Override
	public Collection<ResourceStateSubscription> listSubscriptions(final String prefix) {
		return listSubscriptions(prefix, "*", "*");
	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see eu.dnetlib.enabling.is.sn.SubscriptionDAO#removeSubscription(java.lang.String)
	 */
	@Override
	public boolean removeSubscription(final String subscriptionId) {
		final ResourceStateSubscription subscription = getSubscription(subscriptionId);
		if (subscription == null)
			return false;
		final String key = subscription.getPrefix() + "/" + subscription.getType() + "/" + subscription.getResourceId();
		
		final Collection<ResourceStateSubscription> prefTypeList = getByPrefixAndType().get(key);
		prefTypeList.remove(subscription);
		
		getById().remove(subscriptionId);
		return true;
	}

	/**
	 * inner helper method. returns an empty collection instead of a null.
	 * 
	 * @param collection
	 *            some collection
	 * @return input collection or empty collection
	 */
	private Collection<ResourceStateSubscription> orDefault(final Collection<ResourceStateSubscription> collection) {
		if (collection == null)
			return new ArrayList<ResourceStateSubscription>();
		return collection;
	}

	public Map<String, ResourceStateSubscription> getById() {
		return byId;
	}

	public void setById(final Map<String, ResourceStateSubscription> byId) {
		this.byId = byId;
	}

	public Map<String, Collection<ResourceStateSubscription>> getByPrefixAndType() {
		return byPrefixAndType;
	}

	public void setByPrefixAndType(final Map<String, Collection<ResourceStateSubscription>> byPrefixAndType) {
		this.byPrefixAndType = byPrefixAndType;
	}
}
