package eu.dnetlib.api.functionality;

import java.net.URI;
import java.net.URL;
import java.util.Date;
import java.util.SortedSet;

import eu.dnetlib.api.DriverService;
import eu.dnetlib.domain.functionality.AlertSubscription;
import eu.dnetlib.domain.functionality.AlertTemplate;
import eu.dnetlib.domain.functionality.NotificationEvent;
import eu.dnetlib.domain.functionality.ObjectPage;
import eu.dnetlib.domain.functionality.ResultPage;

/**
 * This interface declares the available methods of alert service. Alert service is used to manage templates and subscriptions. 
 * @author thanos@di.uoa.gr
 * @see eu.dnetlib.domain.functionality.AlertTemplate
 * @see eu.dnetlib.domain.functionality.AlertSubscription
 * @see eu.dnetlib.domain.functionality.NotificationEvent
 * @see AlertServiceException
 * 
 */
public interface AlertService extends DriverService {
	/**
	 * Retrieve all the supported modes in which alerts can be sent.
	 * @return a sorted set containing all the supported modes in which alerts can be sent
	 */
	public SortedSet<String> getSupportedAlertModes();
	
	/**
	 * Retrieve a page of templates.
	 * @param pageNumber the number of the page to retrieve
	 * @param pageSize the size of the page to retrieve
	 * @return an object page containing templates
	 * @throws AlertServiceException if any errors occur
	 */
	public ObjectPage<AlertTemplate> getTemplates(final int pageNumber, final int pageSize) throws AlertServiceException;
	
	/**
	 * Add a template.
	 * @param template the template to add
	 * @throws AlertServiceException if any errors occur
	 */
	public void addTemplate(final AlertTemplate template) throws AlertServiceException;
	
	/**
	 * Remove a template.
	 * @param templateId the unique identifier of the template to remove
	 * @throws AlertServiceException if any errors occur
	 */
	public void removeTemplate(final String templateId) throws AlertServiceException;	
	
	/**
	 * Retrieve a page of subscriptions.
	 * @param pageNumber the number of the page to retrieve
	 * @param pageSize the size of the page to retrieve
	 * @return an object page containing subscriptions
	 * @throws AlertServiceException if any errors occur
	 */
	public ObjectPage<AlertSubscription> getSubscriptions(final int pageNumber, final int pageSize) throws AlertServiceException;

	/**
	 * Retrieve some subscriptions by alert mode and subscriber.
	 * @param alertMode the alert mode of the subscriptions to retrieve
	 * @param subscriber the subscriber URI of the subscriptions to retrieve (prefix match)
	 * @param limit the maximum number of subscriptions to retrieve
	 * @param offset the offset to start at 
	 * @return a list of subscriptions
	 * @throws AlertServiceException if any errors occur
	 */ 
	public SortedSet<AlertSubscription> getSubscriptions(final String alerMode, final String subscriber, final int limit, final int offset) throws AlertServiceException;
	
	/**
	 * Add a new subscription.
	 * @param subscription the subscription to add
	 * @throws AlertServiceException if any errors occur
	 */
	public void addSubscription(final AlertSubscription subscription) throws AlertServiceException;
	
	/**
	 * Enable a subscription.
	 * @param templateId the unique identifier of the template of the subscription to enable
	 * @param notificationService the URL of the notification service of the subscription to enable
	 * @param queryId the unique identifier of the notification query  of the subscription to enable
	 * @param resultId the unique identifier of the result of the subscription to enable
	 * @param alertMode the alert mode of the subscription to enable
	 * @param subscriber the URI of the subscriber of the subscription to enable 
	 * @throws AlertServiceException if any errors occur
	 */
	public void enableSubscription(final String templateId, final URL notificationService, final String queryId, final String resultId, final String alertMode, final URI subscriber) throws AlertServiceException;
	
	/**
	 * Disable a subscription.
	 * @param templateId the unique identifier of the template the subscription to disable
	 * @param notificationService the URL of the notification service of the subscription to disable
	 * @param queryId the unique identifier of the notification query of the subscription to disable
	 * @param resultId the unique identifier of the result of the subscription to disable
	 * @param alertMode the alert mode of the subscription to disable
	 * @param subscriber the URI of the subscriber of the subscription to disable 
	 * @throws AlertServiceException if any errors occur
	 */
	public void disableSubscription(final String templateId, final URL notificationService, final String queryId, final String resultId, final String alertMode, final URI subscriber) throws AlertServiceException;
	
	/**
	 * Remove a subscription.
	 * @param templateId the unique identifier of the template of the subscription to remove
	 * @param notificationService the URL of the notification service of the subscription to remove
	 * @param queryId the unique identifier of the notification query of the subscription to remove
	 * @param resultId the unique identifier of the result of the subscription to remove
	 * @param alertMode the alert mode of the subscription to remove
	 * @param subscriber the URI of the subscriber of the subscription to remove 
	 * @throws AlertServiceException if any errors occur
	 */
	public void removeSubscription(final String templateId, final URL notificationService, final String queryId, final String resultId, final String alertMode, final URI subscriber) throws AlertServiceException;
	
	/**
	 * Count the results of an alert.
	 * @param templateId the unique identifier of the template of the alert results to count
	 * @param notificationService the URL of the notification service of the alert results to count
	 * @param queryId the unique identifier of the notification query of the alert results to count
	 * @param date the date that corresponds to the notification event of the alert results to count
	 * @param resultId the unique identifier of the notification result of the alert results to count
	 * @return the total number of the specified alert results
	 * @throws AlertServiceException if any errors occur
	 */
	public int countAlertResults(final URL notificationService, final String queryId, final Date date, final String resultId) throws AlertServiceException;

	/**
	 * Retrieve the results of an alert.
	 * @param notificationService the URL of the notification service of the alert results to retrieve
	 * @param queryId the unique identfier of the notification query of the alert results to retrieve
	 * @param resultId the unique identifier of the notification result of the alert results to retrieve
	 * @param fromDate the date from which to retrieve alert results
	 * @param toDate the date up to which to retrieve alert results 
	 * @param limit the maximum number of alert results to retrieve
	 * @param offset the offset to start at
	 * @return a result page
	 * @throws AlertServiceException if any errors occur
	 */
	public ResultPage getAlertResults(final URL notificationService, final String queryId, final String resultId, final Date fromDate, final Date toDate, final int limit, final int offset) throws AlertServiceException;
			
	/**
	 * Alert this service about an event generated by a notification service.
	 * @param notificationService the URL of the notification service
	 * @param event the notification event
	 * @throws AlertServiceException if any errors occur
	 */
	public void alert(final URL notificationService, final NotificationEvent event) throws AlertServiceException; 
}
