"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ltr = exports.parse = exports.stringifyRanges = exports.parseRanges = exports.satisfiesRange = void 0;
const ruby_semver_1 = require("@renovatebot/ruby-semver");
const requirement_js_1 = require("@renovatebot/ruby-semver/dist/ruby/requirement.js");
const version_js_1 = require("@renovatebot/ruby-semver/dist/ruby/version.js");
const logger_1 = require("../../../logger");
const regex_1 = require("../../../util/regex");
const operator_1 = require("./operator");
const parse = (range) => {
    const regExp = (0, regex_1.regEx)(/^(?<operator>[^\d\s]+)?(?<delimiter>\s*)(?<version>[0-9a-zA-Z-.]+)$/);
    const value = (range || '').trim();
    const match = regExp.exec(value);
    if (match?.groups) {
        const { version = '', operator = '', delimiter = ' ' } = match.groups;
        return { version, operator, delimiter };
    }
    return {
        version: '',
        operator: '',
        delimiter: ' ',
    };
};
exports.parse = parse;
/** Wrapper for {@link satisfies} for {@link Range} record. */
function satisfiesRange(ver, range) {
    if (range.companion) {
        return ((0, ruby_semver_1.satisfies)(ver, `${range.operator}${range.version}`) &&
            satisfiesRange(ver, range.companion));
    }
    else {
        return (0, ruby_semver_1.satisfies)(ver, `${range.operator}${range.version}`);
    }
}
exports.satisfiesRange = satisfiesRange;
/**
 * Parses a comma-delimited list of range parts,
 * with special treatment for a pair of `~>` and `>=` parts.
 */
function parseRanges(range) {
    const originalRanges = range.split(',').map(parse);
    const ranges = [];
    for (let i = 0; i < originalRanges.length;) {
        if (i + 1 < originalRanges.length &&
            originalRanges[i].operator === operator_1.PGTE &&
            originalRanges[i + 1].operator === operator_1.GTE) {
            ranges.push({
                ...originalRanges[i],
                companion: originalRanges[i + 1],
            });
            i += 2;
        }
        else {
            ranges.push(originalRanges[i]);
            i++;
        }
    }
    return ranges;
}
exports.parseRanges = parseRanges;
/**
 * Stringifies a list of range parts into a comma-separated string,
 * with special treatment for a pair of `~>` and `>=` parts.
 */
function stringifyRanges(ranges) {
    return ranges
        .map((r) => {
        if (r.companion) {
            return `${r.operator}${r.delimiter}${r.version}, ${r.companion.operator}${r.companion.delimiter}${r.companion.version}`;
        }
        else {
            return `${r.operator}${r.delimiter}${r.version}`;
        }
    })
        .join(', ');
}
exports.stringifyRanges = stringifyRanges;
const ltr = (version, range) => {
    const gemVersion = (0, version_js_1.create)(version);
    if (!gemVersion) {
        logger_1.logger.warn(`Invalid ruby version '${version}'`);
        return false;
    }
    const requirements = range.split(',').map(requirement_js_1.parse);
    const results = requirements.map(([operator, ver]) => {
        switch (operator) {
            case operator_1.GT:
            case operator_1.LT:
                return gemVersion.compare(ver) <= 0;
            case operator_1.GTE:
            case operator_1.LTE:
            case operator_1.EQUAL:
            case operator_1.NOT_EQUAL:
                return gemVersion.compare(ver) < 0;
            case operator_1.PGTE:
                return (gemVersion.compare(ver) < 0 &&
                    gemVersion.release().compare(ver.bump()) <= 0);
            // istanbul ignore next
            default:
                logger_1.logger.warn(`Unsupported operator '${operator}'`);
                return false;
        }
    });
    return results.reduce((accumulator, value) => accumulator && value, true);
};
exports.ltr = ltr;
//# sourceMappingURL=range.js.map