"""
Type annotations for botocore.eventstream module.

Copyright 2024 Vlad Emelianov
"""

from typing import Any, Generic, Iterator, TypeVar

from botocore.exceptions import EventStreamError as EventStreamError
from botocore.model import StructureShape
from botocore.parsers import BaseEventStreamParser

_T = TypeVar("_T")

class ParserError(Exception): ...

class DuplicateHeader(ParserError):
    def __init__(self, header: str) -> None: ...

class InvalidHeadersLength(ParserError):
    def __init__(self, length: int) -> None: ...

class InvalidPayloadLength(ParserError):
    def __init__(self, length: int) -> None: ...

class ChecksumMismatch(ParserError):
    def __init__(self, expected: int, calculated: int) -> None: ...

class NoInitialResponseError(ParserError):
    def __init__(self) -> None: ...

class DecodeUtils:
    UINT8_BYTE_FORMAT: str = ...
    UINT16_BYTE_FORMAT: str = ...
    UINT32_BYTE_FORMAT: str = ...
    INT8_BYTE_FORMAT: str = ...
    INT16_BYTE_FORMAT: str = ...
    INT32_BYTE_FORMAT: str = ...
    INT64_BYTE_FORMAT: str = ...
    PRELUDE_BYTE_FORMAT: str = ...
    UINT_BYTE_FORMAT: dict[int, str] = ...
    @staticmethod
    def unpack_true(data: bytes) -> tuple[bool, int]: ...
    @staticmethod
    def unpack_false(data: bytes) -> tuple[bool, int]: ...
    @staticmethod
    def unpack_uint8(data: bytes) -> tuple[int, int]: ...
    @staticmethod
    def unpack_uint32(data: bytes) -> tuple[int, int]: ...
    @staticmethod
    def unpack_int8(data: bytes) -> tuple[int, int]: ...
    @staticmethod
    def unpack_int16(data: bytes) -> tuple[int, int]: ...
    @staticmethod
    def unpack_int32(data: bytes) -> tuple[int, int]: ...
    @staticmethod
    def unpack_int64(data: bytes) -> tuple[int, int]: ...
    @staticmethod
    def unpack_byte_array(data: bytes, length_byte_size: int = ...) -> tuple[bytes, int]: ...
    @staticmethod
    def unpack_utf8_string(data: bytes, length_byte_size: int = ...) -> tuple[str, int]: ...
    @staticmethod
    def unpack_uuid(data: bytes) -> tuple[bytes, int]: ...
    @staticmethod
    def unpack_prelude(data: bytes) -> tuple[tuple[int, int, int], int]: ...

class MessagePrelude:
    def __init__(self, total_length: int, headers_length: int, crc: int) -> None:
        self.total_length: int = ...
        self.headers_length: int = ...
        self.crc: int = ...

    @property
    def payload_length(self) -> int: ...
    @property
    def payload_end(self) -> int: ...
    @property
    def headers_end(self) -> int: ...

class EventStreamMessage:
    def __init__(self, prelude: int, headers: int, payload: bytes, crc: int) -> None:
        self.prelude: int = ...
        self.headers: int = ...
        self.payload: bytes = ...
        self.crc: int = ...

    def to_response_dict(self, status_code: int = ...) -> dict[str, Any]: ...

class EventStreamHeaderParser:
    def __init__(self) -> None: ...
    def parse(self, data: bytes) -> dict[str, Any]: ...

class EventStreamBuffer:
    def __init__(self) -> None: ...
    def add_data(self, data: bytes) -> None: ...
    def next(self) -> EventStreamMessage: ...
    def __next__(self) -> EventStreamMessage: ...
    def __iter__(self: _T) -> _T: ...

class EventStream(Generic[_T]):
    def __init__(
        self,
        raw_stream: Any,
        output_shape: StructureShape,
        parser: BaseEventStreamParser,
        operation_name: str,
    ) -> None: ...
    def __iter__(self) -> Iterator[_T]: ...
    def get_initial_response(self) -> _T: ...
    def close(self) -> None: ...
