from typing import Any, Dict, List, Mapping, Optional

_TagSets = List[Mapping[str, Any]]
_Hedge = Mapping[str, Any]

class _ServerMode:
    def __init__(
        self, mode: int, tag_sets: Optional[_TagSets] = ..., max_staleness: int = ..., hedge: Optional[_Hedge] = ...
    ) -> None: ...
    @property
    def name(self) -> str: ...
    @property
    def mongos_mode(self) -> str: ...
    @property
    def document(self) -> Dict[str, Any]: ...
    @property
    def mode(self) -> int: ...
    @property
    def tag_sets(self) -> _TagSets: ...
    @property
    def max_staleness(self) -> int: ...
    @property
    def hedge(self) -> Optional[_Hedge]: ...
    @property
    def min_wire_version(self) -> int: ...
    def __eq__(self, other: Any) -> bool: ...
    def __ne__(self, other: Any) -> bool: ...

class Primary(_ServerMode):
    def __init__(self) -> None: ...
    def __call__(self, selection: Any): ...
    def __eq__(self, other: Any) -> bool: ...

class PrimaryPreferred(_ServerMode):
    def __init__(self, tag_sets: Optional[_TagSets] = ..., max_staleness: int = ..., hedge: Optional[_Hedge] = ...) -> None: ...
    def __call__(self, selection: Any): ...

class Secondary(_ServerMode):
    def __init__(self, tag_sets: Optional[_TagSets] = ..., max_staleness: int = ..., hedge: Optional[_Hedge] = ...) -> None: ...
    def __call__(self, selection: Any): ...

class SecondaryPreferred(_ServerMode):
    def __init__(self, tag_sets: Optional[_TagSets] = ..., max_staleness: int = ..., hedge: Optional[_Hedge] = ...) -> None: ...
    def __call__(self, selection: Any): ...

class Nearest(_ServerMode):
    def __init__(self, tag_sets: Optional[_TagSets] = ..., max_staleness: int = ..., hedge: Optional[_Hedge] = ...) -> None: ...
    def __call__(self, selection: Any): ...

def make_read_preference(mode: int, tag_sets: Optional[_TagSets], max_staleness: int = ...) -> _ServerMode: ...

class ReadPreference:
    PRIMARY: Primary = ...
    PRIMARY_PREFERRED: PrimaryPreferred = ...
    SECONDARY: Secondary = ...
    SECONDARY_PREFERRED: SecondaryPreferred = ...
    NEAREST: Nearest = ...

def read_pref_mode_from_name(name: str) -> int: ...

class MovingAverage:
    average: Optional[float] = ...
    def __init__(self) -> None: ...
    def add_sample(self, sample: float) -> None: ...
    def get(self) -> Optional[float]: ...
    def reset(self) -> None: ...
