"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const find_workspace_dir_1 = require("@pnpm/find-workspace-dir");
const nopt = require("nopt");
async function parseCliArgs(opts, inputArgv) {
    var _a;
    const noptExploratoryResults = nopt({
        filter: [String],
        help: Boolean,
        recursive: Boolean,
        ...opts.globalOptionsTypes,
        ...opts.getTypesByCommandName('add'),
        ...opts.getTypesByCommandName('install'),
    }, {
        'r': ['--recursive'],
        ...opts.shortHands,
    }, inputArgv, 0);
    if (noptExploratoryResults['help']) {
        return {
            argv: noptExploratoryResults.argv,
            cliArgs: noptExploratoryResults.argv.remain,
            cliConf: {},
            cmd: 'help',
            dir: process.cwd(),
            subCmd: null,
            unknownOptions: [],
        };
    }
    const types = (() => {
        if (opts.getCommandLongName(noptExploratoryResults.argv.remain[0]) === 'recursive') {
            return {
                ...opts.globalOptionsTypes,
                ...opts.getTypesByCommandName('recursive'),
                ...opts.getTypesByCommandName(getCommandName(noptExploratoryResults.argv.remain.slice(1))),
            };
        }
        if (noptExploratoryResults['filter'] || noptExploratoryResults['recursive'] === true) {
            return {
                ...opts.globalOptionsTypes,
                ...opts.getTypesByCommandName('recursive'),
                ...opts.getTypesByCommandName(getCommandName(noptExploratoryResults.argv.remain)),
            };
        }
        return {
            ...opts.globalOptionsTypes,
            ...opts.getTypesByCommandName(getCommandName(noptExploratoryResults.argv.remain)),
        };
    })(); // tslint:disable-line:no-any
    function getCommandName(cliArgs) {
        if (opts.getCommandLongName(cliArgs[0]) !== 'install' || cliArgs.length === 1)
            return cliArgs[0];
        return 'add';
    }
    const { argv, ...cliConf } = nopt(types, opts.shortHands, 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 cmd = opts.getCommandLongName(argv.remain[0])
        || 'help';
    if (!opts.isKnownCommand(cmd)) {
        cmd = 'help';
    }
    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 (cmd !== 'recursive' && (cliConf['filter'] || cliConf['recursive'] === true)) {
        subCmd = cmd;
        cmd = 'recursive';
        cliArgs.unshift(subCmd);
    }
    else if (subCmd && !opts.isKnownCommand(subCmd)) {
        subCmd = null;
    }
    const dir = (_a = cliConf['dir'], (_a !== 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) {
        subCmd = cmd;
        cmd = 'recursive';
        cliArgs.unshift(subCmd);
    }
    if (cmd === 'install' && cliArgs.length > 0) {
        cmd = 'add';
    }
    else if (subCmd === 'install' && cliArgs.length > 1) {
        subCmd = 'add';
    }
    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,
        dir,
        subCmd,
        unknownOptions,
        workspaceDir,
    };
}
exports.default = parseCliArgs;
