"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sortPackageFiles = sortPackageFiles;
exports.generateMermaidGraph = generateMermaidGraph;
exports.inferCommandExecDir = inferCommandExecDir;
const tslib_1 = require("tslib");
const graph_data_structure_1 = require("graph-data-structure");
const upath_1 = tslib_1.__importDefault(require("upath"));
const logger_1 = require("../../../logger");
function sortPackageFiles(depsBetweenFiles, packageFiles) {
    const result = [];
    const graph = (0, graph_data_structure_1.Graph)();
    depsBetweenFiles.forEach(({ sourceFile, outputFile }) => {
        graph.addEdge(sourceFile, outputFile);
    });
    const sorted = graph.topologicalSort();
    for (const file of sorted) {
        if (packageFiles.has(file)) {
            const packageFile = packageFiles.get(file);
            const sortedLockFiles = [];
            // TODO(not7cd): this needs better test case
            for (const lockFile of packageFile.lockFiles) {
                if (sorted.includes(lockFile)) {
                    sortedLockFiles.push(lockFile);
                }
            }
            packageFile.lockFiles = sortedLockFiles;
            result.push(packageFile);
        }
    }
    // istanbul ignore if: should never happen
    if (result.length !== packageFiles.size) {
        throw new Error('Topological sort failed to include all package files');
    }
    return result;
}
function generateMermaidGraph(depsBetweenFiles, lockFileArgs) {
    const lockFiles = [];
    for (const lockFile of lockFileArgs.keys()) {
        // TODO: add extra args to the lock file ${extraArgs ? '\n' + extraArgs : ''}
        // const extraArgs = pipCompileArgs.extra
        //   ?.map((v) => '--extra=' + v)
        //   .join('\n');
        lockFiles.push(`  ${lockFile}[[${lockFile}]]`);
    }
    const edges = depsBetweenFiles.map(({ sourceFile, outputFile, type }) => {
        return `  ${sourceFile} -${type === 'constraint' ? '.' : ''}-> ${outputFile}`;
    });
    return `graph TD\n${lockFiles.join('\n')}\n${edges.join('\n')}`;
}
function inferCommandExecDir(outputFilePath, outputFileArg) {
    if (!outputFileArg) {
        // implicit output file is in the same directory where command was executed
        return upath_1.default.normalize(upath_1.default.dirname(outputFilePath));
    }
    if (upath_1.default.normalize(outputFileArg).startsWith('..')) {
        throw new Error(`Cannot infer command execution directory from path ${outputFileArg}`);
    }
    if (upath_1.default.basename(outputFileArg) !== upath_1.default.basename(outputFilePath)) {
        throw new Error(`Output file name mismatch: ${upath_1.default.basename(outputFileArg)} vs ${upath_1.default.basename(outputFilePath)}`);
    }
    const outputFileDir = upath_1.default.normalize(upath_1.default.dirname(outputFileArg));
    let commandExecDir = upath_1.default.normalize(upath_1.default.dirname(outputFilePath));
    for (const dir of outputFileDir.split('/').reverse()) {
        if (commandExecDir.endsWith(dir)) {
            commandExecDir = upath_1.default.join(commandExecDir.slice(0, -dir.length), '.');
            // outputFileDir = upath.join(outputFileDir.slice(0, -dir.length), '.');
        }
        else {
            break;
        }
    }
    commandExecDir = upath_1.default.normalizeTrim(commandExecDir);
    if (commandExecDir !== '.') {
        logger_1.logger.debug({
            commandExecDir,
            outputFileArg,
            outputFilePath,
        }, `pip-compile: command was not executed in repository root`);
    }
    return commandExecDir;
}
//# sourceMappingURL=utils.js.map