/**
 * Command Registry - Slash Command Management
 *
 * Provides a registry for slash commands with:
 * - Command registration and discovery
 * - Help text generation
 * - Category organization
 * - Command execution delegation
 *
 * Usage:
 * ```typescript
 * const registry = new CommandRegistry();
 *
 * registry.register({
 *   name: '/help',
 *   aliases: ['/?'],
 *   description: 'Show help information',
 *   category: 'navigation',
 *   handler: async (context) => {
 *     context.showHelp();
 *   },
 * });
 *
 * await registry.execute('/help', '', context);
 * ```
 */
import { logDebug } from '../utils/debugLogger.js';
// ═══════════════════════════════════════════════════════════════════════════════
// Command Registry
// ═══════════════════════════════════════════════════════════════════════════════
export class CommandRegistry {
    commands = new Map();
    aliasMap = new Map();
    /**
     * Register a command
     */
    register(command) {
        // Normalize command name
        const name = this.normalizeName(command.name);
        this.commands.set(name, command);
        // Register aliases
        if (command.aliases) {
            for (const alias of command.aliases) {
                const normalizedAlias = this.normalizeName(alias);
                this.aliasMap.set(normalizedAlias, name);
            }
        }
        return this;
    }
    /**
     * Register multiple commands
     */
    registerAll(commands) {
        for (const command of commands) {
            this.register(command);
        }
        return this;
    }
    /**
     * Find a command by name or alias
     */
    find(commandName) {
        const normalized = this.normalizeName(commandName);
        // Direct match
        const direct = this.commands.get(normalized);
        if (direct) {
            return { command: direct, matchedName: commandName };
        }
        // Alias match
        const aliasTarget = this.aliasMap.get(normalized);
        if (aliasTarget) {
            const command = this.commands.get(aliasTarget);
            if (command) {
                return { command, matchedName: commandName };
            }
        }
        return null;
    }
    /**
     * Check if a command exists
     */
    has(commandName) {
        return this.find(commandName) !== null;
    }
    /**
     * Execute a command
     */
    async execute(commandName, input, shell) {
        const match = this.find(commandName);
        if (!match) {
            return false;
        }
        const context = {
            shell,
            input,
            rawCommand: commandName,
        };
        try {
            await Promise.resolve(match.command.handler(context));
            return true;
        }
        catch (error) {
            logDebug(`Error executing command ${commandName}:`, error);
            return false;
        }
    }
    /**
     * Get all commands in a category
     */
    getByCategory(category) {
        return Array.from(this.commands.values()).filter((cmd) => cmd.category === category && !cmd.hidden);
    }
    /**
     * Get all categories with their commands
     */
    getAllCategories() {
        const categories = new Map();
        for (const command of this.commands.values()) {
            if (command.hidden)
                continue;
            const existing = categories.get(command.category) || [];
            existing.push(command);
            categories.set(command.category, existing);
        }
        return categories;
    }
    /**
     * Get all registered commands
     */
    getAll() {
        return Array.from(this.commands.values());
    }
    /**
     * Get all visible commands (excluding hidden)
     */
    getVisible() {
        return Array.from(this.commands.values()).filter((cmd) => !cmd.hidden);
    }
    /**
     * Generate help text for all commands
     */
    generateHelpText() {
        const lines = ['Available commands:', ''];
        const categories = this.getAllCategories();
        const categoryOrder = [
            'navigation',
            'model',
            'context',
            'session',
            'tools',
            'development',
            'security',
            'learning',
            'advanced',
            'ui',
        ];
        for (const category of categoryOrder) {
            const commands = categories.get(category);
            if (!commands || commands.length === 0)
                continue;
            lines.push(`${this.formatCategoryName(category)}:`);
            for (const cmd of commands.sort((a, b) => a.name.localeCompare(b.name))) {
                const aliases = cmd.aliases?.length ? ` (${cmd.aliases.join(', ')})` : '';
                lines.push(`  ${cmd.name}${aliases} - ${cmd.description}`);
            }
            lines.push('');
        }
        return lines.join('\n');
    }
    /**
     * Generate compact help text (just command names)
     */
    generateCompactHelp() {
        const commands = this.getVisible()
            .map((cmd) => cmd.name)
            .sort();
        return commands.join('  ');
    }
    /**
     * Normalize command name
     */
    normalizeName(name) {
        return name.toLowerCase().trim();
    }
    /**
     * Format category name for display
     */
    formatCategoryName(category) {
        const names = {
            navigation: '📍 Navigation',
            model: '🤖 Model Selection',
            context: '📁 Context Management',
            session: '💾 Session Management',
            tools: '🔧 Tools',
            development: '🛠 Development',
            security: '🔐 Security',
            advanced: '⚡ Advanced',
            learning: '🧠 Learning',
            ui: '🎨 UI/Display',
        };
        return names[category] || category;
    }
}
// ═══════════════════════════════════════════════════════════════════════════════
// Built-in Commands Factory
// ═══════════════════════════════════════════════════════════════════════════════
/**
 * Create a standard set of commands for the shell
 *
 * This is meant to be extended/customized by the shell implementation
 */
