"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.api = exports.HermitVersioning = exports.supportsRanges = exports.urls = exports.displayName = exports.id = void 0;
const regex_1 = require("../regex");
exports.id = 'hermit';
exports.displayName = 'Hermit';
exports.urls = [
    'https://cashapp.github.io/hermit/packaging/reference/#versions',
];
exports.supportsRanges = false;
class HermitVersioning extends regex_1.RegExpVersioningApi {
    constructor() {
        super(HermitVersioning.versionRegex);
    }
    _isValid(version) {
        return super._parse(version) !== null;
    }
    _parseHermitVersioning(version) {
        const groups = this._config?.exec(version)?.groups;
        if (!groups) {
            return null;
        }
        const { major, minor, patch, supplement, build, prerelease, compatibility, } = groups;
        const release = [
            typeof major === 'undefined' ? 0 : Number.parseInt(major, 10),
            typeof minor === 'undefined' ? 0 : Number.parseInt(minor, 10),
            typeof patch === 'undefined' ? 0 : Number.parseInt(patch, 10),
            typeof supplement === 'undefined' ? 0 : Number.parseInt(supplement, 10),
        ];
        if (build) {
            release.push(Number.parseInt(build, 10));
        }
        return {
            release,
            prerelease,
            compatibility,
        };
    }
    _parse(version) {
        const parsed = this._parseHermitVersioning(version);
        if (parsed) {
            return parsed;
        }
        const channelVer = HermitVersioning._getChannel(version);
        const groups = this._config?.exec(channelVer)?.groups;
        if (!groups) {
            return null;
        }
        const { major, minor, patch, supplement, build, prerelease, compatibility, } = groups;
        const release = [];
        if (major) {
            release.push(Number.parseInt(major, 10));
        }
        if (minor) {
            release.push(Number.parseInt(minor, 10));
        }
        if (patch) {
            release.push(Number.parseInt(patch, 10));
        }
        if (supplement) {
            release.push(Number.parseInt(supplement, 10));
        }
        if (build) {
            release.push(Number.parseInt(build, 10));
        }
        return {
            release,
            prerelease,
            compatibility,
        };
    }
    static _isChannel(version) {
        return version.startsWith('@');
    }
    static _getChannel(version) {
        return version.substring(1);
    }
    isStable(version) {
        if (this._isValid(version)) {
            return super.isStable(version);
        }
        // channel and the rest should be considered unstable version
        // as channels are changing values
        return false;
    }
    isValid(version) {
        return this._isValid(version) || HermitVersioning._isChannel(version);
    }
    isLessThanRange(version, range) {
        return this._compare(version, range) < 0;
    }
    _compare(version, other) {
        if (this._isValid(version) && this._isValid(other)) {
            return super._compare(version, other);
        }
        const parsedVersion = this._parse(version);
        const parsedOther = this._parse(other);
        if (parsedVersion === null || parsedOther === null) {
            if (parsedVersion === null && parsedOther === null) {
                return version.localeCompare(other);
            }
            return parsedVersion === null ? -1 : 1;
        }
        const versionReleases = parsedVersion.release;
        const otherReleases = parsedOther.release;
        const maxLength = versionReleases.length > otherReleases.length
            ? versionReleases.length
            : otherReleases.length;
        for (let i = 0; i < maxLength; i++) {
            const verVal = versionReleases[i];
            const otherVal = otherReleases[i];
            if (verVal !== undefined &&
                otherVal !== undefined &&
                verVal !== otherVal) {
                return verVal - otherVal;
            }
            else if (verVal === undefined) {
                return 1;
            }
            else if (otherVal === undefined) {
                return -1;
            }
        }
        return 0;
    }
    matches(version, range) {
        return this.equals(version, range);
    }
}
exports.HermitVersioning = HermitVersioning;
// add <supplement> element to accomondate openjdk versioning defined in JEP322
// https://openjdk.org/jeps/322
HermitVersioning.versionRegex = '^(?<major>\\d+)(\\.(?<minor>\\d+))?(\\.(?<patch>\\d+))?(\\.(?<supplement>\\d+))?(_(?<build>\\d+))?([-]?(?<prerelease>[^.+][^+]*))?([+](?<compatibility>[^.-][^+]*))?$';
exports.api = HermitVersioning;
exports.default = exports.api;
//# sourceMappingURL=index.js.map