XMUtil = {};

var CALLBACKS;
var DEDUPLICATION_FILTER_NAME;
var DEFAULT_LANGUAGE_SUFFIX = 'en';
var XMATTERS_DOMAIN;

(function(){

	XMUtil.deduplicate = function(data, filter) {
		var dedupFilter = DEDUPLICATION_FILTER_NAME;
		if (filter) {
			dedupFilter = filter;
		}

		var apxml = data, apxmlMsg = true;
		if (data instanceof Object) {
			apxml = APXML.fromJsObject(data);
			apxmlMsg = false;
		}

		if (APXML.dedup(apxml, dedupFilter)) {
			if (apxmlMsg) {
			    IALOG.warn(
				    "An event with tokens {0} has been injected into the {1} event domain "  +
					"more frequently than allowed by the deduplication filter {2}. It has been suppressed.",
					APXML.toString(apxml),
					apxml.getValue("agent_client_id"),
					dedupFilter
					);
			}
			else {
				IALOG.warn(
					"An event with properties {0} has been injected into the {1} service "  +
					"more frequently than allowed by the deduplication filter {2}. It has been suppressed.",
					JSON.stringify(data, null, 2),
					ServiceAPI.getConfiguration().getName(),
					dedupFilter
					);
			}
			return true;
		}
		return false
	};

	XMUtil.deduplicator = {};
	XMUtil.deduplicator.isDuplicate = function(data, filter) {
		var dedupFilter = DEDUPLICATION_FILTER_NAME;
		if (filter) {
			dedupFilter = filter;
		}
		var apxml = data, apxmlMsg = true;
		if (data instanceof Object) {
			apxml = APXML.fromJsObject(data);
			apxmlMsg = false;
		}

		return (APXML.isDuplicateOccurrence(apxml, dedupFilter));
	};

	/**
	 * Register the event occurrence with the deduplicating filter, but do not issue warnings if it is a duplicate.
	 */
	XMUtil.deduplicator.incrementCount = function(data, filter) {
		var dedupFilter = DEDUPLICATION_FILTER_NAME;
		if (filter) {
			dedupFilter = filter;
		}

		var apxml = data, apxmlMsg = true;
		if (data instanceof Object) {
			apxml = APXML.fromJsObject(data);
			apxmlMsg = false;
		}

		APXML.dedup(apxml, dedupFilter);
	};

	XMUtil.createEventTemplate = function(callbacks, integrationservice) {
		var config = ServiceAPI.getConfiguration(),
		    cb = CALLBACKS,
		    event = {},
		    is;

		if (callbacks) {
			cb = callbacks;
		}

		if (integrationservice) {
			is = integrationservice;
		}
		else {
			is = String(config.getName());
		}

		if (cb) {
			var iaId = String(config.getAgentId());
			event.callbacks = [];
			for ( var i in cb ) {
				event.callbacks[i] = {
				    'url' : 'ia://' + is,
				    'type': cb[i],
				    'iaId': iaId
				}
			}
		}
		return event;
	};

// ----------------------------------------------------------------------------------------------------
// Function to terminate events in xMatters using xm-api
//   See https://help.xmatters.com/xmAPI/index.html#events for more details
// Parameters
// 	filterProperties 	- REQUIRED, a json object whose keys are "propertyName" and values are their
// 										 	respective values. Only supports text properties at this time (due to language
// 										 	suffix addition)
// 	languageSuffix 		- OPTIONAL, the language suffix appended to property names to filter events.
// 											Will default to DEFAULT_LANGUAGE_SUFFIX ('en' by default)
// 	xMattersDomain 		- OPTIONAL, the xMatters Hostname to send requests to. It is expected to
// 											take the form https://<company>.xmatters.com with the protocol and without a
// 											trailing '/'. If unset, it falls back to the value of the XMATTERS_DOMAIN 
// 											variable (the	same format applies). If that variable is also not set, it 
// 											attempts to infer the value from the WEB_SERVER_URL (defined in xmio.js) 
// 											which is widely used to define the Inbound Integration that will be used
// 											to create events.
// ----------------------------------------------------------------------------------------------------
	XMUtil.terminateEvents = function (filterProperties, languageSuffix, xMattersDomain) {
		IALOG.debug("Entering XMUtil.terminateEvents()");
		var baseUrl;
		try {
			var response = {
				success: false,
			};
			if (xMattersDomain) {
				baseUrl = xMattersDomain;
				IALOG.debug('XMUtil.terminateEvents: Using method parameter as xMatters baseUrl: ' + baseUrl);
			} else if (XMATTERS_DOMAIN) {
				baseUrl = XMATTERS_DOMAIN;
				IALOG.debug('XMUtil.terminateEvents: Using XMATTERS_DOMAIN as xMatters baseUrl: ' + baseUrl);
			} else if (WEB_SERVER_URL && (WEB_SERVER_URL.indexOf("/api") > 0 || WEB_SERVER_URL.indexOf("/reapi") > 0)) {
				var endIndex = WEB_SERVER_URL.indexOf("/api") || WEB_SERVER_URL.indexOf("/reapi");
				baseUrl = WEB_SERVER_URL.substring(0, endIndex);
				IALOG.debug('XMUtil.terminateEvents: Using domain of WEB_SERVER_URL as xMatters baseUrl: ' + baseUrl);
			} else {
				IALOG.warn('XMUtil.terminateEvents: Unable to determine the xMatters baseUrl -- Bypassing terminate events');
				response.reason = 'NO_XMATTERS_DOMAIN';
				return response;
			}
			var lang = languageSuffix || DEFAULT_LANGUAGE_SUFFIX;

			var filterPropertyKeys = Object.keys(filterProperties);
			var propertyNames = [];
			var propertyValues = [];
			for (var i = 0; i < filterPropertyKeys.length; i++) {
				var key = filterPropertyKeys[i];
				var propName = encodeURIComponent(key + "#" + lang);
				var propVal = encodeURIComponent(filterProperties[key]);
				IALOG.debug("Adding Key: " + key + " - " + propName + "=" + propVal);
				propertyNames.push(propName);
				propertyValues.push(propVal);
			}

			//get event by property value
	    var getEventsURL = baseUrl + "/api/xm/1/events";
	    getEventsURL += "?status=ACTIVE,SUSPENDED"; // add status filter
	    getEventsURL += "&propertyName=" + propertyNames.join(",");
	    getEventsURL += "&propertyValue=" + propertyValues.join(",");
			IALOG.debug("XMUtil.terminateEvents: Performing GET to " + getEventsURL);
			var xmGetResponse = XMIO.get(getEventsURL);
			IALOG.debug("XMUtil.terminateEvents: XMIO returned response.body: " + xmGetResponse.body);
	    var xmEvents = JSON.parse(xmGetResponse.body).data;
	    IALOG.info("XMUtil.terminateEvents: Found " + xmEvents.length + " xMatters events to terminate");

	    for (var i = 0; i < xmEvents.length; i++) {
	    	var event = xmEvents[i];
	      var postEventsURL = baseUrl + "/api/xm/1/events";
	      var postBody = JSON.stringify({
	        id: event.id,
	        status: "TERMINATED"
	      });
	      IALOG.debug('XMUTIL.terminateEvents: Terminating xMatters Event ' + event.eventId + ' [' + event.priority + '|' + event.status + '].');
	      XMIO.post(postBody, postEventsURL);
	    }
	    response.success = true;
	    response.data = XMUtil.convertJavaObjectToJSON(xmGetResponse.body);
	    response.status = xmGetResponse.status;
	    return response;
		} catch (err) {
			var errMessageStart = "terminateEventByProperty - Error querying xMOD " + baseUrl + " with filter: " + JSON.stringify(filterProperties);
			IALOG.error(errMessageStart + " (message): " + err.message);
			IALOG.error(errMessageStart + " (stack): " + err.stack);
			response.reason = 'ERROR';
			response.error = err.message;
			return response;
		}
		IALOG.debug("Exiting XMUtil.terminateEvents()");
	}
	
	/**
	 * Helper to convert a Java object to its JSON representation
	 * 
	 * @param  {object} obj A Java object
	 * @return {object}     A pure JSON object
	 */
	XMUtil.convertJavaObjectToJSON = function(obj) {
		return JSON.parse("" + obj.toString());
	}

	XMUtil.parseXML = function(string) {
	    string = "" + string;
	    string = string.replace(/<\?(.*?)\?>/g,'');
	    return new XML(string.trim());
	}
})();