export function createBaseCommands() {
    return [
        // Navigation
        {
            name: '/help',
            aliases: ['/?'],
            description: 'Show help information',
            category: 'navigation',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.showHelp?.();
            },
        },
        {
            name: '/exit',
            aliases: ['/quit', '/q'],
            description: 'Exit the shell',
            category: 'navigation',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.shutdown?.();
            },
        },
        // Model
        {
            name: '/model',
            description: 'Show model selection menu',
            category: 'model',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.showModelMenu?.();
            },
        },
        {
            name: '/providers',
            description: 'Show configured providers',
            category: 'model',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.showConfiguredProviders?.();
            },
        },
        // Context
        {
            name: '/context',
            description: 'Refresh workspace context',
            category: 'context',
            async: true,
            handler: async (ctx) => {
                const shell = ctx.shell;
                await shell.refreshWorkspaceContextCommand?.(ctx.input);
            },
        },
        // Session
        {
            name: '/sessions',
            description: 'Session management',
            category: 'session',
            async: true,
            handler: async (ctx) => {
                const shell = ctx.shell;
                await shell.handleSessionCommand?.(ctx.input);
            },
        },
        // Tools
        {
            name: '/tools',
            description: 'Show available tools',
            category: 'tools',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.showToolsMenu?.();
            },
        },
        {
            name: '/mcp',
            description: 'Show MCP server status',
            category: 'tools',
            async: true,
            handler: async (ctx) => {
                const shell = ctx.shell;
                await shell.showMcpStatus?.();
            },
        },
        // Development
        {
            name: '/doctor',
            description: 'Run diagnostics',
            category: 'development',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.runDoctor?.();
            },
        },
        {
            name: '/checks',
            description: 'Run repository checks',
            category: 'development',
            async: true,
            handler: async (ctx) => {
                const shell = ctx.shell;
                await shell.runRepoChecksCommand?.();
            },
        },
        // Security
        {
            name: '/secrets',
            description: 'Manage API keys and secrets',
            category: 'security',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.showSecretsMenu?.();
            },
        },
        // Learning
        {
            name: '/learn',
            description: 'Show learning system status',
            category: 'learning',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.showLearningStatus?.(ctx.input);
            },
        },
        // UI
        {
            name: '/shortcuts',
            aliases: ['/keys'],
            description: 'Show keyboard shortcuts',
            category: 'ui',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.handleShortcutsCommand?.();
            },
        },
        {
            name: '/thinking',
            description: 'Toggle thinking/reasoning display',
            category: 'ui',
            handler: (ctx) => {
                const shell = ctx.shell;
                shell.handleThinkingCommand?.(ctx.input);
            },
        },
        // Advanced - Dual RL Tournament
        {
            name: '/upgrade',
            aliases: ['/up'],
            description: 'Run repo upgrade with dual RL tournament mode',
            category: 'advanced',
            usage: '/upgrade [dual|tournament] [scope:path] [--validate] [--parallel-variants] [--continue-on-failure] <direction>',
            async: true,
            handler: async (ctx) => {
                const shell = ctx.shell;
                const args = ctx.input.split(/\s+/).filter(Boolean);
                await shell.runRepoUpgradeCommand?.(args);
            },
        },
    ];
}
// ═══════════════════════════════════════════════════════════════════════════════
// Singleton Registry Instance
// ═══════════════════════════════════════════════════════════════════════════════
let globalRegistry = null;
export function getCommandRegistry() {
    if (!globalRegistry) {
        globalRegistry = new CommandRegistry();
        globalRegistry.registerAll(createBaseCommands());
    }
    return globalRegistry;
}
export function resetCommandRegistry() {
    globalRegistry = null;
}
//# sourceMappingURL=commandRegistry.js.map