var params = JSON.parse(value);

var request = new HttpRequest();

request.addHeader('X-Cisco-Meraki-API-Key:' + params.token);
request.addHeader('User-Agent: ZabbixServer/1.2 Zabbix');

function parseTime(timeString) {
	var match = timeString.match(/^(\\d+)([h|m|s])$/);
	if (match) {
		var value = parseInt(match[1], 10);
		var unit = match[2];

		switch (unit) {
			case 'h':
				return value * 3600;
			case 'm':
				return value * 60;
			case 's':
				return value;
			default:
				return 0;
		}
	}

	return 0;
};

var response,
	error_msg = '',
	response = [],
	timespan;

	function getHttpData(url) {
		var startTime = new Date().getTime();
		var maxWait = parseInt(timespan, 10) * 1000;
		var waitFor = 1000;
	
		while (true) {
			response = request.get(url);
			Zabbix.log(4, '[ Meraki API ] [ ' + url + ' ] Received response with status code ' + request.getStatus() + ': ' + response);
	
			var status = request.getStatus();
	
			if (response !== null) {
				try {
					response = JSON.parse(response);
				}
				catch (error) {
					throw 'Failed to parse response received from Meraki API. Check debug log for more information.';
				}
			}
	
			if (status === 429 && response && response.errors && Array.isArray(response.errors) &&
				response.errors.indexOf("API rate limit exceeded for organization") !== -1) {
				var now = new Date().getTime();
				var headers = request.getHeaders(false);
	
				if ('Retry-After' in headers) {
					var retryAfter = headers['Retry-After'];
					Zabbix.log(4, '[ Meraki API ] API rate limit exceeded. Retrying after ' + retryAfter + ' seconds.');				 
					waitFor = parseInt(retryAfter) * 1000;
				}
				else {
					Zabbix.log(4, '[ Meraki API ] API rate limit exceeded. No Retry-After header. Retrying after 1 second.');
				}
				if (now - startTime + waitFor > maxWait) {
					throw 'Failed to receive data: API rate limit exceeded and retry timeout reached.';
				}
				Zabbix.sleep(waitFor);
				continue;
			}
	
			if (status !== 200) {
				if (response.errors) {
					throw response.errors.join(', ');
				}
				else {
					throw 'Failed to receive data: invalid response status code.';
				}
			}
	
			if (typeof (response) !== 'object' || response === null) {
				throw 'Cannot process response data: received data is not an object.';
			}
	
			return response;
		}
	};

try {

	if (params.token === '{' + '$MERAKI.TOKEN}') {
		throw 'Please change {' + '$MERAKI.TOKEN} macro to the proper value.';
	}

	if (params.url.indexOf('http://') === -1 && params.url.indexOf('https://') === -1) {
		params.url = 'https://' + params.url;
	}

	if (!params.url.endsWith('/')) {
		params.url += '/';
	}

	if (typeof params.httpproxy !== 'undefined' && params.httpproxy !== '') {
		request.setProxy(params.httpproxy);
	}

	timespan = parseTime('{$MERAKI.GET.STATUS.INTERVAL}');

	response = getHttpData(params.url + 'organizations/' + encodeURIComponent(params.organizationId) + '/devices/availabilities?serials[]=' + encodeURIComponent(params.serial));
	if (Array.isArray(response) & response.length > 0) {
		response = response[0]
	}

} catch (error) {
	error_msg = error;
};

return JSON.stringify({
	'data': response,
	'error': error_msg.toString()
});