var Express = {
    params: [],

    setParams: function (params) {
        if (typeof params !== 'object') {
            return;
        }

        Express.params = params;

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

    setProxy: function (HTTPProxy) {
        Express.HTTPProxy = HTTPProxy;
    },

    request: function (query, data) {
        var response,
            url = Express.params.url + query,
            request = new CurlHttpRequest();

        request.AddHeader('Content-Type: application/json');
        request.AddHeader('Authorization: Bearer ' + Express.params.token);

        if (typeof Express.HTTPProxy !== 'undefined' && Express.HTTPProxy !== '') {
            request.SetProxy(Express.HTTPProxy);
        }

        if (typeof data !== 'undefined') {
            data = JSON.stringify(data);
        }

        Zabbix.Log(4, '[ Express Webhook ] Sending request: ' + url +
            ((typeof data === 'string') ? ('\n' + data) : ''));

        response = request.Post(url, data);

        Zabbix.Log(4, '[ Express Webhook ] Received response with status code ' +
            request.Status() + '\n' + response);

        if (response !== null) {
            try {
                response = JSON.parse(response);
            }
            catch (error) {
                Zabbix.Log(4, '[ Express Webhook ] Failed to parse response received from Express');
                response = {};
            }
        }

        if (response.status !== 'ok') {
            var message = 'Request failed with status code ' + request.Status();

            if (typeof response.reason !== 'undefined') {
                message += ': ' + JSON.stringify(response.reason);
            }

            throw message + '. Check debug log for more information.';
        }

        return response.result;
    },

    postMessage: function (is_problem) {
        var data,
            url,
            result = {tags: {}},
            response;

        if (is_problem) {
            data = {
                group_chat_id: Express.params.send_to,
                notification: {
                    status: 'ok',
                    body: Express.params.message
                }
            };
            url = 'api/v3/botx/notification/callback/direct';
        }
        else {
            data = {
                reply: {
                    status: 'ok',
                    body: Express.params.message
                }
            };
            url = 'api/v3/botx/events/reply_event';

            try {
                var tags = JSON.parse(Express.params.tags);
            }
            catch (error) {
                throw 'Value of "express_tags" is not JSON. Value: ' + Express.params.tags + '.';
            }

            tags.forEach(function(tag) {
                if (tag.tag === '__zbx_ex_sync_id_' + Express.params.send_to) {
                    data.source_sync_id = tag.value;
                }
            });

            if (!data.source_sync_id) {
                throw 'Cannot update data. sync_id for the provided sender is unknown.';
            }
        }

        response = Express.request(url, data);

        if (is_problem && response.sync_id) {
            result.tags['__zbx_ex_sync_id_' + Express.params.send_to] = response.sync_id;

            return JSON.stringify(result);
        }
        else {
            return 'OK';
        }
    }
};

try {
    var params = JSON.parse(value),
        express = {},
        required_params = [
            'express_url', 'express_send_to', 'express_message', 'express_tags', 'express_token',
            'event_source', 'event_value', 'event_update_status'
        ];

    Object.keys(params)
        .forEach(function (key) {
            if (key.startsWith('express_')) {
                express[key.substring(8)] = params[key];
            }

            if (required_params.indexOf(key) !== -1
                    && (params[key].trim() === '' || params[key] === '{ALERT.SENDTO}')) {
                throw 'Parameter "' + key + '" can\'t be empty.';
            }
        });

    if ([0, 1, 2, 3].indexOf(parseInt(params.event_source)) === -1) {
        throw 'Incorrect "event_source" parameter given: ' + params.event_source + '\nMust be 0-3.';
    }

    // Forcing event_value and event_update_status for non trigger-based events.
    if (params.event_source !== '0' ) {
        params.event_value = '1';
        params.event_update_status = '0';
    }

    if (params.event_value !== '0' && params.event_value !== '1') {
        throw 'Incorrect "event_value" parameter given: ' + params.event_value + '\nMust be 0 or 1.';
    }

    // Check {EVENT.UPDATE.STATUS} only for trigger-based events.
    if (params.event_update_status !== '0' && params.event_update_status !== '1' && params.event_source === '0') {
        throw 'Incorrect "event_update_status" parameter given: ' + params.event_update_status + '\nMust be 0 or 1.';
    }

    Express.setParams(express);
    Express.setProxy(params.HTTPProxy);

    return Express.postMessage(params.event_value === '1' && params.event_update_status === '0');
}
catch (error) {
    Zabbix.Log(3, '[ Express Webhook ] ERROR: ' + error);
    throw 'Sending failed: ' + error;
}