"""
Async base client for gRPC communication with Daisi services.
"""

from typing import Any, Optional, Tuple

import grpc.aio

from ..config import DaisiConfig


class AsyncBaseClient:
    """Async base client providing common gRPC functionality."""

    def __init__(self, config: Optional[DaisiConfig] = None) -> None:
        """Initialize async base client.

        Args:
            config: Daisi configuration. Creates default if not provided.
        """
        self.config = config or DaisiConfig()
        self._channel: Optional[grpc.aio.Channel] = None

    def _get_channel(self, address: Optional[str] = None) -> grpc.aio.Channel:
        """Get or create async gRPC channel.

        Args:
            address: Optional custom address. Uses config orc_url if not provided.

        Returns:
            Async gRPC channel.
        """
        if self._channel is None:
            target = address or f"{self.config.orc_address}:{self.config.orc_port}"

            if self.config.use_ssl:
                credentials = grpc.ssl_channel_credentials()
                options = [
                    ("grpc.ssl_target_name_override", self.config.orc_address),
                ]
                self._channel = grpc.aio.secure_channel(target, credentials, options)
            else:
                self._channel = grpc.aio.insecure_channel(target)

        return self._channel

    def _get_metadata(
        self, additional_metadata: Optional[list[Tuple[str, str]]] = None
    ) -> list[Tuple[str, str]]:
        """Get gRPC metadata including auth header.

        Args:
            additional_metadata: Optional additional metadata to include.

        Returns:
            List of metadata tuples.
        """
        metadata = [(self.config.client_key_header, self.config.client_key)]

        if additional_metadata:
            metadata.extend(additional_metadata)

        return metadata

    async def close(self) -> None:
        """Close the async gRPC channel."""
        if self._channel:
            await self._channel.close()
            self._channel = None

    async def __aenter__(self) -> "AsyncBaseClient":
        """Async context manager entry."""
        return self

    async def __aexit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
        """Async context manager exit."""
        await self.close()
