#!/usr/bin/env node
import { realpathSync } from 'node:fs';
import { resolve } from 'node:path';
import { fileURLToPath, pathToFileURL } from 'node:url';
import { buildCommandContext } from './app/command-context.js';
import { formatCommandPath, formatRerunCommand, guardBundledToolMutation, isBundledToolMutationCommand, } from './app/tool-bundle-update-guard.js';
import { maybeNotifyAboutUpdate } from './app/update-notifier.js';
import { OAT_VERSION } from './shared/oat-version.js';
import { createProgram } from './app/create-program.js';
import { registerCommands } from './commands/index.js';
import { CliError } from './errors/index.js';
import { createLogger } from './ui/index.js';
class CliUpdateInstalledSignal extends Error {
}
export function normalizeArgv(argv) {
    // `pnpm run <script> -- ...` passes a literal `--` into argv.
    // Strip that sentinel so Commander can parse subcommand options normally.
    if (argv.length >= 3 && argv[2] === '--') {
        const executable = argv[0];
        const script = argv[1];
        if (!executable || !script) {
            return argv;
        }
        return [executable, script, ...argv.slice(3)];
    }
    return argv;
}
export async function main(argv = process.argv, platform = process.platform) {
    const program = createProgram();
    registerCommands(program);
    const normalizedArgv = normalizeArgv(argv);
    program.hook('preAction', async (_command, actionCommand) => {
        const context = buildCommandContext(actionCommand.optsWithGlobals());
        const notifierOptions = {
            currentVersion: OAT_VERSION,
            home: context.home,
            interactive: context.interactive,
            json: context.json,
            argv: normalizedArgv,
            env: process.env,
            logger: context.logger,
        };
        if (isBundledToolMutationCommand(actionCommand)) {
            const cliUpdated = await guardBundledToolMutation({
                ...notifierOptions,
                commandPath: formatCommandPath(actionCommand),
                dryRun: context.dryRun,
                rerunCommand: formatRerunCommand(normalizedArgv, platform),
            });
            if (cliUpdated) {
                throw new CliUpdateInstalledSignal();
            }
            return;
        }
        try {
            await maybeNotifyAboutUpdate(notifierOptions);
        }
        catch {
            // Update notifications are best-effort and never affect command dispatch.
        }
    });
    try {
        await program.parseAsync(normalizedArgv);
    }
    catch (error) {
        if (!(error instanceof CliUpdateInstalledSignal)) {
            throw error;
        }
    }
}
export function isEntrypoint(argv = process.argv, entrypointUrl = import.meta.url) {
    if (!argv[1]) {
        return false;
    }
    const entrypointPath = fileURLToPath(entrypointUrl);
    const argvPath = resolve(argv[1]);
    try {
        return realpathSync(entrypointPath) === realpathSync(argvPath);
    }
    catch {
        return entrypointUrl === pathToFileURL(argvPath).href;
    }
}
if (isEntrypoint()) {
    void main().catch((error) => {
        const logger = createLogger({ json: false, verbose: false });
        if (error instanceof CliError) {
            logger.error(error.message);
            process.exitCode = error.exitCode;
        }
        else if (error instanceof Error) {
            logger.error(error.message);
            process.exitCode = 2;
        }
        else {
            logger.error('Unexpected error');
            process.exitCode = 2;
        }
    });
}
