"""
Configuration constants and settings for Revenium Google middleware.

This module centralizes all configuration values to eliminate magic numbers
and provide a single source of truth for middleware behavior.
"""

import logging
import os
from typing import Set


def _parse_max_prompt_length() -> int:
    """Parse MAX_PROMPT_LENGTH from env var with safe fallback."""
    default_value = 10000
    env_value = os.getenv("REVENIUM_MAX_PROMPT_LENGTH", str(default_value))
    try:
        parsed = int(env_value)
        # Validate range (must be positive, reasonable upper limit)
        if parsed <= 0:
            logger = logging.getLogger("revenium_middleware.config")
            logger.warning(
                f"REVENIUM_MAX_PROMPT_LENGTH must be positive, got {parsed}. "
                f"Using default: {default_value}"
            )
            return default_value
        if parsed > 1_000_000:  # 1MB character limit
            logger = logging.getLogger("revenium_middleware.config")
            logger.warning(
                f"REVENIUM_MAX_PROMPT_LENGTH too large ({parsed}), "
                f"capping at 1,000,000 characters"
            )
            return 1_000_000
        return parsed
    except (ValueError, TypeError) as e:
        logger = logging.getLogger("revenium_middleware.config")
        logger.warning(
            f"Invalid REVENIUM_MAX_PROMPT_LENGTH value '{env_value}': {e}. "
            f"Using default: {default_value}"
        )
        return default_value


class Config:
    """Configuration constants for Revenium Google middleware."""
    
    # Threading and async timeouts
    THREAD_JOIN_TIMEOUT: float = 5.0
    API_REQUEST_TIMEOUT: float = 30.0
    BACKGROUND_THREAD_TIMEOUT: float = 5.0
    
    # Cache settings
    PROVIDER_CACHE_TTL: int = 3600  # 1 hour
    MODEL_CACHE_TTL: int = 3600     # 1 hour
    
    # Logging and security
    MAX_LOG_STRING_LENGTH: int = 100
    MAX_SANITIZATION_DEPTH: int = 3
    
    # Stream processing
    STREAM_CHUNK_BUFFER_SIZE: int = 1000
    STREAM_TIMEOUT: float = 30.0
    
    # Retry and resilience
    MAX_RETRY_ATTEMPTS: int = 3
    RETRY_BACKOFF_FACTOR: float = 1.5
    INITIAL_RETRY_DELAY: float = 0.1
    
    # Environment variable names
    ENV_GOOGLE_API_KEY: str = "GOOGLE_API_KEY"
    ENV_GOOGLE_CLOUD_PROJECT: str = "GOOGLE_CLOUD_PROJECT"
    ENV_GOOGLE_APPLICATION_CREDENTIALS: str = "GOOGLE_APPLICATION_CREDENTIALS"
    ENV_REVENIUM_API_KEY: str = "REVENIUM_METERING_API_KEY"
    ENV_LOG_LEVEL: str = "REVENIUM_LOG_LEVEL"

    # Trace visualization environment variables
    ENV_REVENIUM_ENVIRONMENT: str = "REVENIUM_ENVIRONMENT"
    ENV_ENVIRONMENT: str = "ENVIRONMENT"
    ENV_DEPLOYMENT_ENV: str = "DEPLOYMENT_ENV"

    ENV_REVENIUM_REGION: str = "REVENIUM_REGION"
    ENV_GCP_REGION: str = "GCP_REGION"
    ENV_GOOGLE_CLOUD_REGION: str = "GOOGLE_CLOUD_REGION"

    ENV_REVENIUM_CREDENTIAL_ALIAS: str = "REVENIUM_CREDENTIAL_ALIAS"
    ENV_REVENIUM_TRACE_TYPE: str = "REVENIUM_TRACE_TYPE"
    ENV_REVENIUM_TRACE_NAME: str = "REVENIUM_TRACE_NAME"
    ENV_REVENIUM_PARENT_TRANSACTION_ID: str = (
        "REVENIUM_PARENT_TRANSACTION_ID"
    )
    ENV_REVENIUM_TRANSACTION_NAME: str = "REVENIUM_TRANSACTION_NAME"
    ENV_REVENIUM_RETRY_NUMBER: str = "REVENIUM_RETRY_NUMBER"

    # Prompt capture settings
    ENV_REVENIUM_CAPTURE_PROMPTS: str = "REVENIUM_CAPTURE_PROMPTS"
    ENV_REVENIUM_MAX_PROMPT_LENGTH: str = "REVENIUM_MAX_PROMPT_LENGTH"
    CAPTURE_PROMPTS: bool = os.getenv("REVENIUM_CAPTURE_PROMPTS", "false").lower() in ("true", "1", "yes", "on")
    MAX_PROMPT_LENGTH: int = _parse_max_prompt_length()  # Maximum characters per prompt field


class SecurityConfig:
    """Security-related configuration."""
    
    # Sensitive fields that should never be logged
    SENSITIVE_FIELDS: Set[str] = {
        'api_key', 'subscriber_credential', 'subscriber_email', 'messages',
        'input', 'content', 'prompt', 'text', 'data', 'authorization',
        'x-api-key', 'bearer', 'token', 'password', 'secret', 'key',
        'credential', 'auth', 'private',
        # Prompt capture fields
        'system_prompt', 'input_messages', 'output_response'
    }
    
    # Additional patterns to check for sensitive data
    SENSITIVE_PATTERNS: Set[str] = {
        'sk-', 'pk-', 'Bearer ', 'Basic ', 'Token '
    }


def get_config_value(key: str, default: any = None) -> any:
    """
    Get configuration value from environment or use default.
    
    Args:
        key: Configuration key (environment variable name)
        default: Default value if environment variable not set
        
    Returns:
        Configuration value
    """
    return os.getenv(key, default)


def is_debug_enabled() -> bool:
    """Check if debug logging is enabled."""
    log_level = get_config_value(Config.ENV_LOG_LEVEL, "INFO").upper()
    return log_level == "DEBUG"


def get_timeout_config() -> dict:
    """Get all timeout-related configuration."""
    return {
        'thread_join': Config.THREAD_JOIN_TIMEOUT,
        'api_request': Config.API_REQUEST_TIMEOUT,
        'background_thread': Config.BACKGROUND_THREAD_TIMEOUT,
        'stream': Config.STREAM_TIMEOUT,
    }

