"use strict";
/*
 * Copyright OpenSearch Contributors
 * SPDX-License-Identifier: Apache-2.0
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.divisionByZeroDetector = void 0;
const rule_index_1 = require("../rule_index");
const range_utils_1 = require("../range_utils");
// PPL groups MODULE ('%') with DIVIDE ('/') in binaryArithmetic; both return
// null silently when the right operand is zero.
const ZERO_DIVISOR_OPERATORS = new Set(['/', '%']);
function isZeroLiteral(raw) {
    let text = raw.trim();
    while (text.startsWith('(') && text.endsWith(')')) {
        text = text.slice(1, -1).trim();
    }
    if (text.startsWith('+') || text.startsWith('-')) {
        text = text.slice(1).trim();
    }
    return /^(?:[0-9]+(?:\.[0-9]*)?|\.[0-9]+)$/.test(text) && Number(text) === 0;
}
const divisionByZeroDetector = (tree, config, _context, ruleNameToIndex) => {
    const diagnostics = [];
    const valueExpressions = (0, rule_index_1.findAllDescendantsByRule)(tree, ruleNameToIndex, 'valueExpression');
    for (const node of valueExpressions) {
        const children = node.children ?? [];
        for (let i = 0; i < children.length; i++) {
            const child = children[i];
            if (!(0, rule_index_1.isTerminalNode)(child) || !ZERO_DIVISOR_OPERATORS.has(child.getText())) {
                continue;
            }
            const divisor = children.slice(i + 1).find(rule_index_1.isRuleNode);
            if (divisor && isZeroLiteral(divisor.getText())) {
                diagnostics.push({
                    ruleId: config.id,
                    severity: config.severity,
                    message: config.message,
                    range: (0, range_utils_1.rangeFromContext)(divisor),
                    docUrl: config.docUrl,
                    hoverFacts: { literal: divisor.getText() },
                });
            }
        }
    }
    return diagnostics;
};
exports.divisionByZeroDetector = divisionByZeroDetector;
//# sourceMappingURL=division_by_zero.js.map