"""Protocol interfaces for the MCP Proxy components.

This module defines the abstract interfaces (protocols) that components
must implement, enabling loose coupling and testability.
"""

from typing import Protocol, Optional, AsyncIterator
from .models import (
    JsonRpcMessage,
    HttpMcpRequest,
    HttpMcpResponse,
    ClientCredentials,
    OAuthTokenResponse,
    ProxyConfig,
    AuthenticationState,
)


class StdioInterface(Protocol):
    """Interface for stdio communication with Kiro."""

    async def start(self) -> None:
        """Start the stdio interface."""
        ...

    async def stop(self) -> None:
        """Stop the stdio interface."""
        ...

    async def send_message(self, message: JsonRpcMessage) -> None:
        """Send a JSON-RPC message to stdout."""
        ...

    async def receive_message(self) -> JsonRpcMessage:
        """Receive a JSON-RPC message from stdin."""
        ...


class ProtocolTranslator(Protocol):
    """Interface for protocol translation between stdio and HTTP."""

    async def translate_stdio_to_http(
        self, message: JsonRpcMessage
    ) -> HttpMcpRequest:
        """Translate stdio JSON-RPC message to HTTP MCP request."""
        ...

    async def translate_http_to_stdio(
        self, response: HttpMcpResponse
    ) -> JsonRpcMessage:
        """Translate HTTP MCP response to stdio JSON-RPC message."""
        ...

    def correlate_messages(self, request_id: str, response_id: str) -> None:
        """Correlate request and response messages."""
        ...


class AuthenticationManager(Protocol):
    """Interface for OAuth DCR and token management."""

    async def initialize(self) -> None:
        """Initialize authentication manager and perform DCR if needed."""
        ...

    async def get_access_token(self) -> str:
        """Get a valid access token, refreshing if necessary."""
        ...

    async def refresh_token(self) -> str:
        """Refresh the access token."""
        ...

    async def perform_dcr(self) -> ClientCredentials:
        """Perform OAuth Dynamic Client Registration."""
        ...

    def is_token_valid(self) -> bool:
        """Check if current token is valid."""
        ...

    def get_state(self) -> AuthenticationState:
        """Get current authentication state."""
        ...


class HttpClient(Protocol):
    """Interface for HTTP communication with backend MCP server."""

    async def send_request(self, request: HttpMcpRequest) -> HttpMcpResponse:
        """Send HTTP request to backend MCP server."""
        ...

    async def open_sse_stream(
        self, session_id: Optional[str] = None
    ) -> AsyncIterator[str]:
        """Open Server-Sent Events stream."""
        ...

    async def close_connection(self) -> None:
        """Close HTTP connection."""
        ...

    def set_auth_token(self, token: str) -> None:
        """Set authentication token for requests."""
        ...


class ConfigurationManager(Protocol):
    """Interface for configuration management."""

    async def load(self) -> ProxyConfig:
        """Load configuration from environment and files."""
        ...

    def validate(self, config: ProxyConfig) -> bool:
        """Validate configuration parameters."""
        ...

    def get_defaults(self) -> ProxyConfig:
        """Get default configuration values."""
        ...
