"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isUUID = exports.configRegexPredicate = exports.isConfigRegex = exports.newlineRegex = exports.escapeRegExp = exports.regEx = exports.regexEngineStatus = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const error_messages_1 = require("../constants/error-messages");
const expose_cjs_1 = require("../expose.cjs");
const cache = new Map();
let status;
let RegEx = RegExp;
// istanbul ignore next
if (process.env.RENOVATE_X_IGNORE_RE2) {
    status = { type: 'ignored' };
}
else {
    try {
        const RE2 = (0, expose_cjs_1.re2)();
        // Test if native is working
        new RE2('.*').exec('test');
        RegEx = RE2;
        status = { type: 'available' };
    }
    catch (err) {
        status = { type: 'unavailable', err };
    }
}
exports.regexEngineStatus = status;
function regEx(pattern, flags, useCache = true) {
    let canBeCached = useCache;
    if (canBeCached && flags?.includes('g')) {
        canBeCached = false;
    }
    if (canBeCached && is_1.default.regExp(pattern) && pattern.flags.includes('g')) {
        canBeCached = false;
    }
    const key = flags ? `${pattern.toString()}:${flags}` : pattern.toString();
    if (canBeCached) {
        const cachedResult = cache.get(key);
        if (cachedResult) {
            return cachedResult;
        }
    }
    try {
        const instance = flags ? new RegEx(pattern, flags) : new RegEx(pattern);
        if (canBeCached) {
            cache.set(key, instance);
        }
        return instance;
    }
    catch (err) {
        const error = new Error(error_messages_1.CONFIG_VALIDATION);
        error.validationMessage = err.message;
        error.validationSource = pattern.toString();
        error.validationError = `Invalid regular expression (re2): ${pattern.toString()}`;
        throw error;
    }
}
exports.regEx = regEx;
function escapeRegExp(input) {
    return input.replace(regEx(/[.*+\-?^${}()|[\]\\]/g), '\\$&'); // $& means the whole matched string
}
exports.escapeRegExp = escapeRegExp;
exports.newlineRegex = regEx(/\r?\n/);
const configValStart = regEx(/^!?\//);
const configValEnd = regEx(/\/i?$/);
function isConfigRegex(input) {
    return (is_1.default.string(input) && configValStart.test(input) && configValEnd.test(input));
}
exports.isConfigRegex = isConfigRegex;
function parseConfigRegex(input) {
    try {
        const regexString = input
            .replace(configValStart, '')
            .replace(configValEnd, '');
        return input.endsWith('i') ? regEx(regexString, 'i') : regEx(regexString);
    }
    catch (err) {
        // no-op
    }
    return null;
}
function configRegexPredicate(input) {
    if (isConfigRegex(input)) {
        const configRegex = parseConfigRegex(input);
        if (configRegex) {
            const isPositive = !input.startsWith('!');
            return (x) => {
                const res = configRegex.test(x);
                return isPositive ? res : !res;
            };
        }
    }
    return null;
}
exports.configRegexPredicate = configRegexPredicate;
const UUIDRegex = regEx(/^\{[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\}$/i);
function isUUID(input) {
    return UUIDRegex.test(input);
}
exports.isUUID = isUUID;
//# sourceMappingURL=regex.js.map