var AzureCosmosDB = {
	params: {},
	token: null,

	setParams: function (params) {
		['app_id', 'password', 'tenant_id', 'subscription_id', 'resource_id'].forEach(function (field) {
			if (typeof params !== 'object' || typeof params[field] === 'undefined' || params[field] === '') {
				throw 'Required param is not set: ' + field + '.';
			}
		});

		AzureCosmosDB.params = params;
	},

	login: function () {
		var response, login = new HttpRequest();
		if (typeof AzureCosmosDB.params.proxy !== 'undefined' && AzureCosmosDB.params.proxy !== '') {
			login.setProxy(AzureCosmosDB.params.proxy);
		}
		login.addHeader('Content-Type: application/x-www-form-urlencoded');
		response = login.post(
			'https://login.microsoftonline.com/' + encodeURIComponent(AzureCosmosDB.params.tenant_id) + '/oauth2/token',
			'grant_type=client_credentials&resource=' + encodeURIComponent('https://management.azure.com/') + '&client_id=' + encodeURIComponent(AzureCosmosDB.params.app_id) + '&client_secret=' + encodeURIComponent(AzureCosmosDB.params.password)
		);

		if (login.getStatus() !== 200) {
			throw 'Login failed with status code ' + login.getStatus() + ': ' + response;
		}
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw 'Failed to parse login session response.';
		}
		if (!response.hasOwnProperty('access_token')) {
			throw 'Authentication response does not contain access token.';
		}
		AzureCosmosDB.token = response['access_token'];
	},

	request: function (url) {
		var response, request = new HttpRequest();
		if (typeof AzureCosmosDB.params.proxy !== 'undefined' && AzureCosmosDB.params.proxy !== '') {
			request.setProxy(AzureCosmosDB.params.proxy);
		}
		if (!AzureCosmosDB.token) {
			throw 'Request does not contain access token.';
		}
		request.addHeader('Accept: application/json');
		request.addHeader('Authorization: Bearer ' + AzureCosmosDB.token);
		Zabbix.log(4, '[ AzureCosmosDB ] 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.';
		}
	},

	getField: function (data, path) {
		var steps = path.split('.');
		for (var i = 0; i < steps.length; i++) {
			var step = steps[i];
			if (typeof data !== 'object' || typeof data[step] === 'undefined') {
				throw 'Required field was not found: ' + path;
			}

			data = data[step];
		}

		return data;
	},

	getMetricsData: function () {
		var data = {};
		start_date = new Date((new Date().getTime()) - 600000).toISOString().replace(/\.\d+/, '');
		end_date = new Date(new Date().getTime()).toISOString().replace(/\.\d+/, '');
		endpoints = {
			'availability': '/providers/Microsoft.Insights/metrics?metricnames=ServiceAvailability&api-version=2021-05-01&interval=PT1H&timespan=' + encodeURIComponent(start_date) + '/' + encodeURIComponent(end_date),
			'requests': '/providers/Microsoft.Insights/metrics?metricnames=DataUsage,IndexUsage,DocumentQuota,AvailableStorage,DocumentCount,NormalizedRUConsumption,PhysicalPartitionThroughputInfo,PhysicalPartitionSizeInfo,AutoscaleMaxThroughput,ProvisionedThroughput,TotalRequests,TotalRequestUnits,MetadataRequests,MongoRequests,MongoRequestCharge,ServerSideLatency,ServerSideLatencyGateway,ServerSideLatencyDirect,ReplicationLatency&api-version=2021-05-01&timespan=' + encodeURIComponent(start_date) + '/' + encodeURIComponent(end_date),
		};

		Object.keys(endpoints).forEach(function (field) {
			data[field] = {};
			try {
				metrics = AzureCosmosDB.request('https://management.azure.com' + AzureCosmosDB.params.resource_id + endpoints[field]);
				if (!metrics.hasOwnProperty('value')) {
					throw 'Failed getting required field. Check debug log for more information.';
				}

				for (k in metrics.value) {
					key = AzureCosmosDB.getField(metrics.value[k], 'name.value')
					if (metrics.value[k].timeseries.length === 0) {
						metrics.value[k].timeseries.push({ 'data': ['nodata'] })
					}
					data[field][key] = AzureCosmosDB.getField(metrics.value[k], 'timeseries.0.data.0');
				}
			}
			catch (error) {
				data.error = error.toString();
			}
		});
		return data
	}

};

try {
	AzureCosmosDB.setParams(JSON.parse(value));
	AzureCosmosDB.login();
	return JSON.stringify(AzureCosmosDB.getMetricsData());
}
catch (error) {
	error += (String(error).endsWith('.')) ? '' : '.';
	Zabbix.log(3, '[ AzureCosmosDB ] ERROR: ' + error);
	return JSON.stringify({ 'error': error });
}