from __future__ import annotations

from collections.abc import (
    Callable,
    Iterable,
    Mapping,
    Sequence,
)
from typing import (
    Any,
    Protocol,
    TypeAlias
)

# InputRow is the typehint for our function arguments
# whereas Row is the typehint for return values.
InputRow: TypeAlias = Mapping[str, Any] | Sequence[Any]
# The exact type of a Row depends on the row_factory and transform functions used
# and so, it is given the generic type Any
Row: TypeAlias = Any
Chunk: TypeAlias = list[Row]
Parameters: TypeAlias = Mapping[str, Any] | Sequence[Any]
Transform: TypeAlias = Callable[[Chunk], Chunk]


class Cursor(Protocol):
    rowcount: int
    def execute(self, *args: Any, **kwargs: Any) -> Cursor: ...
    def executemany(self, *args: Any, **kwargs: Any) -> None: ...
    def fetchone(self) -> Row: ...
    def fetchmany(self, *args: Any, **kwarg) -> Iterable[Row]: ...
    def fetchall(self) -> Iterable[Row]: ...
    def close(self) -> None: ...
    def __enter__(self) -> Cursor: ...
    def __exit__(self, *args: Any, **kwargs: Any) -> None: ...


class Connection(Protocol):
    def close(self) -> None: ...
    def commit(self) -> None: ...
    def rollback(self) -> None: ...
    def cursor(self, *args: Any, **kwargs: Any) -> Cursor: ...
    def __enter__(self) -> Connection: ...
    def __exit__(self, *args: Any, **kwargs: Any) -> None: ...
