import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { Emitter } from '../../../../base/common/event.js';
import { Iterable } from '../../../../base/common/iterator.js';
import { toDisposable } from '../../../../base/common/lifecycle.js';
import { ContextKeyExpr, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js';
var ChatAgentLocation;
( (function(ChatAgentLocation) {
    ChatAgentLocation["Panel"] = "panel";
    ChatAgentLocation["Terminal"] = "terminal";
    ChatAgentLocation["Notebook"] = "notebook";
    ChatAgentLocation["Editor"] = "editor";
})(ChatAgentLocation || (ChatAgentLocation = {})));
( (function(ChatAgentLocation) {
    function fromRaw(value) {
        switch (value) {
            case 'panel': return ChatAgentLocation.Panel;
            case 'terminal': return ChatAgentLocation.Terminal;
            case 'notebook': return ChatAgentLocation.Notebook;
        }
        return ChatAgentLocation.Panel;
    }
    ChatAgentLocation.fromRaw = fromRaw;
})(ChatAgentLocation || (ChatAgentLocation = {})));
const IChatAgentService = ( createDecorator('chatAgentService'));
let ChatAgentService = class ChatAgentService {
    static { this.AGENT_LEADER = '@'; }
    constructor(contextKeyService) {
        this.contextKeyService = contextKeyService;
        this._agents = [];
        this._onDidChangeAgents = ( new Emitter());
        this.onDidChangeAgents = this._onDidChangeAgents.event;
    }
    registerAgent(id, data) {
        const existingAgent = this.getAgent(id);
        if (existingAgent) {
            throw new Error(`Agent already registered: ${JSON.stringify(id)}`);
        }
        const that = this;
        const commands = data.slashCommands;
        data = {
            ...data,
            get slashCommands() {
                return commands.filter(c => !c.when || that.contextKeyService.contextMatchesRules(ContextKeyExpr.deserialize(c.when)));
            }
        };
        const entry = { data };
        this._agents.push(entry);
        return toDisposable(() => {
            this._agents = this._agents.filter(a => a !== entry);
            this._onDidChangeAgents.fire(undefined);
        });
    }
    registerAgentImplementation(id, agentImpl) {
        const entry = this._getAgentEntry(id);
        if (!entry) {
            throw new Error(`Unknown agent: ${JSON.stringify(id)}`);
        }
        if (entry.impl) {
            throw new Error(`Agent already has implementation: ${JSON.stringify(id)}`);
        }
        entry.impl = agentImpl;
        this._onDidChangeAgents.fire(( new MergedChatAgent(entry.data, agentImpl)));
        return toDisposable(() => {
            entry.impl = undefined;
            this._onDidChangeAgents.fire(undefined);
        });
    }
    registerDynamicAgent(data, agentImpl) {
        const agent = { data, impl: agentImpl };
        this._agents.push(agent);
        this._onDidChangeAgents.fire(( new MergedChatAgent(data, agentImpl)));
        return toDisposable(() => {
            this._agents = this._agents.filter(a => a !== agent);
            this._onDidChangeAgents.fire(undefined);
        });
    }
    updateAgent(id, updateMetadata) {
        const agent = this._getAgentEntry(id);
        if (!agent?.impl) {
            throw new Error(`No activated agent with id ${JSON.stringify(id)} registered`);
        }
        agent.data.metadata = { ...agent.data.metadata, ...updateMetadata };
        this._onDidChangeAgents.fire(( new MergedChatAgent(agent.data, agent.impl)));
    }
    getDefaultAgent(location) {
        return this.getActivatedAgents().find(a => !!a.isDefault && a.locations.includes(location));
    }
    getSecondaryAgent() {
        return Iterable.find(( this._agents.values()), a => !!a.data.metadata.isSecondary)?.data;
    }
    _getAgentEntry(id) {
        return this._agents.find(a => a.data.id === id);
    }
    getAgent(id) {
        return this._getAgentEntry(id)?.data;
    }
    getAgents() {
        return ( this._agents.map(entry => entry.data));
    }
    getActivatedAgents() {
        return ( Array.from(( this._agents.values()))
            .filter(a => !!a.impl)
            .map(a => ( new MergedChatAgent(a.data, a.impl))));
    }
    getAgentsByName(name) {
        return this.getAgents().filter(a => a.name === name);
    }
    async invokeAgent(id, request, progress, history, token) {
        const data = this._getAgentEntry(id);
        if (!data?.impl) {
            throw new Error(`No activated agent with id ${id}`);
        }
        return await data.impl.invoke(request, progress, history, token);
    }
    async getFollowups(id, request, result, history, token) {
        const data = this._getAgentEntry(id);
        if (!data?.impl) {
            throw new Error(`No activated agent with id ${id}`);
        }
        if (!data.impl?.provideFollowups) {
            return [];
        }
        return data.impl.provideFollowups(request, result, history, token);
    }
};
ChatAgentService = ( __decorate([
    ( __param(0, IContextKeyService))
], ChatAgentService));
class MergedChatAgent {
    constructor(data, impl) {
        this.data = data;
        this.impl = impl;
    }
    get id() { return this.data.id; }
    get name() { return this.data.name ?? ''; }
    get description() { return this.data.description ?? ''; }
    get extensionId() { return this.data.extensionId; }
    get isDefault() { return this.data.isDefault; }
    get metadata() { return this.data.metadata; }
    get slashCommands() { return this.data.slashCommands; }
    get defaultImplicitVariables() { return this.data.defaultImplicitVariables; }
    get locations() { return this.data.locations; }
    async invoke(request, progress, history, token) {
        return this.impl.invoke(request, progress, history, token);
    }
    async provideFollowups(request, result, history, token) {
        if (this.impl.provideFollowups) {
            return this.impl.provideFollowups(request, result, history, token);
        }
        return [];
    }
    provideWelcomeMessage(token) {
        if (this.impl.provideWelcomeMessage) {
            return this.impl.provideWelcomeMessage(token);
        }
        return undefined;
    }
    provideSampleQuestions(token) {
        if (this.impl.provideSampleQuestions) {
            return this.impl.provideSampleQuestions(token);
        }
        return undefined;
    }
}
export { ChatAgentLocation, ChatAgentService, IChatAgentService, MergedChatAgent };
