"""Base class for extensible settings with typed core and flexible extensions.

Design Goals:
    - Type safety for known/stable fields via dataclass attributes
    - Flexibility for experimental features via extensions dict
    - Schema versioning for forward-compatible migrations
    - Plugin extensibility via RuleTypeRegistry (see domain/rules/)
"""

from __future__ import annotations

from dataclasses import dataclass, field
from typing import TypeVar

T = TypeVar("T")


@dataclass
class ExtensibleSettings:
    """Base for all settings with typed core + extensible metadata.

    Subclasses add typed fields for stable features. Experimental features
    live in `extensions` until promoted to typed fields.

    Example lifecycle:
        Sprint N:   extensions["retention_days"] = 90        # Experimental
        Sprint N+1: retention_days: int | None = None       # Promoted
                    (migration moves data from extensions -> typed field)

    Attributes:
        extensions: Storage for experimental/incubating features.
        schema_version: Version number for migration logic.
    """

    extensions: dict[str, object] = field(default_factory=dict)
    schema_version: int = 1

    def set_extension(self, key: str, value: object) -> None:
        """Store an experimental setting.

        Args:
            key: Extension key to set.
            value: Value to store.
        """
        self.extensions[key] = value

    def has_extension(self, key: str) -> bool:
        """Check if an extension key exists.

        Args:
            key: Extension key to check.

        Returns:
            True if the key exists in extensions.
        """
        return key in self.extensions

    def remove_extension(self, key: str) -> None:
        """Remove an extension key if it exists.

        Args:
            key: Extension key to remove.
        """
        self.extensions.pop(key, None)
