"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getJavaConstraint = exports.updateArtifacts = void 0;
const tslib_1 = require("tslib");
const os_1 = tslib_1.__importDefault(require("os"));
const is_1 = tslib_1.__importDefault(require("@sindresorhus/is"));
const upath_1 = require("upath");
const global_1 = require("../../../config/global");
const logger_1 = require("../../../logger");
const exec_1 = require("../../../util/exec");
const fs_1 = require("../../../util/fs");
const git_1 = require("../../../util/git");
const regex_1 = require("../../../util/regex");
const maven_1 = tslib_1.__importDefault(require("../../versioning/maven"));
const DEFAULT_MAVEN_REPO_URL = 'https://repo.maven.apache.org/maven2';
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;
}
async function updateArtifacts({ packageFileName, newPackageFileContent, updatedDeps, config, }) {
    try {
        logger_1.logger.debug({ updatedDeps }, 'maven-wrapper.updateArtifacts()');
        if (!updatedDeps.some((dep) => dep.depName === 'maven-wrapper')) {
            logger_1.logger.info('Maven wrapper version not updated - skipping Artifacts update');
            return null;
        }
        const cmd = await createWrapperCommand(packageFileName);
        if (!cmd) {
            logger_1.logger.info('No mvnw found - skipping Artifacts update');
            return null;
        }
        const extraEnv = getExtraEnvOptions(updatedDeps);
        await executeWrapperCommand(cmd, config, packageFileName, extraEnv);
        const status = await (0, git_1.getRepoStatus)();
        const artifactFileNames = [
            '.mvn/wrapper/maven-wrapper.properties',
            '.mvn/wrapper/maven-wrapper.jar',
            '.mvn/wrapper/MavenWrapperDownloader.java',
            'mvnw',
            'mvnw.cmd',
        ].map((filename) => packageFileName.replace('.mvn/wrapper/maven-wrapper.properties', '') +
            filename);
        const updateArtifactsResult = (await getUpdatedArtifacts(status, artifactFileNames)).filter(is_1.default.truthy);
        logger_1.logger.debug({ files: updateArtifactsResult.map((r) => r.file?.path) }, `Returning updated maven-wrapper files`);
        return updateArtifactsResult;
    }
    catch (err) {
        logger_1.logger.debug({ err }, 'Error setting new Maven Wrapper release value');
        return [
            {
                artifactError: {
                    lockFile: packageFileName,
                    stderr: err.message,
                },
            },
        ];
    }
}
exports.updateArtifacts = updateArtifacts;
async function getUpdatedArtifacts(status, artifactFileNames) {
    const updatedResults = [];
    for (const artifactFileName of artifactFileNames) {
        const updatedResult = await addIfUpdated(status, artifactFileName);
        if (updatedResult !== null) {
            updatedResults.push(updatedResult);
        }
    }
    return updatedResults;
}
/**
 * Find compatible java version for maven.
 * see https://maven.apache.org/developers/compatibility-plan.html
 * @param mavenWrapperVersion current maven version
 * @returns A Java semver range
 */
function getJavaConstraint(mavenWrapperVersion) {
    const major = mavenWrapperVersion
        ? maven_1.default.getMajor(mavenWrapperVersion)
        : null;
    if (major && major >= 3) {
        return '^17.0.0';
    }
    return '^8.0.0';
}
exports.getJavaConstraint = getJavaConstraint;
async function executeWrapperCommand(cmd, config, packageFileName, extraEnv) {
    logger_1.logger.debug(`Updating maven wrapper: "${cmd}"`);
    const { wrapperFullyQualifiedPath } = getMavenPaths(packageFileName);
    const execOptions = {
        cwdFile: wrapperFullyQualifiedPath,
        docker: {},
        extraEnv,
        toolConstraints: [
            {
                toolName: 'java',
                constraint: config.constraints?.java ?? getJavaConstraint(config.currentValue),
            },
        ],
    };
    try {
        await (0, exec_1.exec)(cmd, execOptions);
    }
    catch (err) {
        logger_1.logger.error({ err }, 'Error executing maven wrapper update command.');
        throw err;
    }
}
function getExtraEnvOptions(deps) {
    const customMavenWrapperUrl = getCustomMavenWrapperRepoUrl(deps);
    if (customMavenWrapperUrl) {
        return { MVNW_REPOURL: customMavenWrapperUrl };
    }
    return {};
}
function getCustomMavenWrapperRepoUrl(deps) {
    const replaceString = deps.find((dep) => dep.depName === 'maven-wrapper')?.replaceString;
    if (!replaceString) {
        return null;
    }
    const match = (0, regex_1.regEx)(/^(.*?)\/org\/apache\/maven\/wrapper\//).exec(replaceString);
    if (!match) {
        return null;
    }
    return match[1] === DEFAULT_MAVEN_REPO_URL ? null : match[1];
}
async function createWrapperCommand(packageFileName) {
    const { wrapperExecutableFileName, localProjectDir, wrapperFullyQualifiedPath, } = getMavenPaths(packageFileName);
    return await prepareCommand(wrapperExecutableFileName, localProjectDir, await (0, fs_1.statLocalFile)(wrapperFullyQualifiedPath), 'wrapper:wrapper');
}
function mavenWrapperFileName() {
    if (os_1.default.platform() === 'win32' &&
        global_1.GlobalConfig.get('binarySource') !== 'docker') {
        return 'mvnw.cmd';
    }
    return './mvnw';
}
function getMavenPaths(packageFileName) {
    const wrapperExecutableFileName = mavenWrapperFileName();
    const localProjectDir = (0, upath_1.join)((0, upath_1.dirname)(packageFileName), '../../');
    const wrapperFullyQualifiedPath = (0, upath_1.join)(localProjectDir, wrapperExecutableFileName);
    return {
        wrapperExecutableFileName,
        localProjectDir,
        wrapperFullyQualifiedPath,
    };
}
async function prepareCommand(fileName, cwd, pathFileStats, args) {
    // istanbul ignore if
    if (pathFileStats?.isFile() === true) {
        // if the file is not executable by others
        if (os_1.default.platform() !== 'win32' && (pathFileStats.mode & 0o1) === 0) {
            // add the execution permission to the owner, group and others
            logger_1.logger.warn('Maven wrapper is missing the executable bit');
            await (0, fs_1.chmodLocalFile)((0, upath_1.join)(cwd, fileName), pathFileStats.mode | 0o111);
        }
        if (args === null) {
            return fileName;
        }
        return `${fileName} ${args}`;
    }
    return null;
}
//# sourceMappingURL=artifacts.js.map