
import { Iterable } from '../../../../base/common/iterator.js';
import { toDisposable, Disposable } from '../../../../base/common/lifecycle.js';
import { Schemas } from '../../../../base/common/network.js';
import '../../../../base/common/observableInternal/index.js';
import { URI } from '../../../../base/common/uri.js';
import { localize } from '../../../../nls.js';
import { ByteSize } from '../../../../platform/files/common/files.js';
import { stringifyPromptElementJSON } from './tools/promptTsxTypes.js';
import { ObservableSet } from '../../../../base/common/observableInternal/set.js';
import { derived } from '../../../../base/common/observableInternal/observables/derived.js';

var ToolDataSource;
(function (ToolDataSource) {
    ToolDataSource.Internal = { type: 'internal', label: 'Built-In' };
    ToolDataSource.External = { type: 'external', label: 'External' };
    function toKey(source) {
        switch (source.type) {
            case 'extension': return `extension:${source.extensionId.value}`;
            case 'mcp': return `mcp:${source.collectionId}:${source.definitionId}`;
            case 'user': return `user:${( source.file.toString())}`;
            case 'internal': return 'internal';
            case 'external': return 'external';
        }
    }
    ToolDataSource.toKey = toKey;
    function equals(a, b) {
        return toKey(a) === toKey(b);
    }
    ToolDataSource.equals = equals;
    function classify(source) {
        if (source.type === 'internal') {
            return { ordinal: 1, label: ( localize(5816, 'Built-In')) };
        }
        else if (source.type === 'mcp') {
            return { ordinal: 2, label: source.label };
        }
        else if (source.type === 'user') {
            return { ordinal: 0, label: ( localize(5817, 'User Defined')) };
        }
        else {
            return { ordinal: 3, label: source.label };
        }
    }
    ToolDataSource.classify = classify;
})(ToolDataSource || (ToolDataSource = {}));
function isToolInvocationContext(obj) {
    return typeof obj === 'object' && typeof obj.sessionId === 'string';
}
function isToolResultInputOutputDetails(obj) {
    return typeof obj === 'object' && typeof obj?.input === 'string' && (typeof obj?.output === 'string' || Array.isArray(obj?.output));
}
function isToolResultOutputDetails(obj) {
    return typeof obj === 'object' && typeof obj?.output === 'object' && typeof obj?.output?.mimeType === 'string' && obj?.output?.type === 'data';
}
function toolContentToA11yString(part) {
    return ( part.map(p => {
        switch (p.kind) {
            case 'promptTsx':
                return stringifyPromptTsxPart(p);
            case 'text':
                return p.value;
            case 'data':
                return localize(
                    5818,
                    "{0} of {1} binary data",
                    ByteSize.formatSize(p.value.data.byteLength),
                    p.value.mimeType || 'unknown'
                );
        }
    })).join(', ');
}
function toolResultHasBuffers(result) {
    return ( result.content.some(part => part.kind === 'data'));
}
function stringifyPromptTsxPart(part) {
    return stringifyPromptElementJSON(part.value);
}
var ToolInvocationPresentation;
(function (ToolInvocationPresentation) {
    ToolInvocationPresentation["Hidden"] = "hidden";
    ToolInvocationPresentation["HiddenAfterComplete"] = "hiddenAfterComplete";
})(ToolInvocationPresentation || (ToolInvocationPresentation = {}));
class ToolSet {
    constructor(id, referenceName, icon, source, description) {
        this.id = id;
        this.referenceName = referenceName;
        this.icon = icon;
        this.source = source;
        this.description = description;
        this._tools = ( new ObservableSet());
        this._toolSets = ( new ObservableSet());
        this.isHomogenous = derived(r => {
            return !( Iterable.some(
                this._tools.observable.read(r),
                tool => !ToolDataSource.equals(tool.source, this.source)
            ))
                && !( Iterable.some(
                this._toolSets.observable.read(r),
                toolSet => !ToolDataSource.equals(toolSet.source, this.source)
            ));
        });
    }
    addTool(data, tx) {
        this._tools.add(data, tx);
        return toDisposable(() => {
            this._tools.delete(data);
        });
    }
    addToolSet(toolSet, tx) {
        if (toolSet === this) {
            return Disposable.None;
        }
        this._toolSets.add(toolSet, tx);
        return toDisposable(() => {
            this._toolSets.delete(toolSet);
        });
    }
    getTools(r) {
        return Iterable.concat(this._tools.observable.read(r), ...( Iterable.map(this._toolSets.observable.read(r), toolSet => toolSet.getTools(r))));
    }
}
function createToolInputUri(toolCallId) {
    return ( URI.from(
        { scheme: Schemas.inMemory, path: `/lm/tool/${toolCallId}/tool_input.json` }
    ));
}
function createToolSchemaUri(toolOrId) {
    if (typeof toolOrId !== 'string') {
        toolOrId = toolOrId.id;
    }
    return ( URI.from(
        { scheme: Schemas.vscode, authority: 'schemas', path: `/lm/tool/${toolOrId}` }
    ));
}
var GithubCopilotToolReference;
(function (GithubCopilotToolReference) {
    GithubCopilotToolReference.shell = 'shell';
    GithubCopilotToolReference.edit = 'edit';
    GithubCopilotToolReference.search = 'search';
    GithubCopilotToolReference.customAgent = 'custom-agent';
})(GithubCopilotToolReference || (GithubCopilotToolReference = {}));
var VSCodeToolReference;
(function (VSCodeToolReference) {
    VSCodeToolReference.runCommands = 'runCommands';
    VSCodeToolReference.runSubagent = 'runSubagent';
})(VSCodeToolReference || (VSCodeToolReference = {}));

export { GithubCopilotToolReference, ToolDataSource, ToolInvocationPresentation, ToolSet, VSCodeToolReference, createToolInputUri, createToolSchemaUri, isToolInvocationContext, isToolResultInputOutputDetails, isToolResultOutputDetails, stringifyPromptTsxPart, toolContentToA11yString, toolResultHasBuffers };
