import chalk from "chalk";
import { APP_NAME, CONFIG_DIR_NAME } from "./config.js";
export function getPackageCommandUsage(command) {
    switch (command) {
        case "install":
            return `${APP_NAME} install <source> [-l] [--approve|--no-approve]`;
        case "remove":
            return `${APP_NAME} remove <source> [-l] [--approve|--no-approve]`;
        case "update":
            return `${APP_NAME} update [source|self|${APP_NAME}] [--self|--extensions|--all] [--extension <source>] [--approve|--no-approve] [--force]`;
        case "list":
            return `${APP_NAME} list [--approve|--no-approve]`;
    }
}
export function printPackageCommandHelp(command) {
    switch (command) {
        case "install":
            console.log(`${chalk.bold("Usage:")}
  ${getPackageCommandUsage("install")}

Install a package and add it to settings.

Options:
  -l, --local       Install project-locally (${CONFIG_DIR_NAME}/settings.json)
  -a, --approve     Trust project-local files for this command
  -na, --no-approve Ignore project-local files for this command

Examples:
  ${APP_NAME} install npm:@foo/bar
  ${APP_NAME} install git:github.com/user/repo
  ${APP_NAME} install git:git@github.com:user/repo
  ${APP_NAME} install https://github.com/user/repo
  ${APP_NAME} install ssh://git@github.com/user/repo
  ${APP_NAME} install ./local/path
`);
            return;
        case "remove":
            console.log(`${chalk.bold("Usage:")}
  ${getPackageCommandUsage("remove")}

Remove a package and its source from settings.
Alias: ${APP_NAME} uninstall <source> [-l]

Options:
  -l, --local       Remove from project settings (${CONFIG_DIR_NAME}/settings.json)
  -a, --approve     Trust project-local files for this command
  -na, --no-approve Ignore project-local files for this command

Examples:
  ${APP_NAME} remove npm:@foo/bar
  ${APP_NAME} uninstall npm:@foo/bar
`);
            return;
        case "update":
            console.log(`${chalk.bold("Usage:")}
  ${getPackageCommandUsage("update")}

Update ${APP_NAME} and installed packages.

Options:
  --self                  Update ${APP_NAME} only (default when no target is given)
  --extensions            Update installed packages only
  --all                   Update ${APP_NAME} and installed packages
  --extension <source>    Update one package only
  -a, --approve           Trust project-local files for this command
  -na, --no-approve       Ignore project-local files for this command
  --force                 Reinstall ${APP_NAME} even if the current version is latest

Short forms:
  ${APP_NAME} update                Update ${APP_NAME} only
  ${APP_NAME} update --all          Update ${APP_NAME} and all extensions
  ${APP_NAME} update <source>       Update one package
  ${APP_NAME} update ${APP_NAME}    Update ${APP_NAME} only (self works as an alias)
`);
            return;
        case "list":
            console.log(`${chalk.bold("Usage:")}
  ${getPackageCommandUsage("list")}

List installed packages from user and project settings.

Options:
  -a, --approve      Trust project-local files for this command
  -na, --no-approve  Ignore project-local files for this command
`);
            return;
    }
}
export function parsePackageCommand(args) {
    const [rawCommand, ...rest] = args;
    let command;
    if (rawCommand === "uninstall") {
        command = "remove";
    }
    else if (rawCommand === "install" || rawCommand === "remove" || rawCommand === "update" || rawCommand === "list") {
        command = rawCommand;
    }
    if (!command) {
        return undefined;
    }
    let local = false;
    let force = false;
    let projectTrustOverride;
    let help = false;
    let invalidOption;
    let invalidArgument;
    let missingOptionValue;
    let conflictingOptions;
    let source;
    let selfFlag = false;
    let extensionsFlag = false;
    let allFlag = false;
    let extensionFlagSource;
    for (let index = 0; index < rest.length; index++) {
        const arg = rest[index];
        if (arg === "-h" || arg === "--help") {
            help = true;
            continue;
        }
        if (arg === "-l" || arg === "--local") {
            if (command === "install" || command === "remove") {
                local = true;
            }
            else {
                invalidOption = invalidOption ?? arg;
            }
            continue;
        }
        if (arg === "--self") {
            if (command === "update") {
                selfFlag = true;
            }
            else {
                invalidOption = invalidOption ?? arg;
            }
            continue;
        }
        if (arg === "--extensions") {
            if (command === "update") {
                extensionsFlag = true;
            }
            else {
                invalidOption = invalidOption ?? arg;
            }
            continue;
        }
        if (arg === "--all") {
            if (command === "update") {
                allFlag = true;
            }
            else {
                invalidOption = invalidOption ?? arg;
            }
            continue;
        }
        if (arg === "--approve" || arg === "-a") {
            projectTrustOverride = true;
            continue;
        }
        if (arg === "--no-approve" || arg === "-na") {
            projectTrustOverride = false;
            continue;
        }
        if (arg === "--force") {
            if (command === "update") {
                force = true;
            }
            else {
                invalidOption = invalidOption ?? arg;
            }
            continue;
        }
        if (arg === "--extension") {
            if (command !== "update") {
                invalidOption = invalidOption ?? arg;
                continue;
            }
            const value = rest[index + 1];
            if (!value || value.startsWith("-")) {
                missingOptionValue = missingOptionValue ?? arg;
            }
            else if (extensionFlagSource) {
                conflictingOptions = conflictingOptions ?? "--extension can only be provided once";
                index++;
            }
            else {
                extensionFlagSource = value;
                index++;
            }
            continue;
        }
        if (arg.startsWith("-")) {
            invalidOption = invalidOption ?? arg;
            continue;
        }
        if (!source) {
            source = arg;
        }
        else {
            invalidArgument = invalidArgument ?? arg;
        }
    }
    let updateTarget;
    let showExtensionsSkippedNote = false;
    if (command === "update") {
        if (allFlag && (selfFlag || extensionsFlag || extensionFlagSource)) {
            conflictingOptions =
                conflictingOptions ?? "--all cannot be combined with --self, --extensions, or --extension";
        }
        if (allFlag && source) {
            conflictingOptions = conflictingOptions ?? "--all cannot be combined with a positional source";
        }
        if (extensionFlagSource) {
            if (selfFlag || extensionsFlag || allFlag) {
                conflictingOptions =
                    conflictingOptions ?? "--extension cannot be combined with --self, --extensions, or --all";
            }
            if (source) {
                conflictingOptions = conflictingOptions ?? "--extension cannot be combined with a positional source";
            }
            updateTarget = { type: "extensions", source: extensionFlagSource };
        }
        else if (source) {
            const sourceIsSelf = source === "self" || source === APP_NAME || source === "pi";
            if (sourceIsSelf) {
                updateTarget = extensionsFlag ? { type: "all" } : { type: "self" };
            }
            else {
                if (extensionsFlag || selfFlag || allFlag) {
                    conflictingOptions =
                        conflictingOptions ??
                            "positional update targets cannot be combined with --self, --extensions, or --all";
                }
                updateTarget = { type: "extensions", source };
            }
        }
        else if (allFlag) {
            updateTarget = { type: "all" };
        }
        else if (selfFlag && extensionsFlag) {
            updateTarget = { type: "all" };
        }
        else if (selfFlag) {
            updateTarget = { type: "self" };
        }
        else if (extensionsFlag) {
            updateTarget = { type: "extensions" };
        }
        else {
            updateTarget = { type: "self" };
            showExtensionsSkippedNote = true;
        }
    }
    return {
        command,
        source,
        updateTarget,
        showExtensionsSkippedNote,
        local,
        force,
        projectTrustOverride,
        help,
        invalidOption,
        invalidArgument,
        missingOptionValue,
        conflictingOptions,
    };
}
//# sourceMappingURL=package-manager-cli-parser.js.map