"use strict";
/**
 * CLIProxy Command Dispatcher
 *
 * Routes cliproxy subcommands to their respective handlers.
 * This is the main entry point for all `ccs cliproxy` commands.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.handleCliproxyCommand = exports.parseProviderArg = void 0;
const binary_manager_1 = require("../../cliproxy/binary-manager");
const provider_capabilities_1 = require("../../cliproxy/provider-capabilities");
const cliproxy_sync_handler_1 = require("../cliproxy-sync-handler");
const arg_extractor_1 = require("../arg-extractor");
// Import subcommand handlers
const auth_subcommand_1 = require("./auth-subcommand");
const quota_subcommand_1 = require("./quota-subcommand");
const variant_subcommand_1 = require("./variant-subcommand");
const proxy_lifecycle_subcommand_1 = require("./proxy-lifecycle-subcommand");
const install_subcommand_1 = require("./install-subcommand");
const help_subcommand_1 = require("./help-subcommand");
const routing_subcommand_1 = require("./routing-subcommand");
const catalog_subcommand_1 = require("./catalog-subcommand");
/**
 * Parse --backend flag from args
 * Returns the backend value and remaining args without --backend flag
 */
function parseBackendArg(args) {
    const extracted = (0, arg_extractor_1.extractOption)(args, ['--backend']);
    if (!extracted.found) {
        return { backend: undefined, remainingArgs: args };
    }
    if (extracted.missingValue || !extracted.value) {
        console.warn(`Invalid backend ''. Valid options: original, plus`);
        return { backend: undefined, remainingArgs: extracted.remainingArgs };
    }
    const value = extracted.value;
    if (value !== 'original' && value !== 'plus') {
        console.warn(`Invalid backend '${value}'. Valid options: original, plus`);
        return { backend: undefined, remainingArgs: extracted.remainingArgs };
    }
    return { backend: value, remainingArgs: extracted.remainingArgs };
}
/**
 * Get selected backend input (CLI flag > config.yaml > default)
 */
function getEffectiveBackend(cliBackend) {
    return cliBackend ?? (0, binary_manager_1.getStoredConfiguredBackend)();
}
function normalizeQuotaProvider(value) {
    if (value === 'all') {
        return 'all';
    }
    const canonicalProvider = (0, provider_capabilities_1.mapExternalProviderName)(value);
    if (!canonicalProvider || !(0, provider_capabilities_1.isQuotaSupportedProvider)(canonicalProvider)) {
        return null;
    }
    return canonicalProvider;
}
function parseProviderArg(args) {
    const extracted = (0, arg_extractor_1.extractOption)(args, ['--provider']);
    if (!extracted.found) {
        return { provider: 'all', remainingArgs: args, invalid: false };
    }
    if (extracted.missingValue || !extracted.value) {
        console.error(`Invalid provider value. --provider requires a value. Valid options: ${provider_capabilities_1.QUOTA_PROVIDER_HELP_TEXT}`);
        return { provider: 'all', remainingArgs: extracted.remainingArgs, invalid: true };
    }
    const value = extracted.value.toLowerCase();
    const normalized = normalizeQuotaProvider(value);
    if (!normalized) {
        console.error(`Invalid provider '${value}'. Valid options: ${provider_capabilities_1.QUOTA_PROVIDER_HELP_TEXT}`);
        return { provider: 'all', remainingArgs: extracted.remainingArgs, invalid: true };
    }
    return {
        provider: normalized,
        remainingArgs: extracted.remainingArgs,
        invalid: false,
    };
}
exports.parseProviderArg = parseProviderArg;
/**
 * Main router for cliproxy commands
 */
