from __future__ import annotations

from collections.abc import Mapping
from typing import Any, TypeVar, BinaryIO, TextIO, TYPE_CHECKING, Generator

from attrs import define as _attrs_define
from attrs import field as _attrs_field

from ..types import UNSET, Unset

from ..models.search_mode import SearchMode
from ..types import UNSET, Unset






T = TypeVar("T", bound="RetrieverConfig")



@_attrs_define
class RetrieverConfig:
    """ 
        Attributes:
            min_retrieval_sim_score (float | Unset): Minimum similarity score for retrieval of a chunk. Default: 0.1.
            max_distinct_documents (int | Unset): Maximum number of distinct documents to search for. Default: 200.
            max_total_chunks_to_retrieve (int | Unset): Maximum total number of chunks to retrieve for all documents
                retrieved. Default: 400.
            group_size (int | Unset): Maximum number of chunks per document for retrieval. Default: 10000.
            search_mode (SearchMode | Unset): Search mode for retrieval.
            hybrid_prefetch_limit (int | Unset): Maximum number of candidates each prefetch (dense and sparse) returns in
                hybrid mode before RRF fusion. Caps the sparse BM25 prefetch to avoid returning tens of thousands of chunks for
                common tokens. Default: 500.
            hybrid_dense_weight (float | Unset): Weight for dense vectors in hybrid mode Default: 0.7.
            hybrid_sparse_weight (float | Unset): Weight for sparse vectors in hybrid mode Default: 0.3.
     """

    min_retrieval_sim_score: float | Unset = 0.1
    max_distinct_documents: int | Unset = 200
    max_total_chunks_to_retrieve: int | Unset = 400
    group_size: int | Unset = 10000
    search_mode: SearchMode | Unset = UNSET
    hybrid_prefetch_limit: int | Unset = 500
    hybrid_dense_weight: float | Unset = 0.7
    hybrid_sparse_weight: float | Unset = 0.3
    additional_properties: dict[str, Any] = _attrs_field(init=False, factory=dict)





    def to_dict(self) -> dict[str, Any]:
        min_retrieval_sim_score = self.min_retrieval_sim_score

        max_distinct_documents = self.max_distinct_documents

        max_total_chunks_to_retrieve = self.max_total_chunks_to_retrieve

        group_size = self.group_size

        search_mode: str | Unset = UNSET
        if not isinstance(self.search_mode, Unset):
            search_mode = self.search_mode.value


        hybrid_prefetch_limit = self.hybrid_prefetch_limit

        hybrid_dense_weight = self.hybrid_dense_weight

        hybrid_sparse_weight = self.hybrid_sparse_weight


        field_dict: dict[str, Any] = {}
        field_dict.update(self.additional_properties)
        field_dict.update({
        })
        if min_retrieval_sim_score is not UNSET:
            field_dict["MIN_RETRIEVAL_SIM_SCORE"] = min_retrieval_sim_score
        if max_distinct_documents is not UNSET:
            field_dict["MAX_DISTINCT_DOCUMENTS"] = max_distinct_documents
        if max_total_chunks_to_retrieve is not UNSET:
            field_dict["MAX_TOTAL_CHUNKS_TO_RETRIEVE"] = max_total_chunks_to_retrieve
        if group_size is not UNSET:
            field_dict["GROUP_SIZE"] = group_size
        if search_mode is not UNSET:
            field_dict["SEARCH_MODE"] = search_mode
        if hybrid_prefetch_limit is not UNSET:
            field_dict["HYBRID_PREFETCH_LIMIT"] = hybrid_prefetch_limit
        if hybrid_dense_weight is not UNSET:
            field_dict["HYBRID_DENSE_WEIGHT"] = hybrid_dense_weight
        if hybrid_sparse_weight is not UNSET:
            field_dict["HYBRID_SPARSE_WEIGHT"] = hybrid_sparse_weight

        return field_dict



    @classmethod
    def from_dict(cls: type[T], src_dict: Mapping[str, Any]) -> T:
        d = dict(src_dict)
        min_retrieval_sim_score = d.pop("MIN_RETRIEVAL_SIM_SCORE", UNSET)

        max_distinct_documents = d.pop("MAX_DISTINCT_DOCUMENTS", UNSET)

        max_total_chunks_to_retrieve = d.pop("MAX_TOTAL_CHUNKS_TO_RETRIEVE", UNSET)

        group_size = d.pop("GROUP_SIZE", UNSET)

        _search_mode = d.pop("SEARCH_MODE", UNSET)
        search_mode: SearchMode | Unset
        if isinstance(_search_mode,  Unset):
            search_mode = UNSET
        else:
            search_mode = SearchMode(_search_mode)




        hybrid_prefetch_limit = d.pop("HYBRID_PREFETCH_LIMIT", UNSET)

        hybrid_dense_weight = d.pop("HYBRID_DENSE_WEIGHT", UNSET)

        hybrid_sparse_weight = d.pop("HYBRID_SPARSE_WEIGHT", UNSET)

        retriever_config = cls(
            min_retrieval_sim_score=min_retrieval_sim_score,
            max_distinct_documents=max_distinct_documents,
            max_total_chunks_to_retrieve=max_total_chunks_to_retrieve,
            group_size=group_size,
            search_mode=search_mode,
            hybrid_prefetch_limit=hybrid_prefetch_limit,
            hybrid_dense_weight=hybrid_dense_weight,
            hybrid_sparse_weight=hybrid_sparse_weight,
        )


        retriever_config.additional_properties = d
        return retriever_config

    @property
    def additional_keys(self) -> list[str]:
        return list(self.additional_properties.keys())

    def __getitem__(self, key: str) -> Any:
        return self.additional_properties[key]

    def __setitem__(self, key: str, value: Any) -> None:
        self.additional_properties[key] = value

    def __delitem__(self, key: str) -> None:
        del self.additional_properties[key]

    def __contains__(self, key: str) -> bool:
        return key in self.additional_properties
