"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateDependency = void 0;
// TODO: types (#22198)
const logger_1 = require("../../../logger");
const regex_1 = require("../../../util/regex");
function getDepNameWithNoVersion(depName) {
    let depNameNoVersion = depName.split('/').slice(0, 3).join('/');
    if (depNameNoVersion.startsWith('gopkg.in')) {
        depNameNoVersion = depNameNoVersion.replace((0, regex_1.regEx)(/\.v\d+$/), '');
    }
    return depNameNoVersion;
}
function updateDependency({ fileContent, upgrade, }) {
    try {
        logger_1.logger.debug(`gomod.updateDependency: ${upgrade.newValue}`);
        const { depName, depType, updateType } = upgrade;
        if (updateType === 'replacement') {
            logger_1.logger.warn('gomod manager does not support replacement updates yet');
            return null;
        }
        // istanbul ignore if: should never happen
        if (!depName || !upgrade.managerData) {
            return null;
        }
        const depNameNoVersion = getDepNameWithNoVersion(depName);
        const lines = fileContent.split(regex_1.newlineRegex);
        const lineToChange = lines[upgrade.managerData.lineNumber];
        if (!lineToChange.includes(depNameNoVersion) &&
            !lineToChange.includes('rethinkdb/rethinkdb-go.v5')) {
            logger_1.logger.debug({ lineToChange, depName }, "go.mod current line doesn't contain dependency");
            return null;
        }
        let updateLineExp;
        if (depType === 'golang') {
            updateLineExp = (0, regex_1.regEx)(/(?<depPart>go)(?<divider>\s+)[^\s]+/);
        }
        if (depType === 'replace') {
            if (upgrade.managerData.multiLine) {
                updateLineExp = (0, regex_1.regEx)(/^(?<depPart>\s+[^\s]+[\s]+[=][>]+\s+)(?<divider>[^\s]+\s+)[^\s]+/);
            }
            else {
                updateLineExp = (0, regex_1.regEx)(/^(?<depPart>replace\s+[^\s]+[\s]+[=][>]+\s+)(?<divider>[^\s]+\s+)[^\s]+/);
            }
        }
        else if (depType === 'require' || depType === 'indirect') {
            if (upgrade.managerData.multiLine) {
                updateLineExp = (0, regex_1.regEx)(/^(?<depPart>\s+[^\s]+)(?<divider>\s+)[^\s]+/);
            }
            else {
                updateLineExp = (0, regex_1.regEx)(/^(?<depPart>require\s+[^\s]+)(?<divider>\s+)[^\s]+/);
            }
        }
        if (updateLineExp && !updateLineExp.test(lineToChange)) {
            logger_1.logger.debug('No image line found');
            return null;
        }
        let newLine;
        if (upgrade.updateType === 'digest') {
            const newDigestRightSized = upgrade.newDigest.substring(0, upgrade.currentDigest.length);
            if (lineToChange.includes(newDigestRightSized)) {
                return fileContent;
            }
            logger_1.logger.debug({ depName, lineToChange, newDigestRightSized }, 'gomod: need to update digest');
            newLine = lineToChange.replace(
            // TODO: can be undefined? (#22198)
            updateLineExp, `$<depPart>$<divider>${newDigestRightSized}`);
        }
        else {
            newLine = lineToChange.replace(
            // TODO: can be undefined? (#22198)
            updateLineExp, `$<depPart>$<divider>${upgrade.newValue}`);
        }
        if (upgrade.updateType === 'major') {
            logger_1.logger.debug(`gomod: major update for ${depName}`);
            if (depName.startsWith('gopkg.in/')) {
                const oldV = depName.split('.').pop();
                newLine = newLine.replace(`.${oldV}`, `.v${upgrade.newMajor}`);
                // Package renames - I couldn't think of a better place to do this
                newLine = newLine.replace('gorethink/gorethink.v5', 'rethinkdb/rethinkdb-go.v5');
            }
            else if (upgrade.newMajor > 1 &&
                !newLine.includes(`/v${upgrade.newMajor}`) &&
                !upgrade.newValue.endsWith('+incompatible')) {
                if (depName === depNameNoVersion) {
                    // If package currently has no version, pin to latest one.
                    newLine = newLine.replace(depName, `${depName}/v${upgrade.newMajor}`);
                }
                else {
                    // Replace version
                    const [oldV] = upgrade.currentValue.split('.');
                    newLine = newLine.replace((0, regex_1.regEx)(`/${oldV}(\\s+)`, undefined, false), `/v${upgrade.newMajor}$1`);
                }
            }
        }
        if (lineToChange.endsWith('+incompatible') &&
            !upgrade.newValue?.endsWith('+incompatible')) {
            let toAdd = '+incompatible';
            if (upgrade.updateType === 'major' && upgrade.newMajor >= 2) {
                toAdd = '';
            }
            newLine += toAdd;
        }
        if (newLine === lineToChange) {
            logger_1.logger.debug('No changes necessary');
            return fileContent;
        }
        if (depType === 'indirect') {
            newLine = newLine.replace((0, regex_1.regEx)(/\s*(?:\/\/\s*indirect(?:\s*;)?\s*)*$/), ' // indirect');
        }
        lines[upgrade.managerData.lineNumber] = newLine;
        return lines.join('\n');
    }
    catch (err) {
        logger_1.logger.debug({ err }, 'Error setting new go.mod version');
        return null;
    }
}
exports.updateDependency = updateDependency;
//# sourceMappingURL=update.js.map