package eu.dnetlib.functionality.notification.dao;

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

import eu.dnetlib.domain.functionality.NotificationEvent;
import eu.dnetlib.domain.functionality.NotificationQuery;
import eu.dnetlib.domain.functionality.NotificationResult;
import eu.dnetlib.domain.functionality.NotificationSchedule;
import eu.dnetlib.domain.functionality.NotificationSubscription;

/**
 * This interface declares methods for persisting notification queries, subscriptions and events .
 * @author thanos@di.uoa.gr
 * @see eu.dnetlib.domain.functionality.NotificationQuery
 * @see eu.dnetlib.domain.functionality.NotificationSubscription
 * @see eu.dnetlib.domain.functionality.NotificationEvent
 * @see NotificationDAOException
 * 
 */
public interface NotificationDAO {
	/**
	 * Count available queries.
	 * @return the number of available queries
	 * @throws NotificationDAOException if any errors occur
	 */
	public int countQueries() throws NotificationDAOException;
		
	/**
	 * Retrieve some of the available queries.
	 * @param limit the number of queries to retrieve
	 * @param offset the offset to start at
	 * @return a sorted set of queries
	 * @throws NotificationDAOException if any errors occur
	 */
	public SortedSet<NotificationQuery> getQueries(final int limit, final int offset) throws NotificationDAOException;

	/**
	 * Retrieve a query.
	 * @param queryId the unique identifier of the query to retrieve
	 * @return the query corresponding to the unique identifier specified or null if no such query exists
	 * @throws NotificationDAOException if any errors occur
	 */
	public NotificationQuery getQuery(final String queryId) throws NotificationDAOException;
	
	/**
	 * Save a query.
	 * @param query the query to save
	 * @throws NotificationDAOException if any errors occur
	 */
	public void saveQuery(final NotificationQuery query) throws NotificationDAOException;
	
	/**
	 * Delete a query.
	 * @param queryId the unique identifier of the query to delete
	 * @throws NotificationDAOException if any errors occur
	 */
	public void deleteQuery(final String queryId) throws NotificationDAOException;

	/**
	 * Count available schedules.
	 * @return the number of available schedules
	 * @throws NotificationDAOException if any errors occur
	 */
	public int countSchedules() throws NotificationDAOException;
	
	/**
	 * Retrieve some of the available schedules.
	 * @param limit the number of schedules to retrieve
	 * @param offset the offset to start at
	 * @return a sorted set containing schedules
	 * @throws NotificationDAOException
	 */
	public SortedSet<NotificationSchedule> getSchedules(final int limit, final int offset) throws NotificationDAOException;
	
	/**
	 * Retrieve enabled schedules.
	 * @param limit the maximum number of schedules to retrieve
	 * @param offset the offset to start at
	 * @return a sorted set of schedules
	 * @throws NotificationDAOException if any errors occur
	 */
	public SortedSet<NotificationSchedule> getEnabledSchedules(final int limit, final int offset) throws NotificationDAOException;

	/**
	 * Retrieve a schedule.
	 * @param queryId the unique identifier of the query whose schedule to retrieve
	 * @return the schedule of the specified query or null if no such schedule exists
	 * @throws NotificationDAOException if any errors occur
	 */
	public NotificationSchedule getSchedule(final String queryId) throws NotificationDAOException;
	
	/**
	 * Save a schedule.
	 * @param schedule the schedule to save
	 * @throws NotificationDAOException if any errors occur
	 */
	public void saveSchedule(final NotificationSchedule schedule) throws NotificationDAOException;
	
	/**
	 * Delete a schedule.
	 * @param queryId the unique identifier of the query of the schedule to delete
	 * @throws NotificationDAOException if any errors occur
	 */
	public void deleteSchedule(final String queryId) throws NotificationDAOException;
	
	/**
	 * Count available events.
	 * @return the number of available events
	 * @throws NotificationDAOException if any errors occur
	 */
	public int countEvents() throws NotificationDAOException;
	
	/**
	 * Retrieve some of the available events.
	 * @param limit the number of events to retrieve
	 * @param offset the offset to start at
	 * @return a sorted set containing events
	 * @throws NotificationDAOException if any errors occur
	 */
	public SortedSet<NotificationEvent> getEvents(final int limit, final int offset) throws NotificationDAOException;
	
