"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.npm2hashicorp = exports.hashicorp2npm = void 0;
const logger_1 = require("../../../logger");
const regex_1 = require("../../../util/regex");
/**
 * This can convert most hashicorp ranges to valid npm syntax
 * The `!=` syntax is currently unsupported as there is no direct
 * equivalent in npm and isn't widely used
 * Also prerelease syntax is less well-defined for hashicorp and will
 * cause issues if it is not semvar compatible as no attempts to convert it
 * are made
 */
function hashicorp2npm(input) {
    return input
        .split(',')
        .map((single) => {
        const r = single.match((0, regex_1.regEx)(/^\s*(|=|!=|>|<|>=|<=|~>)\s*v?((\d+)(\.\d+){0,2}[\w-+]*(\.\d+)*)\s*$/));
        if (!r) {
            logger_1.logger.warn({ constraint: input, element: single }, 'Invalid hashicorp constraint');
            throw new Error('Invalid hashicorp constraint');
        }
        if (r[1] === '!=') {
            logger_1.logger.warn({ constraint: input, element: single }, 'Unsupported hashicorp constraint');
            throw new Error('Unsupported hashicorp constraint');
        }
        return {
            operator: r[1],
            version: r[2],
        };
    })
        .map(({ operator, version }) => {
        switch (operator) {
            case '=':
                return version;
            case '~>':
                if (version.match((0, regex_1.regEx)(/^\d+$/))) {
                    return `>=${version}`;
                }
                if (version.match((0, regex_1.regEx)(/^\d+\.\d+$/))) {
                    return `^${version}`;
                }
                return `~${version}`;
            default:
                return `${operator}${version}`;
        }
    })
        .join(' ');
}
exports.hashicorp2npm = hashicorp2npm;
/**
 * This can convert a limited set of npm range syntax to hashicorp,
 * it supports all the syntax that hashicorp2npm can output
 * It cannot handle `*`, `1.x.x`, range with `-`, `||`
 */
function npm2hashicorp(input) {
    return input
        .split(' ')
        .map((single) => {
        const r = single.match((0, regex_1.regEx)(/^(|>|<|>=|<=|~|\^)v?((\d+)(\.\d+){0,2}[\w-]*(\.\d+)*)$/));
        if (!r) {
            throw new Error('invalid npm constraint');
        }
        return {
            operator: r[1],
            version: r[2],
        };
    })
        .map(({ operator, version }) => {
        switch (operator) {
            case '^': {
                if (version.match((0, regex_1.regEx)(/^\d+$/))) {
                    return `~> ${version}.0`;
                }
                const withZero = version.match((0, regex_1.regEx)(/^(\d+\.\d+)\.0$/));
                if (withZero) {
                    return `~> ${withZero[1]}`;
                }
                const nonZero = version.match((0, regex_1.regEx)(/^(\d+\.\d+)\.\d+$/));
                if (nonZero) {
                    // not including`>= ${version}`, which makes this less accurate
                    // but makes the results cleaner
                    return `~> ${nonZero[1]}`;
                }
                return `~> ${version}`;
            }
            case '~':
                if (version.match((0, regex_1.regEx)(/^\d+$/))) {
                    return `~> ${version}.0`;
                }
                if (version.match((0, regex_1.regEx)(/^\d+\.\d+$/))) {
                    return `~> ${version}.0`;
                }
                return `~> ${version}`;
            case '':
                return `${version}`;
            default:
                return `${operator} ${version}`;
        }
    })
        .join(', ');
}
exports.npm2hashicorp = npm2hashicorp;
//# sourceMappingURL=convertor.js.map