"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.extractResolver = exports.updateArtifacts = exports.constructPipCompileCmd = void 0;
const tslib_1 = require("tslib");
const shlex_1 = require("shlex");
const upath_1 = tslib_1.__importDefault(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 regex_1 = require("../../../util/regex");
const common_1 = require("./common");
function constructPipCompileCmd(content, inputFileName, outputFileName) {
    const headers = common_1.constraintLineRegex.exec(content);
    const args = ['pip-compile'];
    if (headers?.groups) {
        logger_1.logger.debug(`Found pip-compile header: ${headers[0]}`);
        for (const argument of (0, shlex_1.split)(headers.groups.arguments)) {
            if (common_1.deprecatedAllowedPipArguments.includes(argument)) {
                args.push(argument);
            }
            else if (argument.startsWith('--output-file=')) {
                const file = upath_1.default.parse(outputFileName).base;
                if (argument !== `--output-file=${file}`) {
                    // we don't trust the user-supplied output-file argument; use our value here
                    logger_1.logger.warn({ argument }, 'pip-compile was previously executed with an unexpected `--output-file` filename');
                }
                args.push(`--output-file=${file}`);
            }
            else if (argument.startsWith('--resolver=')) {
                const value = extractResolver(argument);
                if (value) {
                    args.push(`--resolver=${value}`);
                }
            }
            else if (argument.startsWith('--')) {
                logger_1.logger.trace({ argument }, 'pip-compile argument is not (yet) supported');
            }
            else {
                // ignore position argument (.in file)
            }
        }
    }
    args.push(upath_1.default.parse(inputFileName).base);
    return args.map((argument) => (0, shlex_1.quote)(argument)).join(' ');
}
exports.constructPipCompileCmd = constructPipCompileCmd;
async function updateArtifacts({ packageFileName: inputFileName, newPackageFileContent: newInputContent, config, }) {
    const outputFileName = inputFileName.replace((0, regex_1.regEx)(/(\.in)?$/), '.txt');
    config.lockFiles = [outputFileName];
    // TODO: remove above and below line and use config.lockFiles directly in the next PR
    // istanbul ignore if
    if (!config.lockFiles) {
        logger_1.logger.warn({ packageFileName: inputFileName }, 'pip-compile: No lock files associated with a package file');
        return null;
    }
    logger_1.logger.debug(`pipCompile.updateArtifacts(${inputFileName}->${JSON.stringify(config.lockFiles)})`);
    const result = [];
    for (const outputFileName of config.lockFiles) {
        const existingOutput = await (0, fs_1.readLocalFile)(outputFileName, 'utf8');
        if (!existingOutput) {
            logger_1.logger.debug('pip-compile: No output file found');
            return null;
        }
        try {
            await (0, fs_1.writeLocalFile)(inputFileName, newInputContent);
            // TODO(not7cd): use --upgrade option instead deleting
            if (config.isLockFileMaintenance) {
                await (0, fs_1.deleteLocalFile)(outputFileName);
            }
            const cmd = constructPipCompileCmd(existingOutput, inputFileName, outputFileName);
            const execOptions = await (0, common_1.getExecOptions)(config, inputFileName);
            logger_1.logger.trace({ cmd }, 'pip-compile command');
            await (0, exec_1.exec)(cmd, execOptions);
            const status = await (0, git_1.getRepoStatus)();
            if (!status?.modified.includes(outputFileName)) {
                return null;
            }
            result.push({
                file: {
                    type: 'addition',
                    path: outputFileName,
                    contents: await (0, fs_1.readLocalFile)(outputFileName, 'utf8'),
                },
            });
        }
        catch (err) {
            // istanbul ignore if
            if (err.message === error_messages_1.TEMPORARY_ERROR) {
                throw err;
            }
            logger_1.logger.debug({ err }, 'pip-compile: Failed to run command');
            result.push({
                artifactError: {
                    lockFile: outputFileName,
                    stderr: err.message,
                },
            });
        }
    }
    logger_1.logger.debug('pip-compile: Returning updated output file(s)');
    return result;
}
exports.updateArtifacts = updateArtifacts;
function extractResolver(argument) {
    const value = argument.replace('--resolver=', '');
    if (['backtracking', 'legacy'].includes(value)) {
        return value;
    }
    logger_1.logger.warn({ argument }, 'pip-compile was previously executed with an unexpected `--resolver` value');
    return null;
}
exports.extractResolver = extractResolver;
//# sourceMappingURL=artifacts.js.map