"""Protocol definitions for AWS client interfaces.

These protocols define the interface for AWS service clients, enabling:
- Type-safe code without importing boto3 types at call sites
- Mock objects in tests that satisfy structural typing checks
- A clean boundary between alice-cli logic and the AWS SDK
"""

from __future__ import annotations

from typing import Any, Protocol


class BedrockRuntimeClient(Protocol):
    """Protocol for boto3 bedrock-runtime client operations used by alice-cli."""

    def converse(
        self,
        *,
        modelId: str,
        messages: list[dict[str, Any]],
        inferenceConfig: dict[str, Any] | None = None,
        system: list[dict[str, Any]] | None = None,
        **kwargs: Any,
    ) -> dict[str, Any]:
        """Invoke the Converse API."""
        ...


class SecretsManagerClient(Protocol):
    """Protocol for boto3 secretsmanager client operations used by alice-cli."""

    def get_secret_value(
        self,
        *,
        SecretId: str,
        **kwargs: Any,
    ) -> dict[str, Any]:
        """Retrieve a secret value."""
        ...

    def list_secrets(
        self,
        *,
        Filters: list[dict[str, Any]] | None = None,
        **kwargs: Any,
    ) -> dict[str, Any]:
        """List secrets matching filters."""
        ...


class STSClient(Protocol):
    """Protocol for boto3 sts client operations used by alice-cli."""

    def get_caller_identity(self, **kwargs: Any) -> dict[str, Any]:
        """Get the current caller identity."""
        ...


class S3Client(Protocol):
    """Protocol for boto3 s3 client operations used by alice-cli."""

    def get_object(
        self,
        *,
        Bucket: str,
        Key: str,
        **kwargs: Any,
    ) -> dict[str, Any]:
        """Get an object from S3."""
        ...

    def put_object(
        self,
        *,
        Bucket: str,
        Key: str,
        Body: bytes,
        **kwargs: Any,
    ) -> dict[str, Any]:
        """Put an object to S3."""
        ...

    def head_object(
        self,
        *,
        Bucket: str,
        Key: str,
        **kwargs: Any,
    ) -> dict[str, Any]:
        """Get object metadata without downloading the body."""
        ...
