function validateZabbixParams(requiredParams, allParams) {
	requiredParams.forEach(function (field) {
		if (typeof allParams !== 'object' || typeof allParams[field] === 'undefined' || allParams[field] === '') {
			throw 'Required param is not set: ' + field + '.';
		}
	});
}

function Dell(service, action, params) {
	this.zabbixLogPrefix = '[ DELL ] [ ' + service + ' ] [ ' + action + ' ]';
	this.request = new HttpRequest();

	this.executeRequest = function (apiPath) {
		this.request.addHeader('Authorization: Basic ' + btoa(params['user'] + ':' + params['password']));

		if (params['http_proxy']) {
			this.request.setProxy(params['http_proxy']);
			Zabbix.log(4, this.zabbixLogPrefix + ' Using http proxy: ' + params['http_proxy']);
		}

		const response = this.request.get(params['url'] + apiPath);

		this.request.clearHeader();

		if (this.request.getStatus() === parseInt(params['http_status_code'])) {
			return response;
		} else {
			Zabbix.log(3, this.zabbixLogPrefix + ' Unexpected HTTP response code: ' + this.request.getStatus());
			throw 'Unexpected HTTP response code: ' + this.request.getStatus();
		}
	};

	this.extractData = function (data, keys, skipParse) {
		if (!skipParse) {
			try {
				data = JSON.parse(data);
			} catch (error) {
				Zabbix.log(3, this.zabbixLogPrefix + ' Could not parse the received JSON object: ' + data);
				throw 'Could not parse received JSON object. See logs for more information.';
			}	
		}

		if (Array.isArray(keys)) {
			var returnBuffer = {};

			for (keyIdx = 0, keysLength = keys.length; keyIdx < keysLength; keyIdx++) {
				if (keys[keyIdx]['path'] === '@odata.id') {
					returnBuffer[keys[keyIdx]['name']] = data[keys[keyIdx]['path']];
				} else {
					returnBuffer[keys[keyIdx]['name']] = this.parseJSON(data, keys[keyIdx]['path'].split('.'));
				}
			}

			return returnBuffer;
		} else if (typeof keys === 'object') {
			return { [keys['name']]: this.parseJSON(data, keys['path'].split('.')) };
		} else if (typeof keys === 'string') {
			return this.parseJSON(data, keys.split('.'));
		} else {
			throw 'Unexpected key type';
		}
	};

	this.parseJSON = function (data, jsonPath) {
		for (var i = 0, args = jsonPath.length; i < args; i++) {
			data = data[jsonPath[i]];
		}

		return data;
	}
}

function formatPSU(psuObj) {
	var foundPowerSupplies = [],
		buffer = [];

	psuObj.forEach(function (obj) {
		const psuName = obj['name'].split(' ')[0];

		if (foundPowerSupplies.indexOf(psuName) === -1) {
			foundPowerSupplies.push(psuName);
			buffer.push({
				'name': psuName,
				[obj['type'].toLowerCase()]: {'reading': obj['reading'], 'health': obj['health']}
			});
		} else {
			buffer.forEach(function (bufferObj) {

				if (bufferObj['name'] === psuName) {
					bufferObj[obj['type'].toLowerCase()] = {'reading': obj['reading'], 'health': obj['health']};

					return;
				}
			});
		}
	})
	return buffer;
};

function formatTemp(tempObj) {
	tempObj.forEach(function (obj) {
		obj.name = obj.name.split(' ').slice(0, -1).join(' ');
	});

	return tempObj;
}

function formatSysBoard(sysObj) {
	const remove = ['System', 'Board', 'Usage'];

	sysObj.forEach(function (obj) {
		var buffer = [];

		obj['name'].split(' ').forEach(function (word) {
			var match = false;

			remove.forEach(function (removeWord) {
				if (removeWord === word) {
					match = true;
				}
			});

			if (!match) {
				buffer.push(word);
			}
		});

		if (buffer.length > 0) {
			obj['name'] = buffer.join(' ');
		}
	});

	return sysObj;
}


const params = JSON.parse(value);

validateZabbixParams(['url', 'user', 'password', 'http_status_code'], params);
var dell = new Dell('Sensor', 'Discovery', params);

const sensors = dell.extractData(dell.executeRequest('/redfish/v1/Chassis/System.Embedded.1/Sensors?$expand=.($levels=1)'), 'Members');

if (!Array.isArray(sensors)) {
	throw 'Unexpected type for sensors.';
}

const keys = [
	{
		'name': 'id',
		'path': 'Id'
	},
	{
		'name': 'name',
		'path': 'Name'
	},
	{
		'name': 'context',
		'path': 'PhysicalContext'
	},
	{
		'name': 'reading',
		'path': 'Reading'
	},
	{
		'name': 'type',
		'path': 'ReadingType'
	},
	{
		'name': 'health',
		'path': 'Status.Health'
	}
];

var buffer = { 'fan': [], 'psu': [], 'temperature': [], 'sysBoard': [] };

sensors.forEach(function (sensor) {
	if (sensor['Name'].substring(0, 2) === 'PS' && sensor['PhysicalContext'] === 'PowerSupply') {
		buffer['psu'].push(dell.extractData(sensor, keys, true));
	} else if (sensor['ReadingType'] === 'Temperature') {
		buffer['temperature'].push(dell.extractData(sensor, keys, true));
	} else if (sensor['Name'].includes('Fan') && sensor['ReadingType'] === 'Rotational') {
		buffer['fan'].push(dell.extractData(sensor, keys, true));
	} else if (sensor['Name'].includes('System Board') && sensor['ReadingType'] === 'Percent') {
		buffer['sysBoard'].push(dell.extractData(sensor, keys, true));
	}
});

buffer['psu'] = formatPSU(buffer['psu']);
buffer['temperature'] = formatTemp(buffer['temperature']);
buffer['sysBoard'] = formatSysBoard(buffer['sysBoard']);

return JSON.stringify(buffer);