import io
from collections.abc import Callable, Generator, Iterator
from typing_extensions import TypeAlias

from gunicorn.http.message import Request
from gunicorn.http.unreader import Unreader

class ChunkedReader:
    req: Request
    parser: Generator[bytes, None, None] | None
    buf: io.BytesIO

    def __init__(self, req: Request, unreader: Unreader) -> None: ...
    def read(self, size: int) -> bytes: ...
    def parse_trailers(self, unreader: Unreader, data: bytes) -> None: ...
    def parse_chunked(self, unreader: Unreader) -> Generator[bytes]: ...
    def parse_chunk_size(self, unreader: Unreader, data: bytes | None = None) -> tuple[int, bytes | None]: ...
    def get_data(self, unreader: Unreader, buf: io.BytesIO) -> None: ...

class LengthReader:
    unreader: Unreader
    length: int

    def __init__(self, unreader: Unreader, length: int) -> None: ...
    def read(self, size: int) -> bytes: ...

class EOFReader:
    unreader: Unreader
    buf: io.BytesIO
    finished: bool

    def __init__(self, unreader: Unreader) -> None: ...
    def read(self, size: int) -> bytes: ...

_ReaderType: TypeAlias = ChunkedReader | LengthReader | EOFReader

class Body:
    reader: _ReaderType
    buf: io.BytesIO

    def __init__(self, reader: _ReaderType) -> None: ...
    def __iter__(self) -> Iterator[bytes]: ...
    def __next__(self) -> bytes: ...
    next: Callable[[Body], bytes]
    def getsize(self, size: int | None) -> int: ...
    def read(self, size: int | None = None) -> bytes: ...
    def readline(self, size: int | None = None) -> bytes: ...
    def readlines(self, size: int | None = None) -> list[bytes]: ...
