"""
Global configuration system for Egregore.

Provides centralized configuration with environment variable support.
Priority: Environment Variables > Code > Defaults
"""

import os
from typing import Optional


class TelemetryConfig:
    """
    Telemetry configuration with environment variable support.

    Priority: Environment Variables > Code > Defaults

    Environment Variables:
        EGREGORE_TELEMETRY_ENABLED: Enable/disable telemetry (bool)
        EGREGORE_TELEMETRY_OUTPUT_DIR: Output directory for local engine (str)
        EGREGORE_TELEMETRY_BUFFER_SIZE: Event buffer size (int)
        EGREGORE_TELEMETRY_FLUSH_INTERVAL: Auto-flush interval in seconds (float)
    """

    def __init__(self):
        # Read from environment first, fallback to defaults
        self._enabled = self._get_env_bool("EGREGORE_TELEMETRY_ENABLED", False)
        self._engine = None
        self._output_dir = os.getenv("EGREGORE_TELEMETRY_OUTPUT_DIR", "./telemetry")

        # Handle empty string env vars -> use defaults
        if self._output_dir == "":
            self._output_dir = "./telemetry"

        self._buffer_size = self._get_env_int("EGREGORE_TELEMETRY_BUFFER_SIZE", 1000)
        self._flush_interval = self._get_env_float(
            "EGREGORE_TELEMETRY_FLUSH_INTERVAL", 5.0
        )

        # Auto-initialize if enabled via env var
        if self._enabled and self._engine is None:
            from egregore.analytics.telemetry.local import LocalTelemetryEngine

            self._engine = LocalTelemetryEngine(output_dir=self._output_dir)

    @property
    def enabled(self) -> bool:
        """Get enabled status."""
        return self._enabled

    @enabled.setter
    def enabled(self, value: bool):
        """
        Set enabled status.

        Auto-initializes LocalTelemetryEngine when enabled if no engine set.
        Clears engine when disabled.
        """
        self._enabled = value
        if value and self._engine is None:
            from egregore.analytics.telemetry.local import LocalTelemetryEngine

            self._engine = LocalTelemetryEngine(output_dir=self._output_dir)
        elif not value:
            # Clear engine when disabling
            self._engine = None

    @property
    def engine(self):
        """Get telemetry engine."""
        return self._engine

    @engine.setter
    def engine(self, value):
        """
        Set custom telemetry engine.

        Auto-enables telemetry when engine is set.
        """
        self._engine = value
        self._enabled = True  # Auto-enable when engine is set

    @property
    def output_dir(self) -> str:
        """Get output directory."""
        return self._output_dir

    @output_dir.setter
    def output_dir(self, value: str):
        """
        Set output directory.

        Propagates to engine if engine has output_dir attribute.
        """
        self._output_dir = value
        if self._engine and hasattr(self._engine, "output_dir"):
            self._engine.output_dir = value

    @property
    def buffer_size(self) -> int:
        """Get buffer size."""
        return self._buffer_size

    @buffer_size.setter
    def buffer_size(self, value: int):
        """Set buffer size."""
        self._buffer_size = value

    @property
    def flush_interval(self) -> float:
        """Get flush interval."""
        return self._flush_interval

    @flush_interval.setter
    def flush_interval(self, value: float):
        """Set flush interval."""
        self._flush_interval = value

    # Helper methods for env var parsing

    @staticmethod
    def _get_env_bool(key: str, default: bool) -> bool:
        """
        Parse boolean from environment variable.

        Accepts: true, True, TRUE, 1, yes, YES, on, ON (case-insensitive)
        """
        val = os.getenv(key)
        if val is None or val == "":
            return default
        return val.lower() in ("true", "1", "yes", "on")

    @staticmethod
    def _get_env_int(key: str, default: int) -> int:
        """Parse integer from environment variable."""
        val = os.getenv(key)
        if not val:
            return default
        return int(val)  # Raises ValueError if invalid

    @staticmethod
    def _get_env_float(key: str, default: float) -> float:
        """Parse float from environment variable."""
        val = os.getenv(key)
        if not val:
            return default
        return float(val)  # Raises ValueError if invalid


class EgregoreConfig:
    """Global framework configuration."""

    def __init__(self):
        self.telemetry = TelemetryConfig()
        # Future: self.logging, self.performance, etc.


# Global singleton
_global_config: Optional[EgregoreConfig] = None


def get_config() -> EgregoreConfig:
    """Get global Egregore configuration."""
    global _global_config
    if _global_config is None:
        _global_config = EgregoreConfig()
    return _global_config
