"""
Agent manifest A2A (Agent-to-Agent) Protocol models.

Defines A2A Agent Card and related configurations for Google's A2A Protocol.
"""

from pydantic import BaseModel, Field

from typing import Optional


class A2ACapabilities(BaseModel):
    """A2A agent capabilities."""

    streaming: bool = Field(False, description="Supports streaming responses")
    push_notifications: bool = Field(
        False,
        alias="pushNotifications",
        description="Supports push notifications",
    )
    state_transition_history: bool = Field(
        False,
        alias="stateTransitionHistory",
        description="Supports state transition history",
    )

    model_config = {"populate_by_name": True}


class A2AOAuth2Config(BaseModel):
    """A2A OAuth2 configuration."""

    authorization_url: str = Field(
        ...,
        alias="authorizationUrl",
        description="OAuth2 authorization URL",
    )
    token_url: str = Field(..., alias="tokenUrl", description="OAuth2 token URL")
    scopes: dict[str, str] = Field(
        default_factory=dict,
        description="Available OAuth2 scopes with descriptions",
    )

    model_config = {"populate_by_name": True}


class A2AAuthentication(BaseModel):
    """A2A authentication configuration."""

    schemes: list[str] = Field(
        default_factory=list,
        description="Supported authentication schemes (e.g., bearer, oauth2)",
    )
    oauth2: Optional[A2AOAuth2Config] = Field(None, description="OAuth2 configuration")


class A2ASkill(BaseModel):
    """
    A2A skill definition.

    Defines a capability/skill the agent can perform.
    """

    id: str = Field(..., description="Skill identifier")
    name: str = Field(..., description="Skill name")
    description: Optional[str] = Field(None, description="Skill description")
    tags: list[str] = Field(default_factory=list, description="Skill tags")
    examples: list[str] = Field(
        default_factory=list,
        description="Example inputs for this skill",
    )
    input_modes: list[str] = Field(
        default_factory=lambda: ["text"],
        alias="inputModes",
        description="Supported input modes (text, data, audio, video)",
    )
    output_modes: list[str] = Field(
        default_factory=lambda: ["text"],
        alias="outputModes",
        description="Supported output modes (text, data, audio, video)",
    )

    model_config = {"populate_by_name": True}


class A2AProvider(BaseModel):
    """A2A agent provider information."""

    organization: str = Field(..., description="Organization name")
    url: Optional[str] = Field(None, description="Organization URL")


class A2AAgentCard(BaseModel):
    """
    A2A Agent Card.

    Follows Google's A2A Protocol specification for agent discovery.
    """

    name: str = Field(..., description="Agent name")
    description: Optional[str] = Field(None, description="Agent description")
    url: str = Field(..., description="Agent endpoint URL")

    # Provider information
    provider: Optional[A2AProvider] = Field(None, description="Agent provider")

    # Capabilities
    capabilities: A2ACapabilities = Field(
        default_factory=A2ACapabilities,
        description="Agent capabilities",
    )

    # Authentication
    authentication: Optional[A2AAuthentication] = Field(
        None,
        description="Authentication requirements",
    )

    # Default I/O modes
    default_input_modes: list[str] = Field(
        default_factory=lambda: ["text"],
        alias="defaultInputModes",
        description="Default input modes",
    )
    default_output_modes: list[str] = Field(
        default_factory=lambda: ["text"],
        alias="defaultOutputModes",
        description="Default output modes",
    )

    # Skills
    skills: list[A2ASkill] = Field(default_factory=list, description="Agent skills")

    model_config = {"populate_by_name": True}


class A2AConfig(BaseModel):
    """
    A2A configuration block.

    Defines the A2A Agent Card for this agent.
    """

    agent_card: A2AAgentCard = Field(
        ...,
        alias="agentCard",
        description="A2A Agent Card",
    )

    model_config = {"populate_by_name": True}
