/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import { coreEvents, CoreEvent, } from '@google/gemini-cli-core';
import { CommandKind } from '../ui/commands/types.js';
/**
 * Handles slash command conflict events and provides user feedback.
 *
 * This handler batches multiple conflict events into a single notification
 * block per command name to avoid UI clutter during startup or incremental loading.
 */
export class SlashCommandConflictHandler {
    notifiedConflicts = new Set();
    pendingConflicts = [];
    flushTimeout = null;
    constructor() {
        this.handleConflicts = this.handleConflicts.bind(this);
    }
    start() {
        coreEvents.on(CoreEvent.SlashCommandConflicts, this.handleConflicts);
    }
    stop() {
        coreEvents.off(CoreEvent.SlashCommandConflicts, this.handleConflicts);
        if (this.flushTimeout) {
            clearTimeout(this.flushTimeout);
            this.flushTimeout = null;
        }
    }
    handleConflicts(payload) {
        const newConflicts = payload.conflicts.filter((c) => {
            // Use a unique key to prevent duplicate notifications for the same conflict
            const sourceId = c.loserExtensionName || c.loserMcpServerName || c.loserKind;
            const key = `${c.name}:${sourceId}:${c.renamedTo}`;
            if (this.notifiedConflicts.has(key)) {
                return false;
            }
            this.notifiedConflicts.add(key);
            return true;
        });
        if (newConflicts.length > 0) {
            this.pendingConflicts.push(...newConflicts);
            this.scheduleFlush();
        }
    }
    scheduleFlush() {
        if (this.flushTimeout) {
            clearTimeout(this.flushTimeout);
        }
        // Use a trailing debounce to capture staggered reloads during startup
        this.flushTimeout = setTimeout(() => this.flush(), 500);
    }
    flush() {
        this.flushTimeout = null;
        const conflicts = [...this.pendingConflicts];
        this.pendingConflicts = [];
        if (conflicts.length === 0) {
            return;
        }
        // Group conflicts by their original command name
        const grouped = new Map();
        for (const c of conflicts) {
            const list = grouped.get(c.name) ?? [];
            list.push(c);
            grouped.set(c.name, list);
        }
        for (const [name, commandConflicts] of grouped) {
            if (commandConflicts.length > 1) {
                this.emitGroupedFeedback(name, commandConflicts);
            }
            else {
                this.emitSingleFeedback(commandConflicts[0]);
            }
        }
    }
    /**
     * Emits a grouped notification for multiple conflicts sharing the same name.
     */
    emitGroupedFeedback(name, conflicts) {
        const messages = conflicts
            .map((c) => {
            const source = this.getSourceDescription(c.loserExtensionName, c.loserKind, c.loserMcpServerName);
            return `- ${this.capitalize(source)} '/${c.name}' was renamed to '/${c.renamedTo}'`;
        })
            .join('\n');
        coreEvents.emitFeedback('info', `Conflicts detected for command '/${name}':\n${messages}`);
    }
    /**
     * Emits a descriptive notification for a single command conflict.
     */
    emitSingleFeedback(c) {
        const loserSource = this.getSourceDescription(c.loserExtensionName, c.loserKind, c.loserMcpServerName);
        const winnerSource = this.getSourceDescription(c.winnerExtensionName, c.winnerKind, c.winnerMcpServerName);
        coreEvents.emitFeedback('info', `${this.capitalize(loserSource)} '/${c.name}' was renamed to '/${c.renamedTo}' because it conflicts with ${winnerSource}.`);
    }
    capitalize(s) {
        return s.charAt(0).toUpperCase() + s.slice(1);
    }
    /**
     * Returns a human-readable description of a command's source.
     */
    getSourceDescription(extensionName, kind, mcpServerName) {
        switch (kind) {
            case CommandKind.EXTENSION_FILE:
                return extensionName
                    ? `extension '${extensionName}' command`
                    : 'extension command';
            case CommandKind.SKILL:
                return extensionName
                    ? `extension '${extensionName}' skill`
                    : 'skill command';
            case CommandKind.MCP_PROMPT:
                return mcpServerName
                    ? `MCP server '${mcpServerName}' command`
                    : 'MCP server command';
            case CommandKind.USER_FILE:
                return 'user command';
            case CommandKind.WORKSPACE_FILE:
                return 'workspace command';
            case CommandKind.BUILT_IN:
                return 'built-in command';
            default:
                return 'existing command';
        }
    }
}
//# sourceMappingURL=SlashCommandConflictHandler.js.map