"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateArtifacts = exports.updateBuildFile = void 0;
const tslib_1 = require("tslib");
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const good_enough_parser_1 = require("good-enough-parser");
const shlex_1 = require("shlex");
const upath_1 = require("upath");
const error_messages_1 = require("../../../constants/error-messages");
const logger_1 = require("../../../logger");
const exec_1 = require("../../../util/exec");
const fs_1 = require("../../../util/fs");
const git_1 = require("../../../util/git");
const http_1 = require("../../../util/http");
const regex_1 = require("../../../util/regex");
const string_1 = require("../../../util/string");
const utils_1 = require("./utils");
const http = new http_1.Http('gradle-wrapper');
const groovy = good_enough_parser_1.lang.createLang('groovy');
async function addIfUpdated(status, fileProjectPath) {
    if (status.modified.includes(fileProjectPath)) {
        return {
            file: {
                type: 'addition',
                path: fileProjectPath,
                contents: await (0, fs_1.readLocalFile)(fileProjectPath),
            },
        };
    }
    return null;
}
function getDistributionUrl(newPackageFileContent) {
    const distributionUrlLine = newPackageFileContent
        .split(regex_1.newlineRegex)
        .find((line) => line.startsWith('distributionUrl='));
    if (distributionUrlLine) {
        return distributionUrlLine
            .replace('distributionUrl=', '')
            .replace('https\\:', 'https:');
    }
    return null;
}
async function getDistributionChecksum(url) {
    const { body } = await http.get(`${url}.sha256`);
    return body;
}
async function updateBuildFile(localGradleDir, wrapperProperties) {
    let buildFileName = (0, upath_1.join)(localGradleDir, 'build.gradle');
    if (!(await (0, fs_1.localPathExists)(buildFileName))) {
        buildFileName = (0, upath_1.join)(localGradleDir, 'build.gradle.kts');
    }
    const buildFileContent = await (0, fs_1.readLocalFile)(buildFileName, 'utf8');
    if (!buildFileContent) {
        logger_1.logger.debug('build.gradle or build.gradle.kts not found');
        return buildFileName;
    }
    let buildFileUpdated = buildFileContent;
    for (const [propertyName, newValue] of Object.entries(wrapperProperties)) {
        if (!newValue) {
            continue;
        }
        const query = good_enough_parser_1.query.tree({
            type: 'wrapped-tree',
            maxDepth: 1,
            search: good_enough_parser_1.query
                .sym(propertyName)
                .op('=')
                .str((ctx, { value, offset }) => {
                buildFileUpdated = (0, string_1.replaceAt)(buildFileUpdated, offset, value, newValue);
                return ctx;
            }),
        });
        groovy.query(buildFileUpdated, query, []);
    }
    await (0, fs_1.writeLocalFile)(buildFileName, buildFileUpdated);
    return buildFileName;
}
exports.updateBuildFile = updateBuildFile;
async function updateArtifacts({ packageFileName, newPackageFileContent, updatedDeps, config, }) {
    try {
        logger_1.logger.debug({ updatedDeps }, 'gradle-wrapper.updateArtifacts()');
        const localGradleDir = (0, upath_1.join)((0, upath_1.dirname)(packageFileName), '../../');
        const gradlewFile = (0, upath_1.join)(localGradleDir, (0, utils_1.gradleWrapperFileName)());
        let cmd = await (0, utils_1.prepareGradleCommand)(gradlewFile);
        if (!cmd) {
            logger_1.logger.info('No gradlew found - skipping Artifacts update');
            return null;
        }
        cmd += ' wrapper';
        let checksum = null;
        const distributionUrl = getDistributionUrl(newPackageFileContent);
        if (distributionUrl) {
            cmd += ` --gradle-distribution-url ${distributionUrl}`;
            if (newPackageFileContent.includes('distributionSha256Sum=')) {
                //update checksum in case of distributionSha256Sum in properties then run wrapper
                checksum = await getDistributionChecksum(distributionUrl);
                await (0, fs_1.writeLocalFile)(packageFileName, newPackageFileContent.replace(/distributionSha256Sum=.*/, `distributionSha256Sum=${checksum}`));
                cmd += ` --gradle-distribution-sha256-sum ${(0, shlex_1.quote)(checksum)}`;
            }
        }
        else {
            cmd += ` --gradle-version ${(0, shlex_1.quote)(config.newValue)}`;
        }
        logger_1.logger.debug(`Updating gradle wrapper: "${cmd}"`);
        const execOptions = {
            cwdFile: gradlewFile,
            docker: {
                image: 'sidecar',
            },
            extraEnv: utils_1.extraEnv,
            toolConstraints: [
                {
                    toolName: 'java',
                    constraint: config.constraints?.java ?? (0, utils_1.getJavaConstraint)(config.currentValue),
                },
            ],
        };
        try {
            await (0, exec_1.exec)(cmd, execOptions);
        }
        catch (err) {
            // istanbul ignore if
            if (err.message === error_messages_1.TEMPORARY_ERROR) {
                throw err;
            }
            logger_1.logger.warn({ err }, 'Error executing gradle wrapper update command. It can be not a critical one though.');
        }
        const buildFileName = await updateBuildFile(localGradleDir, {
            gradleVersion: config.newValue,
            distributionSha256Sum: checksum,
            distributionUrl,
        });
        const status = await (0, git_1.getRepoStatus)();
        const artifactFileNames = [
            packageFileName,
            buildFileName,
            ...['gradle/wrapper/gradle-wrapper.jar', 'gradlew', 'gradlew.bat'].map((filename) => (0, upath_1.join)(localGradleDir, filename)),
        ];
        const updateArtifactsResult = (await Promise.all(artifactFileNames.map((fileProjectPath) => addIfUpdated(status, fileProjectPath)))).filter(is_1.default.truthy);
        logger_1.logger.debug({ files: updateArtifactsResult.map((r) => r.file?.path) }, `Returning updated gradle-wrapper files`);
        return updateArtifactsResult;
    }
    catch (err) {
        logger_1.logger.debug({ err }, 'Error setting new Gradle Wrapper release value');
        return [
            {
                artifactError: {
                    lockFile: packageFileName,
                    stderr: err.message,
                },
            },
        ];
    }
}
exports.updateArtifacts = updateArtifacts;
//# sourceMappingURL=artifacts.js.map