package eu.dnetlib.api.functionality;

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

import eu.dnetlib.api.DriverService;
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;
import eu.dnetlib.domain.functionality.ObjectPage;
import eu.dnetlib.domain.functionality.ResultPage;

/**
 * This interface declares the available methods of notification service. Alert service is used to manage queries, schedules, events, results and subscriptions.
 * @author thanos@di.uoa.gr
 * @see eu.dnetlib.domain.functionality.NotificationQuery
 * @see eu.dentlib.domain.functionality.NotificationSchedule
 * @see eu.dnetlib.domain.functionality.NotificationEvent
 * @see eu.dnetlib.domain.functionality.NotificationResult
 * @see eu.dnetlib.domain.functionality.NotificationSubscription
 * @see NotificationServiceException
 * 
 */
public interface NotificationService extends DriverService {
	/**
	 * Retrieve all the supported languages in which queries can be expressed.
	 * @return a set containing all the supported languages in which queries can be expressed
	 */
	public SortedSet<String> getSupportedQueryLanguages();

	/**
	 * Retrieve a page of queries.
	 * @param pageNumber the number of the page to retrieve
	 * @param pageSize the size of the page to retrieve
	 * @return an object page containing queries
	 * @throws NotificationServiceException if any errors occur
	 */
	public ObjectPage<NotificationQuery> getQueries(final int pageNumber, final int pageSize) throws NotificationServiceException;
	
	/**
	 * Add a query.
	 * @param query the query to add
	 * @throws NotificationServiceException if any errors occur
	 */
	public void addQuery(final NotificationQuery query) throws NotificationServiceException;
	
	/**
	 * Remove a query.
	 * @param queryId the unique identifier of the query to remove
	 * @throws NotificationServiceException if any errors occur
	 */
	public void removeQuery(final String queryId) throws NotificationServiceException;
	
	/**
	 * Execute a query and return the generated result.
	 * @param queryId the unique identifier of the query to execute
	 * @param resultId the unique result identifier to use
	 * @param fromDate the from date to use
	 * @param toDate the to date to use
	 * @param limit the limit to use
	 * @param offset the offset to use
	 * @return a result page containing the generated result
	 * @throws NotificationServiceException if any errors occur
	 */
	public ResultPage executeQuery(final String queryId, final String resultId, final Date fromDate, final Date toDate, final int limit, final int offset) throws NotificationServiceException;
	
	/**
	 * Retrieve a page of schedules.
	 * @param pageNumber the number of the page to retrieve
	 * @param pageSize the size of the page to retrieve
	 * @return an object page containing schedules
	 * @throws NotificationServiceException if any errors occur
	 */
	public ObjectPage<NotificationSchedule> getSchedules(final int pageNumber, final int pageSize) throws NotificationServiceException;
	
	/**
	 * Add a schedule.
	 * @param schedule the schedule to add
	 * @throws NotificationServiceException if any errors occur
	 */
	public void addSchedule(final NotificationSchedule schedule) throws NotificationServiceException;
	
	/**
	 * Enable a schedule.
	 * @param queryId the unique identifier of the query whose schedule to enable
	 * @throws NotificationServiceException if any errors occur
	 */
	public void enableSchedule(final String queryId) throws NotificationServiceException;
	
	/**
	 * Disable a schedule.
	 * @param queryId the unique identifier of the query whose schedule to disable
	 * @throws NotificationServiceException if any errors occur
	 */
	public void disableSchedule(final String queryId) throws NotificationServiceException;
	
	/**
	 * Remove a schedule.
	 * @param queryId the unique identifier of the query of the schedule to remove
	 * @throws NotificationServiceException if any errors occur
	 */
	public void removeSchedule(final String queryId) throws NotificationServiceException;
	
	/**
	 * Retrieve a page of events.
	 * @param pageNumber the number of the page to retrieve
	 * @param pageSize the size of the page to retrieve
	 * @return an object page containing events
	 * @throws NotificationServiceException if any errors occur
	 */
	public ObjectPage<NotificationEvent> getEvents(final int pageNumber, final int pageSize) throws NotificationServiceException;

	/**
	 * Retrieve a page of results.
	 * @param pageNumber the number of the page to retrieve
	 * @param pageSize the size of the page to retrieve
	 * @return an object page containing results
	 * @throws NotificationServiceException if any errors occur
	 */
	public ObjectPage<NotificationResult> getResults(final int pageNumber, final int pageSize) throws NotificationServiceException;
	
	/**
	 * 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 NotificationServiceException if any errors occur
	 */
	public NotificationResult getResult(final String queryId, final Date date, final String resultId) throws NotificationServiceException;
	
	/**
	 * 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 whose 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 NotificationServiceException if any errors occur
	 */
	public NotificationResult getPreviousResult(final String queryId, final Date date, final String resultId) throws NotificationServiceException;
	
	/**
	 * 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 containign subscriptions
	 * @throws NotificationServiceException if any errors occur
	 */
	public ObjectPage<NotificationSubscription> getSubscriptions(final int pageNumber, final int pageSize) throws NotificationServiceException;
	
	/**
	 * Add a subscription.
	 * @param subscription the subscription to add
	 * @throws NotificationServiceException if any errors occur
	 */
	public void addSubscription(final NotificationSubscription subscription) throws NotificationServiceException;
	
	/**
	 * Enable a subscription.
	 * @param queryId the unique identifier of the query of the schedule of the subscription to enable
	 * @param alertService the URL of the alert service of the subscription to enable
	 * @throws NotificationServiceException if any errors occur
	 */
	public void enableSubscription(final String queryId, final URL alertService) throws NotificationServiceException;
	
	/**
	 * Disable a subscription.
	 * @param queryId the unique identifier of the query of the schedule of the subscription to disable
	 * @param alertService the URL of the alert service of the subscription to disable
	 * @throws NotificationServiceException if any errors occur
	 */
	public void disableSubscription(final String queryId, final URL alertService) throws NotificationServiceException;
	
	/**
	 * Remove a subscription.
	 * @param queryId the unique identifier of the query of the schedule of the subscription to remove
	 * @param alertService the URL of the alert service of the subscription to remove
	 * @throws NotificationServiceException if any errors occur
	 */
	public void removeSubscription(final String queryId, final URL alertService) throws NotificationServiceException;
}
