package eu.dnetlib.enabling.is.sn;

import java.util.Collection;

import eu.dnetlib.enabling.is.sn.resourcestate.ResourceStateSubscription;
import eu.dnetlib.enabling.is.sn.rmi.SubscriptionRequestRejectedException;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;

/**
 * A subscription registry stores subscriptions.
 * 
 * <p>
 * Different subscription registries know how to to store different kind of subscriptions. Each registry is specialized
 * in one type of subscriptions and knows how to quickly find all potentially interesting subscriptions so that a
 * particular NotificationDetector can do his job the quickest way possible.
 * </p>
 * 
 * <p>
 * This interface is generic only for subscription purposes because the Subscriber component simply tries to register a
 * new subscription to all available subscription registries.
 * </p>
 * 
 * <p>
 * Normally a subscription registry manages only a set of topic expression prefixes, but this interface doesn't force
 * the Subscriber to know this information; instead the subscription registry itself will decide whether to accept the
 * subscription or not.
 * </p>
 * <p>
 * Since many subscription registries may accept the same subscription, the identifier is preallocated by the
 * Subscriber, since the subscription is only one, and even if we give the possibility for several detectors to detect
 * it from different sources only one event will be generated.
 * </p>
 * 
 * @author marko
 * 
 */
public interface SubscriptionRegistry {

	/**
	 * register a subscription.
	 * 
	 * @param subscription
	 *            subscription request
	 * @return if we can accept this subcription we return the (possibly changed) identifier, otherwise null
	 */
	String registerSubscription(SubscriptionRequest subscription) throws SubscriptionRequestRejectedException;

	/**
	 * Unsubscribe a subscription if it exists.
	 * 
	 * @param subId subscription identifier
	 * @return true if this subscription existed and was successfully removed
	 */
	boolean unsubscribe(final String subId);

	/**
	 * return all subscriptions matching a given prefix and a given type. Wildcard subscriptions will match any resource type.
	 *
	 * @param prefix
	 *            prefix
	 * @param type
	 *            concrete type
	 * @param resId
	 *            resource identifier
	 * @return all matching subscriptions
	 */
	Collection<ResourceStateSubscription> listMatchingSubscriptions(final String prefix, final String type, final String resId);

	/**
	 * return all subscriptions.
	 *
	 * @return all subscriptions
	 */
	Collection<ResourceStateSubscription> listSubscriptions();

	/**
	 * removes a particular subscription.
	 *
	 * @param subscriptionId identifier
	 * @return true if successful
	 */
	boolean removeSubscription(String subscriptionId);
}
