var token = value;

function getField(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 "' + path + '" is not present in data received.';
		}
		data = data[step];
	}
	return data;
}

function getFieldBool(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') {
			return false;
		}
		data = data[step];
	}
	return true;
}

function getHttpData(url, token) {
	var request = new HttpRequest(),
		proxy = '{$GCP.PROXY}';
	if (proxy !== '{' + '$GCP.PROXY}' && proxy !== '') {
		request.setProxy(proxy);
	};
	request.addHeader('Authorization: Bearer ' + token);
	request.addHeader('Content-Type: application/json');

	var response = request.get(url);

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

	if (response !== null) {
		try {
			response = JSON.parse(response);
		}
		catch (error) {
			throw 'Failed to parse response received from GCP API. Check debug log for more information.';
		}
	}

	if (typeof response !== 'object' || response === null) {
		throw 'Cannot process response data: received data is not an object. Check debug log for more information.';
	}

	if (request.getStatus() !== 200) {
		if (typeof (response.error && response.error.message) !== 'undefined') {
			throw response.error.message;
		}
		else {
			throw 'Failed to receive data: invalid response status code. Check debug log for more information.';
		}
	}
	return response;
};

var project = '{$GCP.PROJECT.ID}';

if (!project || project === '{' + '$GCP.PROJECT.ID}') {
	throw 'Error. Set the \{$GCP.PROJECT.ID\} macro value.';
}

var inst_raw = getHttpData('https://sqladmin.googleapis.com/sql/v1beta4/projects/' + project + '/instances', token);

if (Object.keys(inst_raw).length === 0) {
	return '[]';
}

return JSON.stringify(getField(inst_raw, 'items').map(function (sql_inst) {
	obj = {
		name: getField(sql_inst, 'name'),
		token: value,
		zone: getField(sql_inst, 'settings.locationPreference.zone'),
		inst_type: getField(sql_inst, 'instanceType'),
		tier: getField(sql_inst, 'settings.tier'),
		project_id: getField(sql_inst, 'project'),
		db_type: getField(sql_inst, 'databaseInstalledVersion')
	};

	obj.high_availability = (sql_inst.failoverReplica) ? true : false;

	if (obj.db_type.match(/SQLSERVER*/)) {
		var mssql_audit = getField(sql_inst, 'settings.sqlServerAuditConfig');

		obj.audited = (mssql_audit.bucket) ? true : false;
	}

	if (obj.inst_type === 'READ_REPLICA_INSTANCE') {
		obj.master = getField(sql_inst, 'masterInstanceName');
	}

	if (Array.isArray(sql_inst.ipAddresses)) {
		var int_addresses = sql_inst.ipAddresses.filter(function (addr) {
			return addr.type === 'PRIVATE';
		});

		var ext_addresses = sql_inst.ipAddresses.filter(function (addr) {
			return addr.type === 'PRIMARY';
		});

		obj.ip = getFieldBool(int_addresses, '0.ipAddress') ? int_addresses[0].ipAddress : '0.0.0.0';
		obj.ext_ip = getFieldBool(ext_addresses, '0.ipAddress') ? ext_addresses[0].ipAddress : '0.0.0.0';
	}
	else {
		obj.ip = '0.0.0.0';
		obj.ext_ip = '0.0.0.0';
	}

	return obj;
}));