from typing import Any, Iterable, List, Mapping, Optional, Union

from pymongo.client_session import ClientSession
from pymongo.collation import Collation
from pymongo.collection import Collection
from pymongo.database import Database
from pymongo.mongo_client import MongoClient

_Collation = Union[Mapping[str, Any], Collation]
_DocumentOut = Any

class ChangeStream:
    def __init__(
        self,
        target: Union[MongoClient, Database, Collection],
        pipeline: Optional[List[Mapping[str, Any]]],
        full_document: Optional[str],
        resume_after: Optional[Mapping[str, Any]],
        max_await_time_ms: Optional[int],
        batch_size: Optional[int],
        collation: Optional[_Collation],
        start_at_operation_time: Optional[Mapping[str, Any]],
        session: Optional[ClientSession],
        start_after: Optional[Mapping[str, Any]],
    ) -> None: ...
    def close(self) -> None: ...
    def __iter__(self) -> Iterable[Mapping[str, Any]]: ...
    @property
    def resume_token(self) -> Optional[Mapping[str, Any]]: ...
    def next(self) -> _DocumentOut: ...
    def __next__(self) -> _DocumentOut: ...
    @property
    def alive(self) -> bool: ...
    def try_next(self) -> Optional[_DocumentOut]: ...
    def __enter__(self) -> ChangeStream: ...
    def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None: ...

class CollectionChangeStream(ChangeStream): ...
class DatabaseChangeStream(ChangeStream): ...
class ClusterChangeStream(DatabaseChangeStream): ...
