#!/usr/bin/env python3
# src/chuk_mcp_math_server/math_config.py
"""
Math-specific configuration that extends the base ServerConfig.
"""

import logging
import os
from typing import Optional

from .config import ServerConfig

logger = logging.getLogger(__name__)


class MathServerConfig(ServerConfig):
    """Math-specific server configuration with math domain defaults."""

    @classmethod
    def from_env(cls) -> "MathServerConfig":
        """Load math configuration from environment variables with math-specific prefixes."""
        # First load generic config
        base_config = super().from_env()
        config_dict = base_config.model_dump()

        # Then check for math-specific environment variables (backward compatibility)
        math_env_mapping: dict[
            str, str | tuple[str, type | type[int] | type[float]]
        ] = {
            "MCP_MATH_TRANSPORT": "transport",
            "MCP_MATH_PORT": ("port", int),
            "MCP_MATH_HOST": "host",
            "MCP_MATH_CACHE_STRATEGY": "cache_strategy",
            "MCP_MATH_CACHE_SIZE": ("cache_size", int),
            "MCP_MATH_LOG_LEVEL": "log_level",
            "MCP_MATH_TIMEOUT": ("computation_timeout", float),
            "MCP_MATH_MAX_CONCURRENT": ("max_concurrent_calls", int),
        }

        # Handle boolean and list conversions separately
        bool_env_mapping = {
            "MCP_MATH_ENABLE_TOOLS": "enable_tools",
            "MCP_MATH_ENABLE_PROMPTS": "enable_prompts",
            "MCP_MATH_ENABLE_RESOURCES": "enable_resources",
        }

        list_env_mapping = {
            "MCP_MATH_FUNCTION_ALLOWLIST": "function_allowlist",
            "MCP_MATH_FUNCTION_DENYLIST": "function_denylist",
            "MCP_MATH_DOMAIN_ALLOWLIST": "domain_allowlist",
            "MCP_MATH_DOMAIN_DENYLIST": "domain_denylist",
            "MCP_MATH_CATEGORY_ALLOWLIST": "category_allowlist",
            "MCP_MATH_CATEGORY_DENYLIST": "category_denylist",
        }

        # Override with math-specific environment variables if they exist
        for env_key, config_field in math_env_mapping.items():
            if env_key in os.environ:
                if isinstance(config_field, tuple):
                    field_name, converter = config_field
                    try:
                        config_dict[field_name] = converter(os.environ[env_key])
                    except (ValueError, TypeError) as e:
                        logger.warning(f"Invalid value for {env_key}: {e}")
                else:
                    config_dict[config_field] = os.environ[env_key]

        # Handle boolean conversions
        for env_key, field_name in bool_env_mapping.items():
            if env_key in os.environ:
                config_dict[field_name] = os.environ[env_key].lower() == "true"

        # Handle list conversions
        for env_key, field_name in list_env_mapping.items():
            if env_key in os.environ:
                config_dict[field_name] = os.environ[env_key].split(",")

        return cls(**config_dict)


def load_math_configuration_from_sources(
    config_file: Optional[str] = None, cli_overrides: Optional[dict] = None
) -> MathServerConfig:
    """Load math configuration from multiple sources with proper precedence.

    Priority order:
    1. CLI arguments (highest priority)
    2. Math-specific environment variables (MCP_MATH_*)
    3. Generic environment variables (MCP_SERVER_*)
    4. Configuration file
    5. Math defaults (lowest priority)
    """

    # Start with defaults
    base_dict = {}

    # Load from file if provided
    if config_file:
        base_config = ServerConfig.from_file(config_file)
        base_dict = base_config.model_dump()
        logger.debug(f"Loaded configuration from file: {config_file}")

    # Override with environment variables (both generic and math-specific)
    # Only apply values that are explicitly set in environment
    try:
        env_overrides_found = False
        # Create env_config once to get proper type conversions
        env_config = MathServerConfig.from_env()
        env_dict = env_config.model_dump()

        for key in MathServerConfig.model_fields.keys():
            env_value = os.getenv(f"MCP_MATH_{key.upper()}") or os.getenv(
                f"MCP_SERVER_{key.upper()}"
            )
            # Only override if this specific key has an env var set
            if env_value is not None:
                base_dict[key] = env_dict[key]
                env_overrides_found = True

        if env_overrides_found:
            logger.debug("Applied environment variable overrides")
    except Exception as e:
        logger.warning(f"Error loading environment config: {e}")

    # Apply CLI overrides (highest priority)
    if cli_overrides:
        base_dict.update(cli_overrides)
        logger.debug("Applied CLI overrides")

    return MathServerConfig(**base_dict)
