"""Population configuration for cache population jobs.

Issue #110: Unified configuration via pydantic-settings.
Issue #128: Per-feature computation toggles.

All values load from environment variables (OPENDEVIATIONBAR_ prefix) with automatic
overlay: CLI > env > TOML > defaults via pydantic-settings.
"""

from __future__ import annotations

from typing import Literal

from pydantic import field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict

# Quick win: use symbol_registry for default threshold (will read from [meta] in future)
from opendeviationbar.symbol_registry import get_default_threshold


class PopulationConfig(BaseSettings):
    """Configuration for cache population jobs.

    Environment Variables
    ---------------------
    OPENDEVIATIONBAR_CRYPTO_MIN_THRESHOLD : int
        Default threshold in dbps (default: 250 = 0.25%)
    OPENDEVIATIONBAR_OUROBOROS_MODE : str
        Reset boundary: "day" or "aion" (per-symbol registry takes precedence)
    OPENDEVIATIONBAR_OUROBOROS_GUARD : str
        Guard behavior: "strict", "warn", "off" (default: "warn")
    OPENDEVIATIONBAR_INTER_BAR_LOOKBACK_COUNT : int
        Inter-bar lookback trade count (default: 200)
    OPENDEVIATIONBAR_INCLUDE_INTRA_BAR_FEATURES : bool
        Include intra-bar microstructure features (default: True)
    OPENDEVIATIONBAR_SYMBOL_GATE : str
        Symbol registry gate: "strict", "warn", "off" (default: "strict")
    OPENDEVIATIONBAR_CONTINUITY_TOLERANCE : float
        Continuity tolerance (default: 0.001)
    OPENDEVIATIONBAR_COMPUTE_TIER2 : bool
        Compute Tier 2 inter-bar features (default: False)
    OPENDEVIATIONBAR_COMPUTE_TIER3 : bool
        Compute Tier 3 inter-bar features (default: False)
    OPENDEVIATIONBAR_COMPUTE_HURST : bool
        Compute Hurst DFA (default: False)
    OPENDEVIATIONBAR_COMPUTE_PERMUTATION_ENTROPY : bool
        Compute permutation entropy (default: False)
    """

    model_config = SettingsConfigDict(
        env_prefix="OPENDEVIATIONBAR_",
        case_sensitive=False,
    )

    # Core — field names match env var suffixes (after OPENDEVIATIONBAR_ prefix)
    crypto_min_threshold: int = get_default_threshold()
    ouroboros_mode: Literal["day", "aion"] = "aion"
    ouroboros_guard: Literal["strict", "warn", "off"] = "warn"
    inter_bar_lookback_count: int = 200
    include_intra_bar_features: bool = True
    symbol_gate: Literal["strict", "warn", "off"] = "strict"
    continuity_tolerance: float = 0.001

    # Issue #128: Per-feature computation toggles
    compute_tier2: bool = False
    compute_tier3: bool = False
    compute_hurst: bool = False
    compute_permutation_entropy: bool = False

    @field_validator("ouroboros_mode")
    @classmethod
    def _validate_ouroboros(cls, v: str) -> str:
        from opendeviationbar.ouroboros import validate_ouroboros_mode

        validate_ouroboros_mode(v)
        return v

    # Backwards compatibility: existing code uses .default_threshold
    @property
    def default_threshold(self) -> int:
        """Alias for crypto_min_threshold (backwards compatibility)."""
        return self.crypto_min_threshold
