from __future__ import annotations

from typing import Any, Optional

from pydantic import BaseModel, ConfigDict, Field, model_validator

from goodmem.models.no_chunking_configuration import NoChunkingConfiguration
from goodmem.models.recursive_chunking_configuration import RecursiveChunkingConfiguration
from goodmem.models.sentence_chunking_configuration import SentenceChunkingConfiguration


class ChunkingConfiguration(BaseModel):
    """Configuration for text chunking strategy used when processing content. Exactly one of none, recursive, or sentence must be provided."""

    model_config = ConfigDict(populate_by_name=True, protected_namespaces=())

    none: Optional[NoChunkingConfiguration] = Field(default=None, description='No chunking strategy - preserve original content as single unit')
    recursive: Optional[RecursiveChunkingConfiguration] = Field(default=None, description='Recursive hierarchical chunking strategy with configurable separators')
    sentence: Optional[SentenceChunkingConfiguration] = Field(default=None, description='Sentence-based chunking strategy with language detection')

    @model_validator(mode='after')
    def _check_exactly_one_variant(self) -> 'ChunkingConfiguration':
        _variant_fields = ['none', 'recursive', 'sentence']
        _set = [f for f in _variant_fields if getattr(self, f) is not None]
        if len(_set) != 1:
            raise ValueError(
                f"Exactly one of none, recursive, sentence must be set, "
                f"got {len(_set)}: {_set or 'none'}"
            )
        return self

