function parseFilters(filter) {
    var pairs = {};

    filter.split(/\\s*,\\s*/).forEach(function (kv) {
        if (/([\\w\\.-]+\\/[\\w\\.-]+):\\s*.+/.test(kv)) {
            var pair = kv.split(/\\s*:\\s*/);
            pairs[pair[0]] = pair[1];
        }
    });

    return pairs;
}

function filter(name, data, filters) {
    var filtered = true;

    if (typeof data === 'object') {
        Object.keys(filters).some(function (filter) {
            var exclude = filter.match(/^!(.+)/);
            if (filter in data || (exclude && exclude[1] in data)) {
                if ((exclude && new RegExp(filters[filter]).test(data[exclude[1]]))
                    || (!exclude && !(new RegExp(filters[filter]).test(data[filter])))) {
                    Zabbix.log(4, '[ Kubernetes discovery ] Discarded "' + name + '" by filter "' + filter + ': ' + filters[filter] + '"');

                    filtered = false;
                    return true;
                }
            };
        });
    }

    return filtered;
}

try {
    var input = JSON.parse(value),
        output = [];

    if (typeof input !== 'object' || typeof input.items === 'undefined') {
        Zabbix.log(4, '[ Kubernetes ] Received incorrect JSON: ' + input);
        throw 'Incorrect JSON. Check debug log for more information.';
    }

    var filterLabels = parseFilters('{$KUBE.NODE.FILTER.LABELS}'),
        filterAnnotations = parseFilters('{$KUBE.NODE.FILTER.ANNOTATIONS}');

    input.items.forEach(function (node) {
        if (filter(node.metadata.name, node.metadata.labels, filterLabels)
            && filter(node.metadata.name, node.metadata.annotations, filterAnnotations)) {
            Zabbix.log(4, '[ Kubernetes discovery ] Filtered node "' + node.metadata.name + '"');

            var internalIPs = node.status.addresses.filter(function (addr) {
                return addr.type === 'InternalIP';
            });

            var internalIP = internalIPs.length && internalIPs[0].address;

            if (internalIP in input.endpointIPs) {
                output.push({
                    '{#NAME}': node.metadata.name,
                    '{#IP}': internalIP,
                    '{#ROLES}': node.status.roles,
                    '{#ARCH}': node.metadata.labels['kubernetes.io/arch'] || '',
                    '{#OS}': node.metadata.labels['kubernetes.io/os'] || ''
                });
            }
            else {
                Zabbix.log(4, '[ Kubernetes discovery ] Node "' + node.metadata.name + '" is not included in the list of endpoint IPs');
            }
        }
    });

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