package eu.dnetlib.domain.functionality;

import java.net.URI;
import java.net.URL;

/**
 * This class represents a subscription to a topic of the alert service.
 * @author thanos@di.uoa.gr
 * @see eu.dnetlib.api.functionality.AlertService
 * @see eu.dnetlib.functionality.alert.alerter.Alerter
 * @see AlertTopic
 * @see AlertTemplate
 *
 */
public class AlertSubscription implements Comparable<AlertSubscription> {
	private String templateId;
	private URL notificationService;
	private String queryId;
	private String resultId;
	private String alertMode;
	private URI subscriber;
	private boolean enabled;
	
	/**
	 * Construct a new alert subscription.
	 * @param templateId the unique identifier of the template of the topic of this subscription
	 * @param notificationService the URL of notification service of the topic of this subscription
	 * @param queryId the unique identifier of the notification service of the topic of this subscription
	 * @param resultId the unique identifier of the notification result of the topic of this subscription
	 * @param alertMode the alert mode of this subscription
	 * @param subscriber the URI of the subscriber of this topic
	 * @param enabled true if this subscription is currently enabled, false if it is currently disabled
	 */
	public AlertSubscription(final String templateId, final URL notificationService, final String queryId, final String resultId, final String alertMode, final URI subscriber, final boolean enabled) {
		this.templateId = templateId;
		this.notificationService = notificationService;
		this.queryId = queryId;
		this.resultId = resultId;
		this.alertMode = alertMode;
		this.subscriber = subscriber;
		this.enabled = enabled;
	}
	
	/**
	 * Construct a new alert subscription with template identifier, notification service, query identifier, result identifier, alert mode and subscriber set to null and enabled set to false.
	 */
	public AlertSubscription() {
		this(null, null, null, null, null, null, false);
	}
	
	/**
	 * Get the template of the topic of this subscription.
	 * @return the unique identifier of the template of the topic of this subscription 
	 */
	public String getTemplateId() {
		return templateId;
	}

	/**
	 * Set the template of the topic of this subscription.
	 * @param templateId the unique identifier of the template of the topic of this subscription
	 */
	public void setTemplateId(final String templateId) {
		this.templateId = templateId;
	}

	/**
	 * Get the notification service of the topic of this subscription.
	 * @return the URL of the notification service of the topic of this subscription
	 */
	public URL getNotificationService() {
		return notificationService;
	}

	/**
	 * Set the notification service of the topic of this subscription.
	 * @param notificationService the URL of the notification service of the topic of this subscription
	 */
	public void setNotificationService(final URL notificationService) {
		this.notificationService = notificationService;
	}

	/**
	 * Set the notification query of the topic of this subscription.
	 * @return the unique identifier of the notification query of the topic of this subscription
	 */
	public String getQueryId() {
		return queryId;
	}

	/**
	 * Set the notification query of the topic of this subscription.
	 * @param queryId the unique identifier of the notification query of the topic of this subscription
	 */
	public void setQueryId(final String queryId) {
		this.queryId = queryId;
	}

	/**
	 * Get the notification result of the topic of this subscription.
	 * @return the resultId the unique identifier of the notification result of the topic of this subscription
	 */
	public String getResultId() {
		return resultId;
	}

	/**
	 * Set the notification result of the topic of this subscription.
	 * @param resultId the unique identifier of the notification result of the topic of this subscription
	 */
	public void setResultId(final String resultId) {
		this.resultId = resultId;
	}

	/**
	 * Get the alert mode of this subscription.
	 * @return the alert mode of this subscription
	 */
	public String getAlertMode() {
		return alertMode;
	}

	/**
	 * Set the alert mode of this subscription
	 * @param alertMode the alert mode of this subscription
	 */
	public void setAlertMode(final String alertMode) {
		this.alertMode = alertMode;
	}

	/**
	 * Get the subscriber of this subscription.
	 * @return the URI of the subscriber of this subscription
	 */
	public URI getSubscriber() {
		return subscriber;
	}

	/**
	 * Set the subscriber of this subscription.
	 * @param subscriber the URI of the subscriber of this subscription
	 */
	public void setSubscriber(final URI subscriber) {
		this.subscriber = subscriber;
	}

	/**
	 * Check if this subscription is enabled.
	 * @return true if this subscription is currently enabled, false otherwise
	 */
	public boolean isEnabled() {
		return enabled;
	}

	/**
	 * Set the enabled status of this subscription.
	 * @param enabled true to enable this subscription, false to disable it
	 */
	public void setEnabled(final boolean enabled) {
		this.enabled = enabled;
	}

	@Override
	public int compareTo(final AlertSubscription subscription) {
		final int templateIdComparison = templateId.compareTo(subscription.templateId);
		final int notificationServiceComparison = notificationService.toString().compareTo(subscription.notificationService.toString());
		final int queryIdComparison = queryId.compareTo(subscription.queryId);
		final int resultIdComparison = resultId.compareTo(subscription.resultId);
		final int alertModeComparison = alertMode.compareTo(subscription.alertMode);
		final int subscriberComparison = subscriber.compareTo(subscription.subscriber);
		return (templateIdComparison == 0) ? ((notificationServiceComparison == 0) ? ((queryIdComparison == 0) ? ((resultIdComparison == 0) ? ((alertModeComparison == 0) ? subscriberComparison : alertModeComparison) :
				resultIdComparison) : queryIdComparison) : notificationServiceComparison) : templateIdComparison;
	}
	
	@Override
	public boolean equals(final Object object) {
		if (!(object instanceof AlertSubscription))
			return false;
		final AlertSubscription subscription = (AlertSubscription) object;
		return ((templateId == null) ? (subscription.templateId == null) : templateId.equals(subscription.templateId)) &&
				((notificationService == null) ? (subscription.notificationService == null) : notificationService.equals(subscription.notificationService)) &&
				((queryId == null) ? (subscription.queryId == null) : queryId.equals(subscription.queryId)) &&
				((resultId == null) ? (subscription.resultId == null) : resultId.equals(subscription.resultId)) &&
				((alertMode == null) ? (subscription.alertMode == null) : alertMode.equals(subscription.alertMode)) &&
				((subscriber == null) ? (subscription.subscriber == null) : subscriber.equals(subscription.subscriber));
	}
	
	@Override
	public int hashCode() {
		return ((templateId == null) ? 0 : templateId.hashCode()) + ((notificationService == null) ? 0 : notificationService.hashCode()) + ((queryId == null) ? 0 : queryId.hashCode()) +
				((resultId == null) ? 0 : resultId.hashCode()) + ((alertMode == null) ? 0 : alertMode.hashCode()) + ((subscriber == null) ? 0 : subscriber.hashCode());
	}
	
	@Override
	public String toString() {
		return "(template: " + templateId + ", notification service: " + notificationService + ", query: " + queryId + ", result: " + resultId + ", alert mode: " + alertMode + ", subscriber: " + subscriber + ")";
	}
}
