"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const find_workspace_dir_1 = require("@pnpm/find-workspace-dir");
const didyoumean2_1 = require("didyoumean2");
const nopt = require("nopt");
const RECURSIVE_CMDS = new Set(['recursive', 'multi', 'm']);
async function parseCliArgs(opts, inputArgv) {
    var _a;
    const noptExploratoryResults = nopt({
        filter: [String],
        help: Boolean,
        recursive: Boolean,
        ...opts.universalOptionsTypes,
        ...opts.getTypesByCommandName('add'),
        ...opts.getTypesByCommandName('install'),
    }, {
        'r': '--recursive',
        ...opts.universalShorthands,
    }, inputArgv, 0);
    if (noptExploratoryResults['help']) {
        return {
            argv: noptExploratoryResults.argv,
            cmd: 'help',
            options: {},
            params: noptExploratoryResults.argv.remain,
            unknownOptions: new Map(),
        };
    }
    const recursiveCommandUsed = RECURSIVE_CMDS.has(noptExploratoryResults.argv.remain[0]);
    const commandName = getCommandName(noptExploratoryResults.argv.remain);
    let cmd = commandName ? opts.getCommandLongName(commandName) : null;
    const types = {
        ...opts.universalOptionsTypes,
        ...opts.getTypesByCommandName(commandName),
    }; // tslint:disable-line:no-any
    function getCommandName(args) {
        if (recursiveCommandUsed) {
            args = args.slice(1);
        }
        if (opts.getCommandLongName(args[0]) !== 'install' || args.length === 1) {
            return args[0];
        }
        return 'add';
    }
    const { argv, ...options } = nopt({
        'recursive': Boolean,
        ...types,
    }, {
        ...opts.universalShorthands,
        ...opts.shorthandsByCommandName[commandName],
    }, inputArgv, 0);
    if (opts.renamedOptions) {
        for (const cliOption of Object.keys(options)) {
            if (opts.renamedOptions[cliOption]) {
                options[opts.renamedOptions[cliOption]] = options[cliOption];
                delete options[cliOption];
            }
        }
    }
    // `pnpm install ""` is going to be just `pnpm install`
    const params = argv.remain.slice(1).filter(Boolean);
    if (options['recursive'] !== true && (options['filter'] || recursiveCommandUsed)) {
        options['recursive'] = true;
        let subCmd = argv.remain[1] && opts.getCommandLongName(argv.remain[1]);
        if (subCmd && recursiveCommandUsed) {
            params.shift();
            argv.remain.shift();
            cmd = subCmd;
        }
    }
    const dir = (_a = options['dir']) !== null && _a !== void 0 ? _a : process.cwd();
    const workspaceDir = options['global'] // tslint:disable-line
        ? undefined
        : await find_workspace_dir_1.default(dir);
    if ((cmd === 'add' || cmd === 'install') &&
        typeof workspaceDir === 'string' &&
        params.length === 0) {
        options['recursive'] = true;
    }
    if (cmd === 'install' && params.length > 0) {
        cmd = 'add';
    }
    if (!cmd && options['recursive']) {
        cmd = 'recursive';
    }
    const knownOptions = new Set(Object.keys(types));
    const unknownOptions = getUnknownOptions(Object.keys(options), knownOptions);
    return {
        argv,
        cmd,
        options,
        params,
        unknownOptions,
        workspaceDir,
    };
}
exports.default = parseCliArgs;
function getUnknownOptions(usedOptions, knownOptions) {
    const unknownOptions = new Map();
    const closestMatches = getClosestOptionMatches.bind(null, Array.from(knownOptions));
    for (const usedOption of usedOptions) {
        if (knownOptions.has(usedOption) || usedOption.startsWith('//'))
            continue;
        unknownOptions.set(usedOption, closestMatches(usedOption));
    }
    return unknownOptions;
}
function getClosestOptionMatches(knownOptions, option) {
    var _a;
    return (_a = didyoumean2_1.default(option, knownOptions, {
        returnType: didyoumean2_1.ReturnTypeEnums.ALL_CLOSEST_MATCHES,
    })) !== null && _a !== void 0 ? _a : [];
}
//# sourceMappingURL=index.js.map