import { onUnexpectedExternalError } from '../../../base/common/errors.js';
import { toDisposable } from '../../../base/common/lifecycle.js';
import { MainContext } from './extHost.protocol.js';
import { ChatVariable, ChatResponseProgressPart, ChatResponseReferencePart } from './extHostTypeConverters.js';
import { ChatResponseReferencePart as ChatResponseReferencePart$1, ChatResponseProgressPart as ChatResponseProgressPart$1 } from './extHostTypes.js';
import { checkProposedApiEnabled } from '../../services/extensions/common/extensions.js';
class ExtHostChatVariables {
    static { this._idPool = 0; }
    constructor(mainContext) {
        this._resolver = ( new Map());
        this._proxy = ( mainContext.getProxy(MainContext.MainThreadChatVariables));
    }
    async $resolveVariable(handle, requestId, messageText, token) {
        const item = this._resolver.get(handle);
        if (!item) {
            return undefined;
        }
        try {
            if (item.resolver.resolve2) {
                checkProposedApiEnabled(item.extension, 'chatParticipantAdditions');
                const stream = ( new ChatVariableResolverResponseStream(requestId, this._proxy));
                const value = await item.resolver.resolve2(item.data.name, { prompt: messageText }, stream.apiObject, token);
                if (value) {
                    return ( value.map(ChatVariable.from));
                }
            }
            else {
                const value = await item.resolver.resolve(item.data.name, { prompt: messageText }, token);
                if (value) {
                    return ( value.map(ChatVariable.from));
                }
            }
        }
        catch (err) {
            onUnexpectedExternalError(err);
        }
        return undefined;
    }
    registerVariableResolver(extension, name, description, resolver) {
        const handle = ExtHostChatVariables._idPool++;
        this._resolver.set(handle, { extension, data: { name, description }, resolver: resolver });
        this._proxy.$registerVariable(handle, { name, description });
        return toDisposable(() => {
            this._resolver.delete(handle);
            this._proxy.$unregisterVariable(handle);
        });
    }
}
class ChatVariableResolverResponseStream {
    constructor(_requestId, _proxy) {
        this._requestId = _requestId;
        this._proxy = _proxy;
        this._isClosed = false;
    }
    close() {
        this._isClosed = true;
    }
    get apiObject() {
        if (!this._apiObject) {
            const that = this;
            function throwIfDone(source) {
                if (that._isClosed) {
                    const err = ( new Error('Response stream has been closed'));
                    Error.captureStackTrace(err, source);
                    throw err;
                }
            }
            const _report = (progress) => {
                this._proxy.$handleProgressChunk(this._requestId, progress);
            };
            this._apiObject = {
                progress(value) {
                    throwIfDone(this.progress);
                    const part = new ChatResponseProgressPart$1(value);
                    const dto = ChatResponseProgressPart.to(part);
                    _report(dto);
                    return this;
                },
                reference(value) {
                    throwIfDone(this.reference);
                    const part = new ChatResponseReferencePart$1(value);
                    const dto = ChatResponseReferencePart.to(part);
                    _report(dto);
                    return this;
                },
                push(part) {
                    throwIfDone(this.push);
                    if (part instanceof ChatResponseReferencePart$1) {
                        _report(ChatResponseReferencePart.to(part));
                    }
                    else if (part instanceof ChatResponseProgressPart$1) {
                        _report(ChatResponseProgressPart.to(part));
                    }
                    return this;
                }
            };
        }
        return this._apiObject;
    }
}
export { ExtHostChatVariables };
