"""
Agent manifest MCP (Model Context Protocol) models.

Defines MCP server and client configurations for tool integration.
"""

from pydantic import BaseModel, Field

from typing import Literal, Optional


class MCPTool(BaseModel):
    """
    MCP tool definition.

    Defines a tool exposed via MCP server.
    """

    name: str = Field(..., description="Tool name")
    description: str = Field(..., description="Tool description")
    input_schema: dict[str, object] = Field(
        ...,
        alias="inputSchema",
        description="JSON Schema for tool input",
    )

    model_config = {"populate_by_name": True}


class MCPResource(BaseModel):
    """
    MCP resource definition.

    Defines a resource exposed via MCP server.
    """

    uri: str = Field(..., description="Resource URI template (e.g., knowledge://articles/{id})")
    name: str = Field(..., description="Resource name")
    description: Optional[str] = Field(None, description="Resource description")
    mime_type: Optional[str] = Field(
        None,
        alias="mimeType",
        description="Resource MIME type",
    )

    model_config = {"populate_by_name": True}


class MCPPromptArgument(BaseModel):
    """MCP prompt argument definition."""

    name: str = Field(..., description="Argument name")
    description: Optional[str] = Field(None, description="Argument description")
    required: bool = Field(False, description="Whether argument is required")


class MCPPrompt(BaseModel):
    """
    MCP prompt definition.

    Defines a prompt template exposed via MCP server.
    """

    name: str = Field(..., description="Prompt name")
    description: Optional[str] = Field(None, description="Prompt description")
    arguments: list[MCPPromptArgument] = Field(
        default_factory=list,
        description="Prompt arguments",
    )


class MCPServer(BaseModel):
    """
    MCP server configuration.

    Defines the MCP server this agent provides.
    """

    name: str = Field(..., description="Server name")
    version: str = Field(..., description="Server version")
    description: Optional[str] = Field(None, description="Server description")

    # Exposed capabilities
    tools: list[MCPTool] = Field(default_factory=list, description="Tools exposed via MCP")
    resources: list[MCPResource] = Field(
        default_factory=list,
        description="Resources exposed via MCP",
    )
    prompts: list[MCPPrompt] = Field(default_factory=list, description="Prompts exposed via MCP")


class MCPClient(BaseModel):
    """
    MCP client configuration.

    Defines an MCP server this agent connects to.
    """

    name: str = Field(..., description="Client name (for reference)")

    # Remote server connection
    url: Optional[str] = Field(None, description="MCP server URL")

    # Local server connection (stdio transport)
    command: Optional[str] = Field(None, description="Command to start local MCP server")
    args: list[str] = Field(default_factory=list, description="Command arguments")

    # Transport configuration
    transport: Literal["sse", "stdio", "websocket"] = Field(
        "sse",
        description="Transport protocol",
    )

    # Additional configuration
    config: dict[str, object] = Field(
        default_factory=dict,
        description="Additional client configuration (e.g., api_key)",
    )


class MCPConfig(BaseModel):
    """
    MCP configuration block.

    Defines both the MCP server this agent provides and
    the MCP servers this agent connects to.
    """

    # MCP server this agent provides
    server: Optional[MCPServer] = Field(
        None,
        description="MCP server configuration (tools/resources this agent exposes)",
    )

    # MCP servers this agent connects to
    clients: list[MCPClient] = Field(
        default_factory=list,
        description="MCP clients (servers this agent connects to)",
    )
