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

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

    request: function (query) {
        var response,
            request = new HttpRequest(),
            url = Consul.params.api_endpoint + query;

        request.addHeader('Content-Type: application/json');
        request.addHeader('X-Consul-Token: ' + Consul.params.token);

        Zabbix.log(4, '[ Consul ] Sending request: ' + url);
        response = request.get(url);

        Zabbix.log(4, '[ Consul ] 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 Consul Agent API.';
            }
        }

        return {
            status: request.getStatus(),
            response: response
        };
    },

    getServices: function () {
        var result = Consul.request('v1/agent/services'),
            services = [];

        if (typeof result.response !== 'object' || result.status != 200) {
            throw 'Cannot get service list from Consul Agent API.';
        }

        Object.keys(result.response).forEach(function (service) {
            services.push(result.response[service]['ID']);
        });

        return services;
    },

    getServiceStats: function (service_id) {
        var result = Consul.request('v1/agent/health/service/id/' + service_id);

        if (typeof result.response !== 'object' || [200, 429, 503].indexOf(result.status) === -1) {
            throw 'Cannot get service info from Consul Agent API.';
        }

        return result.response;
    }
}

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

    var services = Consul.getServices(),
        result = [];

    services.forEach(function (service) {
        var service_stats = Consul.getServiceStats(service);

        result.push({
            'id': service,
            'name': service_stats['Service']['Service'],
            'status': service_stats['AggregatedStatus'],
            'checks': service_stats['Checks'],
            'namespace': typeof service_stats['Service']['Namespace'] === 'undefined' ? 'None' : service_stats['Service']['Namespace']
        });
    });

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

    return JSON.stringify({error: error + ' Check debug log for more information.'});
}