"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.updateArtifacts = exports.getPipenvConstraint = exports.getPythonConstraint = void 0;
const shlex_1 = require("shlex");
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 schema_1 = require("./schema");
function getPythonConstraint(existingLockFileContent, config) {
    const { constraints = {} } = config;
    const { python } = constraints;
    if (python) {
        logger_1.logger.debug('Using python constraint from config');
        return python;
    }
    try {
        const result = schema_1.PipfileLockSchema.safeParse(JSON.parse(existingLockFileContent));
        // istanbul ignore if: not easily testable
        if (!result.success) {
            logger_1.logger.warn({ error: result.error }, 'Invalid Pipfile.lock');
            return undefined;
        }
        if (result.data._meta?.requires?.python_version) {
            const pythonVersion = result.data._meta.requires.python_version;
            return `== ${pythonVersion}.*`;
        }
        if (result.data._meta?.requires?.python_full_version) {
            const pythonFullVersion = result.data._meta.requires.python_full_version;
            return `== ${pythonFullVersion}`;
        }
    }
    catch (err) {
        // Do nothing
    }
    return undefined;
}
exports.getPythonConstraint = getPythonConstraint;
function getPipenvConstraint(existingLockFileContent, config) {
    const { constraints = {} } = config;
    const { pipenv } = constraints;
    if (pipenv) {
        logger_1.logger.debug('Using pipenv constraint from config');
        return pipenv;
    }
    try {
        const result = schema_1.PipfileLockSchema.safeParse(JSON.parse(existingLockFileContent));
        // istanbul ignore if: not easily testable
        if (!result.success) {
            logger_1.logger.warn({ error: result.error }, 'Invalid Pipfile.lock');
            return '';
        }
        if (result.data.default?.pipenv?.version) {
            return result.data.default.pipenv.version;
        }
        if (result.data.develop?.pipenv?.version) {
            return result.data.develop.pipenv.version;
        }
    }
    catch (err) {
        // Do nothing
    }
    return '';
}
exports.getPipenvConstraint = getPipenvConstraint;
async function updateArtifacts({ packageFileName: pipfileName, newPackageFileContent: newPipfileContent, config, }) {
    logger_1.logger.debug(`pipenv.updateArtifacts(${pipfileName})`);
    const lockFileName = pipfileName + '.lock';
    const existingLockFileContent = await (0, fs_1.readLocalFile)(lockFileName, 'utf8');
    if (!existingLockFileContent) {
        logger_1.logger.debug('No Pipfile.lock found');
        return null;
    }
    try {
        await (0, fs_1.writeLocalFile)(pipfileName, newPipfileContent);
        if (config.isLockFileMaintenance) {
            await (0, fs_1.deleteLocalFile)(lockFileName);
        }
        const cmd = 'pipenv lock';
        const tagConstraint = getPythonConstraint(existingLockFileContent, config);
        const pipenvConstraint = getPipenvConstraint(existingLockFileContent, config);
        const execOptions = {
            cwdFile: pipfileName,
            extraEnv: {
                PIPENV_CACHE_DIR: await (0, fs_1.ensureCacheDir)('pipenv'),
                PIP_CACHE_DIR: await (0, fs_1.ensureCacheDir)('pip'),
            },
            docker: {},
            preCommands: [`pip install --user ${(0, shlex_1.quote)(`pipenv${pipenvConstraint}`)}`],
            toolConstraints: [
                {
                    toolName: 'python',
                    constraint: tagConstraint,
                },
            ],
        };
        logger_1.logger.trace({ cmd }, 'pipenv lock command');
        await (0, exec_1.exec)(cmd, execOptions);
        const status = await (0, git_1.getRepoStatus)();
        if (!status?.modified.includes(lockFileName)) {
            return null;
        }
        logger_1.logger.debug('Returning updated Pipfile.lock');
        return [
            {
                file: {
                    type: 'addition',
                    path: lockFileName,
                    contents: await (0, fs_1.readLocalFile)(lockFileName, 'utf8'),
                },
            },
        ];
    }
    catch (err) {
        // istanbul ignore if
        if (err.message === error_messages_1.TEMPORARY_ERROR) {
            throw err;
        }
        logger_1.logger.debug({ err }, 'Failed to update Pipfile.lock');
        return [
            {
                artifactError: {
                    lockFile: lockFileName,
                    stderr: err.message,
                },
            },
        ];
    }
}
exports.updateArtifacts = updateArtifacts;
//# sourceMappingURL=artifacts.js.map