"""Memory configuration for NCP agents."""

from dataclasses import dataclass, field
from enum import Enum
from typing import Any, Dict


class STMStrategy(Enum):
    """Short-term memory strategies for managing conversation context."""

    LAST_N_MESSAGES = "last_n_messages"
    # Future strategies can be added here:
    # TOKEN_WINDOW = "token_window"
    # ADAPTIVE_SUMMARY = "adaptive_summary"
    # HYBRID = "hybrid"


@dataclass
class MemoryConfig:
    """Configuration for agent memory management.

    Controls how agents manage conversation history within the LLM context window.
    Short-term memory (STM) is enabled by default to prevent unbounded context growth.

    Attributes:
        stm_enabled: Whether short-term memory is enabled. Default: True
            - True: Apply STM strategy to manage conversation history
            - False: Stateless mode - no conversation history (only system + current message)
        stm_strategy: Strategy to use for managing context window. Default: LAST_N_MESSAGES
        stm_config: Strategy-specific configuration. Default:
            - max_messages: Number of conversation turns to keep (default: 30)
              Note: A "turn" includes user message + tool calls + tool results + response
            - include_tools: Include tool calls and tool results in turns (default: True)

    Note:
        The first system message is always preserved regardless of configuration.
        This behavior is not user-configurable to ensure agent instructions remain intact.

    Example:
        >>> # Use default settings (STM enabled, last 30 turns with full tool context)
        >>> config = MemoryConfig()

        >>> # Keep last 50 turns
        >>> config = MemoryConfig(stm_config={"max_messages": 50})

        >>> # Keep last 10 turns without tools (save tokens)
        >>> config = MemoryConfig(stm_config={
        ...     "max_messages": 10,
        ...     "include_tools": False
        ... })

        >>> # Stateless mode (no conversation history, each request independent)
        >>> config = MemoryConfig(stm_enabled=False)
    """

    stm_enabled: bool = True
    stm_strategy: STMStrategy = STMStrategy.LAST_N_MESSAGES
    stm_config: Dict[str, Any] = field(
        default_factory=lambda: {
            "max_messages": 20,
            "include_tools": True,
        }
    )

    def __post_init__(self):
        """Validate configuration after initialization."""
        if self.stm_enabled:
            if self.stm_strategy == STMStrategy.LAST_N_MESSAGES:
                # Validate max_messages
                max_messages = self.stm_config.get("max_messages", 30)
                if not isinstance(max_messages, int) or max_messages < 1:
                    raise ValueError(
                        f"max_messages must be a positive integer, got: {max_messages}"
                    )

                # Validate include_tools (optional, default True)
                include_tools = self.stm_config.get("include_tools", True)
                if not isinstance(include_tools, bool):
                    raise ValueError(
                        f"include_tools must be a boolean, got: {include_tools}"
                    )
