"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const find_workspace_dir_1 = require("@pnpm/find-workspace-dir");
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,
            cliArgs: noptExploratoryResults.argv.remain,
            cliConf: {},
            cmd: 'help',
            isKnownCommand: true,
            subCmd: null,
            unknownOptions: [],
        };
    }
    const recursiveCommandUsed = RECURSIVE_CMDS.has(noptExploratoryResults.argv.remain[0]);
    const commandName = getCommandName(noptExploratoryResults.argv.remain);
    let cmd = commandName ? opts.getCommandLongName(commandName) : null;
    const types = {
        'recursive': Boolean,
        ...opts.universalOptionsTypes,
        ...opts.getTypesByCommandName(commandName),
    }; // tslint:disable-line:no-any
    function getCommandName(cliArgs) {
        if (recursiveCommandUsed) {
            cliArgs = cliArgs.slice(1);
        }
        if (opts.getCommandLongName(cliArgs[0]) !== 'install' || cliArgs.length === 1) {
            return cliArgs[0];
        }
        return 'add';
    }
    const { argv, ...cliConf } = nopt(types, {
        ...opts.universalShorthands,
        ...opts.shorthandsByCommandName[commandName],
    }, inputArgv, 0);
    if (opts.renamedOptions) {
        for (const cliOption of Object.keys(cliConf)) {
            if (opts.renamedOptions[cliOption]) {
                cliConf[opts.renamedOptions[cliOption]] = cliConf[cliOption];
                delete cliConf[cliOption];
            }
        }
    }
    let subCmd = argv.remain[1] && opts.getCommandLongName(argv.remain[1]);
    // `pnpm install ""` is going to be just `pnpm install`
    const cliArgs = argv.remain.slice(1).filter(Boolean);
    if (cliConf['recursive'] !== true && (cliConf['filter'] || recursiveCommandUsed)) {
        cliConf['recursive'] = true;
        if (subCmd && recursiveCommandUsed) {
            cliArgs.shift();
            argv.remain.shift();
            cmd = subCmd;
            subCmd = null;
        }
    }
    else if (subCmd && !opts.isKnownCommand(subCmd)) {
        subCmd = null;
    }
    const dir = (_a = cliConf['dir']) !== null && _a !== void 0 ? _a : process.cwd();
    const workspaceDir = cliConf['global'] // tslint:disable-line
        ? undefined
        : await find_workspace_dir_1.default(dir);
    if ((cmd === 'add' || cmd === 'install') &&
        typeof workspaceDir === 'string' &&
        cliArgs.length === 0) {
        cliConf['recursive'] = true;
    }
    if (cmd === 'install' && cliArgs.length > 0) {
        cmd = 'add';
    }
    else if (subCmd === 'install' && cliArgs.length > 1) {
        cmd = 'add';
    }
    if (!cmd && cliConf['recursive']) {
        cmd = 'recursive';
    }
    const allowedOptions = new Set(Object.keys(types));
    const unknownOptions = [];
    for (const cliOption of Object.keys(cliConf)) {
        if (!allowedOptions.has(cliOption) && !cliOption.startsWith('//')) {
            unknownOptions.push(cliOption);
        }
    }
    return {
        argv,
        cliArgs,
        cliConf,
        cmd,
        isKnownCommand: opts.isKnownCommand(commandName),
        subCmd,
        unknownOptions,
        workspaceDir,
    };
}
exports.default = parseCliArgs;
