"""Redis client wrapper with connection pooling and Logfire instrumentation."""

import os
import socket
from typing import Optional

import redis
from redis.connection import ConnectionPool

from common.logging import get_logger

logger = get_logger(__name__)


class RedisConfig:
    """Redis configuration from environment variables."""

    def __init__(self):
        self.host = os.getenv("REDIS_HOST", "localhost")
        self.port = int(os.getenv("REDIS_PORT", "6379"))
        self.password = os.getenv("REDIS_PASSWORD")
        self.db = int(os.getenv("REDIS_DB", "0"))
        self.use_tls = os.getenv("REDIS_USE_TLS", "false").lower() == "true"

        if not self.host:
            raise ValueError("REDIS_HOST environment variable is required")


def _build_keepalive_options() -> dict[int, int]:
    """Build platform-compatible TCP keepalive socket options."""
    options: dict[int, int] = {}

    # Linux uses TCP_KEEPIDLE; macOS uses TCP_KEEPALIVE for idle time.
    idle_opt = getattr(socket, "TCP_KEEPIDLE", None)
    if idle_opt is None:
        idle_opt = getattr(socket, "TCP_KEEPALIVE", None)
    if idle_opt is not None:
        options[idle_opt] = 30

    keepintvl_opt = getattr(socket, "TCP_KEEPINTVL", None)
    if keepintvl_opt is not None:
        options[keepintvl_opt] = 10

    keepcnt_opt = getattr(socket, "TCP_KEEPCNT", None)
    if keepcnt_opt is not None:
        options[keepcnt_opt] = 3

    return options


def get_redis_client(config: Optional[RedisConfig] = None) -> redis.Redis:
    """
    Get Redis client with connection pooling.

    Args:
        config: Redis configuration (defaults to environment variables)

    Returns:
        redis.Redis: Configured Redis client with connection pooling

    Example:
        >>> client = get_redis_client()
        >>> client.set("key", "value", ex=300)
        >>> value = client.get("key")
    """
    if config is None:
        config = RedisConfig()

    # Create connection pool
    # For TLS connections to ElastiCache AUTH token mode (Redis 7.x)
    # AUTH token mode does NOT use RBAC - password-only authentication
    connection_kwargs = {
        "host": config.host,
        "port": config.port,
        # NO username parameter - AUTH token mode uses password-only
        "password": config.password,
        "db": config.db,
        "decode_responses": True,
        "max_connections": 50,
        "socket_keepalive": True,
        "health_check_interval": 30,
    }
    keepalive_options = _build_keepalive_options()
    if keepalive_options:
        connection_kwargs["socket_keepalive_options"] = keepalive_options

    # Add SSL connection class for TLS
    if config.use_tls:
        from redis.connection import SSLConnection

        connection_kwargs["connection_class"] = SSLConnection
        connection_kwargs["ssl_cert_reqs"] = (
            "none"  # Disable cert verification for ElastiCache
        )
        connection_kwargs["ssl_check_hostname"] = False

    pool = ConnectionPool(**connection_kwargs)

    client = redis.Redis(connection_pool=pool)

    logger.debug(
        "Redis client initialized",
        extra={
            "host": config.host,
            "port": config.port,
            "db": config.db,
            "use_tls": config.use_tls,
        },
    )

    return client
