var Cisco = {
	api_url: '{$CISCO.FTD.API.URL}',
	http_proxy: '{$CISCO.FTD.HTTP_PROXY}',

	getToken: function (params) {
		['access_token'].forEach(function (field) {
			if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
				throw 'Unexpected session token value has been received: ' + field + '.';
			}
		});
		Cisco.params = params;
	},

	getField: function (data, path, default_value) {
		var steps = path.split('.');
		var step = steps.shift();

		while (typeof step !== 'undefined') {
			if (typeof data === undefined || typeof data[step] === 'undefined') {
				return default_value;
			}

			data = data[step];
			step = steps.shift();
		}
		return data;
	},

	request: function (url) {

		var response,
			request = new HttpRequest();

		if (typeof Cisco.http_proxy !== 'undefined' && Cisco.http_proxy !== '') {
			request.setProxy(Cisco.http_proxy);
		}
		if (!Cisco.params.access_token) {
			throw 'Request does not contain access token.';
		}
		request.addHeader('Accept: application/json');
		request.addHeader('Content-Type: application/json');
		request.addHeader('Authorization: Bearer ' + Cisco.params.access_token);

		Zabbix.log(4, '[ Cisco ] request url: ' + url);

		response = request.get(url);

		if (request.getStatus() !== 200) {
			throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
		}

		try {
			return JSON.parse(response);
		}
		catch (error) {
			throw 'Failed to parse response received from API.';
		}
	},

	getMetricsData: function () {
		if (typeof Cisco.api_url === 'string' && !Cisco.api_url.endsWith('/')) {
			Cisco.api_url += '/';
		}

		metrics = Cisco.getField(Cisco.request(Cisco.api_url + 'devices/default/operational/metrics'), 'items');

		return metrics.map(function (data) {
			const idField = Cisco.getField(data, 'id', '');
			const parts = idField.split('.');

			const type = parts[0];
			const id = parts[1] || type;
			const metric = parts.length >= 3 ? parts.slice(2).join('.') : parts.slice(1).join('.');

			return {
				type,
				id,
				metric,
				name: Cisco.getField(data, 'name', ''),
				value: Cisco.getField(data, 'metric.value', null),
				status: Cisco.getField(data, 'metric.status'),
				mounted_on: Cisco.getField(data, 'mountedOn'),
				unit: Cisco.getField(data, 'metric.unit', '')
			};
		});

	}
};

try {
	Cisco.getToken(JSON.parse(value));

	return JSON.stringify(Cisco.getMetricsData());
}
catch (error) {
	error += (String(error).endsWith('.')) ? '' : '.';
	Zabbix.log(3, '[ Cisco ] ERROR: ' + error);

	return JSON.stringify({ 'error': error });
}