	/**
	 * Count the available results.
	 * @return the number of available results
	 * @throws NotificationDAOException if any errors occur
	 */
	public int countResults() throws NotificationDAOException;
	
	/**
	 * Retrieve some of the available results.
	 * @param limit the number of results to retrieve
	 * @param offset the offset to start at
	 * @return a sorted set containing results
	 * @throws NotificationDAOException if any errors occur
	 */
	public SortedSet<NotificationResult> getResults(final int limit, final int offset) throws NotificationDAOException;

	/**
	 * Retrieve a result of an event of a query.
	 * @param queryId the unique identifier of the query of the event of the result to retrieve
	 * @param date the date corresponding to the event of the result to retrieve
	 * @param resultId the unique identifier of the result to retrieve
	 * @return the specified result of the specified event of the specified query or null if no such result exists
	 * @throws NotificationDAOException if any errors occur
	 */
	public NotificationResult getResult(final String queryId, final Date date, final String resultId) throws NotificationDAOException;
	
	/**
	 * Retrieve a result of the previous event of an event of a query.
	 * @param queryId the unique identifier of the query of the event of the result to retrieve
	 * @param date the date corresponding to the next event of the event of the result to retrieve 
	 * @param resultId the unique identifier of the result to retrieve
	 * @return the specified result of the previous event of the specified event of the specified query or null if no such result exists
	 * @throws NotificationDAOException if any errors occur
	 */
	public NotificationResult getPreviousResult(final String queryId, final Date date, final String resultId) throws NotificationDAOException;
	
	/**
	 * Retrieve a result of the last event of a query.
	 * @param queryId the unique identifier of the query of the event of the result whose value to retrieve
	 * @param resultId the unique identifier of the result to retrieve
	 * @return the specified result of the last event of the specified query or null if no such result exists
	 * @throws NotificationDAOException if any errors occur
	 */
	public NotificationResult getLastResult(final String queryId, final String resultId) throws NotificationDAOException;

	/**
	 * Save a result.
	 * @param result the result to save
	 * @throws NotificationDAOException if any errors occur
	 */
	public void saveResult(final NotificationResult result) throws NotificationDAOException;
	
	/**
	 * Count available subscriptions.
	 * @return the number of available subscriptions
	 * @throws NotificationServiceException if any errors occur
	 */
	public int countSubscriptions() throws NotificationDAOException;
	
	/**
	 * Retrieve some of the available subscriptions. 
	 * @param limit
	 * @param offset
	 * @return
	 * @throws NotificationServiceException
	 */
	public SortedSet<NotificationSubscription> getSubscriptions(final int limit, final int offset) throws NotificationDAOException;
	
	/**
	 * Retrieve some of the available enabled subscriptions of a query.
	 * @param queryId the unique identifier of the query whose subscriptions to retrieve
	 * @param limit the number of subscriptions to retrieve
	 * @param offset the offset to start at
	 * @return a sorted set of enabled subscriptions
	 * @throws NotificationDAOException if any errors occur
	 */
	public SortedSet<NotificationSubscription> getEnabledSubscriptions(final String queryId, final int limit, final int offset) throws NotificationDAOException;
	
	/**
	 * Retrieve a subscription.
	 * @param queryId the unique identifier of the query of the schedule of the subscription to retrieve
	 * @param alertService the URL of the alert service of the subscription to retrieve
	 * @return the specified subscription or null if no such subscription exists
	 * @throws NotificationDAOException if any errors occur
	 */
	public NotificationSubscription getSubscription(final String queryId, final URL alertService) throws NotificationDAOException;
	
	/**
	 * Save a subscription.
	 * @param subscription the subscription to save
	 * @throws NotificationDAOException if any errors occur
	 */
	public void saveSubscription(final NotificationSubscription subscription) throws NotificationDAOException;
	
	/**
	 * Delete a subscription.
	 * @param queryId the unique identifier of the query of the schedule of the subscription to delete
	 * @param alertService the URL of the alert service of the subscription to delete
	 * @throws NotificationDAOException if any errors occur
	 */
	public void deleteSubscription(final String queryId, final URL alertService) throws NotificationDAOException;
}