async function handleCliproxyCommand(args) {
    // Parse --backend flag first (before other processing)
    const { backend: cliBackend, remainingArgs } = parseBackendArg(args);
    const effectiveBackend = getEffectiveBackend(cliBackend);
    const verbose = (0, arg_extractor_1.hasAnyFlag)(remainingArgs, ['--verbose', '-v']);
    const command = remainingArgs[0];
    if ((0, arg_extractor_1.hasAnyFlag)(remainingArgs, ['--help', '-h'])) {
        await (0, help_subcommand_1.showHelp)();
        return;
    }
    // Catalog commands
    if (command === 'catalog') {
        // --json takes priority over subcommands (refresh/reset) — it always
        // outputs the current resolved catalog regardless of other arguments.
        if ((0, arg_extractor_1.hasAnyFlag)(remainingArgs, ['--json'])) {
            (0, catalog_subcommand_1.handleCatalogJson)();
            return;
        }
        const subcommand = remainingArgs[1];
        if (subcommand === 'refresh') {
            await (0, catalog_subcommand_1.handleCatalogRefresh)(verbose);
            return;
        }
        if (subcommand === 'reset') {
            await (0, catalog_subcommand_1.handleCatalogReset)();
            return;
        }
        await (0, catalog_subcommand_1.handleCatalogStatus)(verbose);
        return;
    }
    // Sync command
    if (command === 'sync') {
        await (0, cliproxy_sync_handler_1.handleSync)(remainingArgs.slice(1));
        return;
    }
    if (command === 'quota') {
        const { provider: providerFilter, invalid } = parseProviderArg(remainingArgs.slice(1));
        if (invalid) {
            process.exitCode = 1;
            return;
        }
        await (0, quota_subcommand_1.handleQuotaStatus)(verbose, providerFilter);
        return;
    }
    if (command === 'routing') {
        const subcommand = remainingArgs[1];
        if (subcommand === 'set') {
            await (0, routing_subcommand_1.handleRoutingSet)(remainingArgs.slice(2));
            return;
        }
        if (subcommand === 'explain') {
            await (0, routing_subcommand_1.handleRoutingExplain)();
            return;
        }
        if (subcommand === 'affinity') {
            if ((0, arg_extractor_1.hasAnyFlag)(remainingArgs.slice(2), ['--help', '-h'])) {
                await (0, routing_subcommand_1.handleRoutingAffinityHelp)();
                return;
            }
            if (remainingArgs[2]) {
                await (0, routing_subcommand_1.handleRoutingAffinitySet)(remainingArgs.slice(2));
                return;
            }
            await (0, routing_subcommand_1.handleRoutingAffinityStatus)();
            return;
        }
        await (0, routing_subcommand_1.handleRoutingStatus)();
        return;
    }
    const commandHandlers = {
        create: async () => (0, variant_subcommand_1.handleCreate)(remainingArgs.slice(1), effectiveBackend),
        edit: async () => (0, variant_subcommand_1.handleEdit)(remainingArgs.slice(1), effectiveBackend),
        list: async () => (0, auth_subcommand_1.handleList)(),
        ls: async () => (0, auth_subcommand_1.handleList)(),
        remove: async () => (0, variant_subcommand_1.handleRemove)(remainingArgs.slice(1)),
        delete: async () => (0, variant_subcommand_1.handleRemove)(remainingArgs.slice(1)),
        rm: async () => (0, variant_subcommand_1.handleRemove)(remainingArgs.slice(1)),
        start: async () => (0, proxy_lifecycle_subcommand_1.handleStart)(verbose),
        stop: async () => (0, proxy_lifecycle_subcommand_1.handleStop)(),
        restart: async () => (0, proxy_lifecycle_subcommand_1.handleRestart)(verbose),
        status: async () => (0, proxy_lifecycle_subcommand_1.handleProxyStatus)(),
        doctor: async () => (0, quota_subcommand_1.handleDoctor)(verbose),
        diag: async () => (0, quota_subcommand_1.handleDoctor)(verbose),
        default: async () => (0, quota_subcommand_1.handleSetDefault)(remainingArgs.slice(1)),
        pause: async () => (0, quota_subcommand_1.handlePauseAccount)(remainingArgs.slice(1)),
        resume: async () => (0, quota_subcommand_1.handleResumeAccount)(remainingArgs.slice(1)),
    };
    const commandHandler = command ? commandHandlers[command] : undefined;
    if (commandHandler) {
        await commandHandler();
        return;
    }
    // Binary installation commands
    const installIdx = remainingArgs.indexOf('--install');
    if (installIdx !== -1) {
        let version = remainingArgs[installIdx + 1];
        if (!version || version.startsWith('-')) {
            console.error('Missing version argument for --install');
            console.error('    Usage: ccs cliproxy --install <version>');
            console.error('    Example: ccs cliproxy --install 6.6.80-0');
            process.exit(1);
        }
        // Strip leading 'v' prefix and whitespace (user may type " v6.6.80-0 ")
        version = version.trim().replace(/^v/, '');
        await (0, install_subcommand_1.handleInstallVersion)(version, verbose, effectiveBackend);
        return;
    }
    if (remainingArgs.includes('--latest') || remainingArgs.includes('--update')) {
        await (0, install_subcommand_1.handleInstallLatest)(verbose, effectiveBackend);
        return;
    }
    // Default: show status
    await (0, install_subcommand_1.showStatus)(verbose, effectiveBackend);
}
exports.handleCliproxyCommand = handleCliproxyCommand;
//# sourceMappingURL=index.js.map