"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getDatasourceFor = getDatasourceFor;
exports.getDefaultVersioning = getDefaultVersioning;
exports.isGetPkgReleasesConfig = isGetPkgReleasesConfig;
exports.applyVersionCompatibility = applyVersionCompatibility;
exports.applyExtractVersion = applyExtractVersion;
exports.filterValidVersions = filterValidVersions;
exports.sortAndRemoveDuplicates = sortAndRemoveDuplicates;
exports.applyConstraintsFiltering = applyConstraintsFiltering;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const logger_1 = require("../../logger");
const filter_map_1 = require("../../util/filter-map");
const regex_1 = require("../../util/regex");
const versioning_1 = require("../versioning");
const allVersioning = tslib_1.__importStar(require("../versioning"));
const api_1 = tslib_1.__importDefault(require("./api"));
const custom_1 = require("./custom");
function getDatasourceFor(datasource) {
    if (datasource?.startsWith('custom.')) {
        return getDatasourceFor(custom_1.CustomDatasource.id);
    }
    return api_1.default.get(datasource) ?? null;
}
function getDefaultVersioning(datasourceName) {
    if (!datasourceName) {
        return versioning_1.defaultVersioning.id;
    }
    const datasource = getDatasourceFor(datasourceName);
    if (!datasource) {
        logger_1.logger.warn({ datasourceName }, 'Missing datasource!');
        return versioning_1.defaultVersioning.id;
    }
    if (!datasource.defaultVersioning) {
        return versioning_1.defaultVersioning.id;
    }
    return datasource.defaultVersioning;
}
function isGetPkgReleasesConfig(input) {
    return (is_1.default.nonEmptyStringAndNotWhitespace(input.datasource) &&
        is_1.default.nonEmptyStringAndNotWhitespace(input.packageName));
}
function applyVersionCompatibility(releaseResult, versionCompatibility, currentCompatibility) {
    if (!versionCompatibility) {
        return releaseResult;
    }
    const versionCompatibilityRegEx = (0, regex_1.regEx)(versionCompatibility);
    releaseResult.releases = (0, filter_map_1.filterMap)(releaseResult.releases, (release) => {
        const regexResult = versionCompatibilityRegEx.exec(release.version);
        if (!regexResult?.groups?.version) {
            logger_1.logger.trace({ releaseVersion: release.version, versionCompatibility }, 'versionCompatibility: Does not match regex');
            return null;
        }
        if (regexResult?.groups?.compatibility !== currentCompatibility) {
            logger_1.logger.trace({ releaseVersion: release.version, versionCompatibility }, 'versionCompatibility: Does not match compatibility');
            return null;
        }
        logger_1.logger.trace({
            releaseVersion: release.version,
            versionCompatibility,
            version: regexResult.groups.version,
            compatibility: regexResult.groups.compatibility,
        }, 'versionCompatibility: matches');
        release.version = regexResult.groups.version;
        return release;
    });
    return releaseResult;
}
function applyExtractVersion(releaseResult, extractVersion) {
    if (!extractVersion) {
        return releaseResult;
    }
    const extractVersionRegEx = (0, regex_1.regEx)(extractVersion);
    releaseResult.releases = (0, filter_map_1.filterMap)(releaseResult.releases, (release) => {
        const version = extractVersionRegEx.exec(release.version)?.groups?.version;
        if (!version) {
            return null;
        }
        release.version = version;
        return release;
    });
    return releaseResult;
}
function filterValidVersions(releaseResult, config) {
    const versioningName = config.versioning ?? getDefaultVersioning(config.datasource);
    const versioning = allVersioning.get(versioningName);
    releaseResult.releases = (0, filter_map_1.filterMap)(releaseResult.releases, (release) => versioning.isVersion(release.version) ? release : null);
    return releaseResult;
}
function sortAndRemoveDuplicates(releaseResult, config) {
    const versioningName = config.versioning ?? getDefaultVersioning(config.datasource);
    const versioning = allVersioning.get(versioningName);
    releaseResult.releases = releaseResult.releases.sort((a, b) => versioning.sortVersions(a.version, b.version));
    // Once releases are sorted, deduplication is straightforward and efficient
    let previousVersion = null;
    releaseResult.releases = (0, filter_map_1.filterMap)(releaseResult.releases, (release) => {
        if (previousVersion === release.version) {
            return null;
        }
        previousVersion = release.version;
        return release;
    });
    return releaseResult;
}
function applyConstraintsFiltering(releaseResult, config) {
    if (config?.constraintsFiltering !== 'strict') {
        for (const release of releaseResult.releases) {
            delete release.constraints;
        }
        return releaseResult;
    }
    const versioningName = config.versioning ?? getDefaultVersioning(config.datasource);
    const versioning = allVersioning.get(versioningName);
    const configConstraints = config.constraints;
    const filteredReleases = [];
    const startingLength = releaseResult.releases.length;
    releaseResult.releases = (0, filter_map_1.filterMap)(releaseResult.releases, (release) => {
        const releaseConstraints = release.constraints;
        delete release.constraints;
        if (!configConstraints || !releaseConstraints) {
            return release;
        }
        for (const [name, configConstraint] of Object.entries(configConstraints)) {
            if (!versioning.isValid(configConstraint)) {
                logger_1.logger.once.warn({
                    packageName: config.packageName,
                    constraint: configConstraint,
                    versioning: versioningName,
                }, 'Invalid constraint used with strict constraintsFiltering');
                continue;
            }
            const constraint = releaseConstraints[name];
            if (!is_1.default.nonEmptyArray(constraint)) {
                // A release with no constraints is OK
                continue;
            }
            let satisfiesConstraints = false;
            for (const releaseConstraint of constraint) {
                if (!releaseConstraint) {
                    satisfiesConstraints = true;
                    logger_1.logger.once.debug({
                        packageName: config.packageName,
                        versioning: versioningName,
                        constraint: releaseConstraint,
                    }, 'Undefined release constraint');
                    break;
                }
                if (!versioning.isValid(releaseConstraint)) {
                    logger_1.logger.once.debug({
                        packageName: config.packageName,
                        versioning: versioningName,
                        constraint: releaseConstraint,
                    }, 'Invalid release constraint');
                    break;
                }
                if (configConstraint === releaseConstraint) {
                    satisfiesConstraints = true;
                    break;
                }
                if (versioning.subset?.(configConstraint, releaseConstraint)) {
                    satisfiesConstraints = true;
                    break;
                }
                if (versioning.matches(configConstraint, releaseConstraint)) {
                    satisfiesConstraints = true;
                    break;
                }
            }
            if (!satisfiesConstraints) {
                filteredReleases.push(release.version);
                return null;
            }
        }
        return release;
    });
    if (filteredReleases.length) {
        const count = filteredReleases.length;
        const packageName = config.packageName;
        const releases = filteredReleases.join(', ');
        logger_1.logger.debug(`Filtered out ${count} non-matching releases out of ${startingLength} total for ${packageName} due to constraintsFiltering=strict: ${releases}`);
    }
    return releaseResult;
}
//# sourceMappingURL=common.js.map