
import { MarkdownString } from '../../../../base/common/htmlContent.js';
import { Disposable } from '../../../../base/common/lifecycle.js';
import { localize } from '../../../../nls.js';
import { SyncDescriptor } from '../../../../platform/instantiation/common/descriptors.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { mcpSchemaId } from '../../../services/configuration/common/configuration.js';
import { inputsSchema } from '../../../services/configurationResolver/common/configurationResolverSchema.js';
import { Extensions } from '../../../services/extensionManagement/common/extensionFeatures.js';

const mcpActivationEventPrefix = "onMcpCollection:";
const mcpActivationEvent = contributedCollectionId => mcpActivationEventPrefix + contributedCollectionId;
var DiscoverySource;
(function(DiscoverySource) {
    DiscoverySource["ClaudeDesktop"] = "claude-desktop";
    DiscoverySource["Windsurf"] = "windsurf";
    DiscoverySource["CursorGlobal"] = "cursor-global";
    DiscoverySource["CursorWorkspace"] = "cursor-workspace";
})(DiscoverySource || (DiscoverySource = {}));
const allDiscoverySources = ( Object.keys({
    [DiscoverySource.ClaudeDesktop]: true,
    [DiscoverySource.Windsurf]: true,
    [DiscoverySource.CursorGlobal]: true,
    [DiscoverySource.CursorWorkspace]: true
}));
const discoverySourceLabel = {
    [DiscoverySource.ClaudeDesktop]: ( localize(10629, "Claude Desktop")),
    [DiscoverySource.Windsurf]: ( localize(10630, "Windsurf")),
    [DiscoverySource.CursorGlobal]: ( localize(10631, "Cursor (Global)")),
    [DiscoverySource.CursorWorkspace]: ( localize(10632, "Cursor (Workspace)"))
};
const discoverySourceSettingsLabel = {
    [DiscoverySource.ClaudeDesktop]: ( localize(10633, "Claude Desktop configuration (`claude_desktop_config.json`)")),
    [DiscoverySource.Windsurf]: ( localize(10634, "Windsurf configurations (`~/.codeium/windsurf/mcp_config.json`)")),
    [DiscoverySource.CursorGlobal]: ( localize(10635, "Cursor global configuration (`~/.cursor/mcp.json`)")),
    [DiscoverySource.CursorWorkspace]: ( localize(10636, "Cursor workspace configuration (`.cursor/mcp.json`)"))
};
const mcpConfigurationSection = "mcp";
const mcpDiscoverySection = "chat.mcp.discovery.enabled";
const mcpServerSamplingSection = "chat.mcp.serverSampling";
const mcpSchemaExampleServers = {
    "mcp-server-time": {
        command: "python",
        args: ["-m", "mcp_server_time", "--local-timezone=America/Los_Angeles"],
        env: {}
    }
};
const httpSchemaExamples = {
    "my-mcp-server": {
        url: "http://localhost:3001/mcp",
        headers: {}
    }
};
const mcpDevModeProps = stdio => ({
    dev: {
        type: "object",
        markdownDescription: ( localize(
            10637,
            "Enabled development mode for the server. When present, the server will be started eagerly and output will be included in its output. Properties inside the `dev` object can configure additional behavior."
        )),
        examples: [{
            watch: "src/**/*.ts",
            debug: {
                type: "node"
            }
        }],
        properties: {
            watch: {
                description: ( localize(
                    10638,
                    "A glob pattern or list of glob patterns relative to the workspace folder to watch. The MCP server will be restarted when these files change."
                )),
                examples: ["src/**/*.ts"],
                oneOf: [{
                    type: "string"
                }, {
                    type: "array",
                    items: {
                        type: "string"
                    }
                }]
            },
            ...(stdio && {
                debug: {
                    markdownDescription: ( localize(
                        10639,
                        "If set, debugs the MCP server using the given runtime as it's started."
                    )),
                    oneOf: [{
                        type: "object",
                        required: ["type"],
                        properties: {
                            type: {
                                type: "string",
                                enum: ["node"],
                                description: ( localize(10640, "Debug the MCP server using Node.js."))
                            }
                        },
                        additionalProperties: false
                    }, {
                        type: "object",
                        required: ["type"],
                        properties: {
                            type: {
                                type: "string",
                                enum: ["debugpy"],
                                description: ( localize(10641, "Debug the MCP server using Python and debugpy."))
                            },
                            debugpyPath: {
                                type: "string",
                                description: ( localize(10642, "Path to the debugpy executable."))
                            }
                        },
                        additionalProperties: false
                    }]
                }
            })
        }
    }
});
const mcpStdioServerSchema = {
    type: "object",
    additionalProperties: false,
    examples: [mcpSchemaExampleServers["mcp-server-time"]],
    properties: {
        type: {
            type: "string",
            enum: ["stdio"],
            description: ( localize(10643, "The type of the server."))
        },
        sandboxEnabled: {
            type: "boolean",
            default: false,
            description: ( localize(10644, "Whether to run the server in a sandboxed environment."))
        },
        command: {
            type: "string",
            description: ( localize(10645, "The command to run the server."))
        },
        cwd: {
            type: "string",
            description: ( localize(
                10646,
                "The working directory for the server command. Defaults to the workspace folder when run in a workspace."
            )),
            examples: ["${workspaceFolder}"]
        },
        args: {
            type: "array",
            description: ( localize(10647, "Arguments passed to the server.")),
            items: {
                type: "string"
            }
        },
        envFile: {
            type: "string",
            description: ( localize(10648, "Path to a file containing environment variables for the server.")),
            examples: ["${workspaceFolder}/.env"]
        },
        env: {
            description: ( localize(10649, "Environment variables passed to the server.")),
            additionalProperties: {
                anyOf: [{
                    type: "null"
                }, {
                    type: "string"
                }, {
                    type: "number"
                }]
            }
        },
        ...mcpDevModeProps(true)
    }
};
const mcpServerSchema = {
    id: mcpSchemaId,
    type: "object",
    title: ( localize(10650, "Model Context Protocol Servers")),
    allowTrailingCommas: true,
    allowComments: true,
    additionalProperties: false,
    properties: {
        sandbox: {
            description: ( localize(
                10651,
                "Sandbox config that determines file system and network access. Sandboxing is enabled when sandboxEnabled property is set at the server level on Mac OS and Linux only."
            )),
            type: "object",
            additionalProperties: false,
            properties: {
                network: {
                    description: ( localize(10652, "Network access settings for the sandboxed server.")),
                    type: "object",
                    additionalProperties: false,
                    properties: {
                        allowedDomains: {
                            description: ( localize(
                                10653,
                                "List of domains that the server is allowed to access. Wildcards are supported, e.g. `*.example.com`."
                            )),
                            type: "array",
                            items: {
                                type: "string"
                            },
                            default: []
                        },
                        deniedDomains: {
                            description: ( localize(
                                10654,
                                "List of domains that the server is not allowed to access. e.g. `invalid.example.com`."
                            )),
                            type: "array",
                            items: {
                                type: "string"
                            },
                            default: []
                        }
                    }
                },
                filesystem: {
                    description: ( localize(
                        10655,
                        "Filesystem access settings for the sandboxed server. Glob patterns are supported for Mac OS only."
                    )),
                    type: "object",
                    additionalProperties: false,
                    properties: {
                        denyRead: {
                            description: ( localize(
                                10656,
                                "List of file paths that the server is not allowed to read. By default, all files are allowed to be read. e.g. `~/src/secrets`."
                            )),
                            type: "array",
                            items: {
                                type: "string"
                            },
                            default: []
                        },
                        allowWrite: {
                            description: ( localize(
                                10657,
                                "List of file paths that the server is allowed to write to. e.g. `~/src/`."
                            )),
                            type: "array",
                            items: {
                                type: "string"
                            },
                            default: []
                        },
                        denyWrite: {
                            description: ( localize(
                                10658,
                                "List of file paths that the server is not allowed to write to. e.g. `~/src/auth/`."
                            )),
                            type: "array",
                            items: {
                                type: "string"
                            },
                            default: []
                        }
                    }
                }
            }
        },
        servers: {
            examples: [mcpSchemaExampleServers, httpSchemaExamples],
            additionalProperties: {
                oneOf: [mcpStdioServerSchema, {
                    type: "object",
                    additionalProperties: false,
                    required: ["url"],
                    examples: [httpSchemaExamples["my-mcp-server"]],
                    properties: {
                        type: {
                            type: "string",
                            enum: ["http", "sse"],
                            description: ( localize(10643, "The type of the server."))
                        },
                        url: {
                            type: "string",
                            format: "uri",
                            pattern: "^https?:\\/\\/.+",
                            patternErrorMessage: ( localize(10659, "The URL must start with 'http://' or 'https://'.")),
                            description: ( localize(10660, "The URL of the Streamable HTTP or SSE endpoint."))
                        },
                        headers: {
                            type: "object",
                            description: ( localize(10661, "Additional headers sent to the server.")),
                            additionalProperties: {
                                type: "string"
                            }
                        },
                        ...mcpDevModeProps(false)
                    }
                }]
            }
        },
        inputs: inputsSchema.definitions.inputs
    }
};
const mcpContributionPoint = {
    extensionPoint: "mcpServerDefinitionProviders",
    activationEventsGenerator: function*(contribs) {
        for (const contrib of contribs) {
            if (contrib.id) {
                yield mcpActivationEvent(contrib.id);
            }
        }
    },
    jsonSchema: {
        description: ( localize(
            10662,
            "Contributes Model Context Protocol servers. Users of this should also use `vscode.lm.registerMcpServerDefinitionProvider`."
        )),
        type: "array",
        defaultSnippets: [{
            body: [{
                id: "",
                label: ""
            }]
        }],
        items: {
            additionalProperties: false,
            type: "object",
            defaultSnippets: [{
                body: {
                    id: "",
                    label: ""
                }
            }],
            properties: {
                id: {
                    description: ( localize(10663, "Unique ID for the collection.")),
                    type: "string"
                },
                label: {
                    description: ( localize(10664, "Display name for the collection.")),
                    type: "string"
                },
                when: {
                    description: ( localize(10665, "Condition which must be true to enable this collection.")),
                    type: "string"
                }
            }
        }
    }
};
class McpServerDefinitionsProviderRenderer extends Disposable {
    constructor() {
        super(...arguments);
        this.type = "table";
    }
    shouldRender(manifest) {
        return !!manifest.contributes?.mcpServerDefinitionProviders && Array.isArray(manifest.contributes.mcpServerDefinitionProviders) && manifest.contributes.mcpServerDefinitionProviders.length > 0;
    }
    render(manifest) {
        const mcpServerDefinitionProviders = manifest.contributes?.mcpServerDefinitionProviders ?? [];
        const headers = [( localize(10666, "ID")), ( localize(10667, "Name"))];
        const rows = ( mcpServerDefinitionProviders.map(mcpServerDefinitionProvider => {
            return [( new MarkdownString()).appendMarkdown(`\`${mcpServerDefinitionProvider.id}\``), mcpServerDefinitionProvider.label];
        }));
        return {
            data: {
                headers,
                rows
            },
            dispose: () => {}
        };
    }
}
( Registry.as(Extensions.ExtensionFeaturesRegistry)).registerExtensionFeature({
    id: mcpConfigurationSection,
    label: ( localize(10668, "MCP Servers")),
    access: {
        canToggle: false
    },
    renderer: ( new SyncDescriptor(McpServerDefinitionsProviderRenderer))
});

export { DiscoverySource, allDiscoverySources, discoverySourceLabel, discoverySourceSettingsLabel, mcpActivationEvent, mcpConfigurationSection, mcpContributionPoint, mcpDiscoverySection, mcpSchemaExampleServers, mcpServerSamplingSection, mcpServerSchema, mcpStdioServerSchema };
