var Kube = {
	params: {},

	setParams: function (params) {
		['api_url', 'api_token', 'state_endpoint_name'].forEach(function (field) {
			if (typeof params !== 'object' || typeof params[field] === 'undefined'
				|| params[field] === '') {
				throw 'Required param is not set: "' + field + '".';
			}
		});

		Kube.params = params;
		if (typeof Kube.params.api_url === 'string' && !Kube.params.api_url.endsWith('/')) {
			Kube.params.api_url += '/';
		}
	},

	apiRequest: function (query) {
		var request = new HttpRequest(),
			response,
			url = encodeURI(Kube.params.api_url + query);

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

		request.addHeader('Content-Type: application/json');
		request.addHeader('Authorization: Bearer ' + Kube.params.api_token);

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

		if (Kube.params.http_proxy) {
			Zabbix.log(4, '[ Kubernetes ] Using http proxy: ' + Kube.params.http_proxy);
		}

		response = request.get(url);

		Zabbix.log(4, '[ Kubernetes ] Received response with status code ' + request.getStatus() + ': ' + response);

		if (request.getStatus() < 200 || request.getStatus() >= 300) {
			throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
		}
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw 'Failed to parse response received from Kubernetes API. Check debug log for more information.';
		}
		return response;
	},

	getEndpoint: function (ep) {
		if (typeof ep.subsets[0].addresses !== 'undefined') {
			var scheme,
				addr,
				port;
			ep.subsets.forEach(function (subset) {
				var lp = subset.ports.filter(function (port) {
					if (port.name !== 'http' &&
						port.name !== 'https' &&
						port.name !== 'https-main') {
						return false;
					}
					scheme = port.name.match(/https?/);
					return true;
				})
				if (lp.length) {
					port = lp[0].port
					addr = subset.addresses[0].ip
				}
			})
			return {
				scheme: scheme || 'http',
				address: addr || ep.subsets[0].addresses[0].ip,
				port: port || 8080
			}
		}
	},

	getMetricsEndpoint: function () {
		var result = Kube.apiRequest('api/v1/endpoints'),
			endpoint = [];

		if (typeof result !== 'object'
			|| typeof result.items === 'undefined') {
			throw 'Cannot get endpoints from Kubernetes API. Check debug log for more information.';
		};

		result.items.forEach(function (ep) {
			if (ep.metadata.name === Kube.params.state_endpoint_name && Array.isArray(ep.subsets)) {
				endpoint.push(Kube.getEndpoint(ep));
			}
			if (typeof Kube.params.openshift_endpoint_name !== 'undefined' && Kube.params.openshift_endpoint_name !== ''
				&& ep.metadata.name === Kube.params.openshift_endpoint_name && Array.isArray(ep.subsets)) {
				endpoint.push(Kube.getEndpoint(ep));
			}
		});
		if (endpoint.length === 0) {
			throw 'Cannot get state metrics endpoints from Kubernetes API. Check debug log for more information.';
		}
		return endpoint;
	},

	getStateMetrics: function () {
		var metrics_endpoint = Kube.getMetricsEndpoint(),
			IPv4 = /(?:\d{1,3}\.){3}\d{1,3}/,
			result = '',
			request = new HttpRequest();

		request.addHeader('Content-Type: application/json');
		request.addHeader('Authorization: Bearer ' + Kube.params.api_token);

		if (typeof Kube.params.http_proxy !== 'undefined' && Kube.params.http_proxy !== '') {
			request.setProxy(Kube.params.http_proxy);
			Zabbix.log(4, '[ Kubernetes ] Using http proxy: ' + Kube.params.http_proxy);
		}

		metrics_endpoint.forEach(function (endpoint) {
			var url = endpoint.scheme + '://' + (IPv4.test(endpoint.address) ? endpoint.address : '[' + endpoint.address + ']') + ':' + endpoint.port + '/metrics';

			Zabbix.log(4, '[ Kubernetes ] Sending request: ' + url);
			response = request.get(url);
			Zabbix.log(4, '[ Kubernetes ] Received response with status code ' + request.getStatus() + ': ' + response);

			if (request.getStatus() < 200 || request.getStatus() >= 300) {
				throw 'Request failed with status code ' + request.getStatus() + ': ' + response;
			}
			if (response === null) {
				throw 'Failed to get state metrics. Check debug log for more information.';
			}
			result += response + '\n';
		}
		);

		return result;

	}
};

try {
	Kube.setParams(JSON.parse(value));

	var stateMetrics = Kube.getStateMetrics();

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