"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.joinStringWithBindings = exports.combineDynamicBindings = exports.getDynamicBindings = exports.isExactBinding = exports.containsBindingsAnywhere = void 0;
exports.getDynamicStringSegments = getDynamicStringSegments;
const lodash_1 = require("lodash");
const DATA_BIND_REGEX = /{{([\s\S]*?)}}/;
// referencing DATA_BIND_REGEX fails for the value "{{Table1.tableData[Table1.selectedRowIndex]}}" if you run it multiple times and don't recreate
const containsBindingsAnywhere = (value) => DATA_BIND_REGEX.test(value);
exports.containsBindingsAnywhere = containsBindingsAnywhere;
/**
 * used to filter the output of `getDynamicStringSegments` for further processing, not a validator
 */
const isExactBinding = (value) => value.startsWith('{{') && value.endsWith('}}');
exports.isExactBinding = isExactBinding;
function getDynamicStringSegments(dynamicString) {
    return getDynamicStringSegmentsWithPositions(dynamicString).map((segment) => segment.str);
}
// See unit tests for examples
function getDynamicStringSegmentsWithPositions(inputString) {
    const tokens = [];
    let currentToken = '';
    let betweenBrackets = false;
    let sum = 0;
    for (let i = 0; i < inputString.length; i++) {
        if (inputString[i] === '{') {
            if (betweenBrackets) {
                currentToken += '{';
                sum++;
            }
            else if (inputString[i + 1] === '{') {
                if (currentToken.length > 0) {
                    tokens.push({
                        str: currentToken,
                        from: i - currentToken.length,
                        to: i
                    });
                }
                currentToken = '{{';
                betweenBrackets = true;
                sum = 0;
                i++; // Skip the second '{' character
            }
            else {
                currentToken += '{';
            }
        }
        else if (inputString[i] === '}') {
            if (betweenBrackets) {
                // Look for closing }} only when the brackets are balanced. This prevents bugs with {{{a: 1}}}
                // while it will fail for mismatched brackets like {{{a: 1}}
                if (sum === 0 && inputString[i + 1] === '}') {
                    currentToken += '}}';
                    i++; // Skip the second '}' character
                    tokens.push({
                        str: currentToken,
                        from: i - currentToken.length,
                        to: i
                    });
                    currentToken = '';
                    betweenBrackets = false;
                }
                else {
                    currentToken += '}';
                    sum = Math.max(sum - 1, 0);
                }
            }
            else {
                currentToken += '}';
                sum = Math.max(sum - 1, 0);
            }
        }
        else {
            currentToken += inputString[i];
        }
    }
    if (currentToken.length > 0) {
        tokens.push({
            str: currentToken,
            from: inputString.length - currentToken.length,
            to: inputString.length
        });
    }
    return tokens;
}
const getDynamicBindings = (dynamicString) => {
    // Protect against bad string parse
    if (!dynamicString || !(0, lodash_1.isString)(dynamicString)) {
        return { stringSegments: [], jsSnippets: [], positionedSnippets: [] };
    }
    // Get the {{binding}} bound values
    const stringSegments = getDynamicStringSegmentsWithPositions(dynamicString.trim());
    // Get the "binding" path values
    const paths = stringSegments.map((positionedSegment) => {
        const segment = positionedSegment.str;
        const length = segment.length;
        const matches = (0, exports.isExactBinding)(segment);
        if (matches) {
            return {
                str: segment.substring(2, length - 2),
                from: positionedSegment.from + 2,
                to: positionedSegment.from + length - 2
            };
        }
        return {
            str: '',
            from: 0,
            to: 0
        };
    });
    return {
        stringSegments: stringSegments.map((segment) => segment.str),
        jsSnippets: paths.map((path) => path.str),
        positionedSnippets: paths.filter((path) => path.str !== '')
    };
};
exports.getDynamicBindings = getDynamicBindings;
const combineDynamicBindings = (jsSnippets, stringSegments) => {
    return stringSegments
        .map((segment, index) => {
        if (jsSnippets[index] && jsSnippets[index].length > 0) {
            return jsSnippets[index];
        }
        else {
            return `'${segment}'`;
        }
    })
        .join(' + ');
};
exports.combineDynamicBindings = combineDynamicBindings;
const joinStringWithBindings = (segments) => {
    return segments.map((segment) => (segment.dynamic ? `{{${segment.value}}}` : segment.value)).join('');
};
exports.joinStringWithBindings = joinStringWithBindings;
//# sourceMappingURL=utils.js.map