"""
Feature flags for the CAAE / kvict B2B service.

Best practices:
- Central definition: all CAAE/B2B feature flags live here.
- Environment-driven: read from CAAE_FEATURE_* or CAAE_*_ENABLED env vars.
- Default off for new features: opt-in to avoid surprising behavior.
- Typed and documented: each flag has type, default, and doc.
- Testable: use set_feature_flags() in tests to override.
- No business logic: flags are booleans; logic stays in plugin/dashboard.
"""

from __future__ import annotations

import os
from dataclasses import MISSING, dataclass, field
from typing import Any, Dict


def _parse_bool(value: str | None, default: bool) -> bool:
    """Parse env string to bool. True for 'true', '1', 'yes'; False otherwise."""
    if value is None or value == "":
        return default
    return value.strip().lower() in ("true", "1", "yes")


@dataclass(frozen=True)
class CAAEFeatureFlags:
    """
    CAAE (B2B) feature flags.

    All flags are read from environment at construction time. Use get_feature_flags()
    to obtain the singleton instance.
    """

    # -------------------------------------------------------------------------
    # Existing behavior (default on for backward compatibility)
    # -------------------------------------------------------------------------

    circuit_breaker_enabled: bool = field(
        default=True,
        metadata={
            "env": "CAAE_FEATURE_CIRCUIT_BREAKER",
            "doc": "Switch to LRU when PCIe saturated; disable to always use cost-aware.",
        },
    )

    prometheus_enabled: bool = field(
        default=True,
        metadata={
            "env": "CAAE_ENABLE_PROMETHEUS",
            "doc": "Expose Prometheus metrics endpoint.",
        },
    )

    # -------------------------------------------------------------------------
    # New / optional features (default off)
    # -------------------------------------------------------------------------

    llm_observability_enabled: bool = field(
        default=False,
        metadata={
            "env": "CAAE_LLM_OBSERVABILITY_ENABLED",
            "doc": "LLM to classify errors, summarize traces, or suggest CAAE tuning.",
        },
    )

    advisor_recommendations_enabled: bool = field(
        default=False,
        metadata={
            "env": "CAAE_ADVISOR_RECOMMENDATIONS_ENABLED",
            "doc": "Expose rule-based recommendations (block pool, shared KV) from advisor.",
        },
    )

    @classmethod
    def from_env(cls) -> CAAEFeatureFlags:
        """Build flags from current environment. Used by get_feature_flags()."""
        values: Dict[str, bool] = {}
        for name, f in cls.__dataclass_fields__.items():
            if "env" not in f.metadata:
                continue
            default = f.default if f.default is not MISSING else False
            env_key = f.metadata["env"]
            values[name] = _parse_bool(os.getenv(env_key), default)
        return cls(**values)

    def to_dict(self) -> Dict[str, Any]:
        """For logging and /health or config endpoints."""
        return {
            "circuit_breaker_enabled": self.circuit_breaker_enabled,
            "prometheus_enabled": self.prometheus_enabled,
            "llm_observability_enabled": self.llm_observability_enabled,
            "advisor_recommendations_enabled": self.advisor_recommendations_enabled,
        }


# Singleton and test override
_flags: CAAEFeatureFlags | None = None


def get_feature_flags() -> CAAEFeatureFlags:
    """Return the global CAAE feature flags (from env, cached)."""
    global _flags
    if _flags is None:
        _flags = CAAEFeatureFlags.from_env()
    return _flags


def set_feature_flags(flags: CAAEFeatureFlags | None) -> None:
    """Override global flags (e.g. in tests). Pass None to reset to env-based."""
    global _flags
    _flags = flags
