# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: streams.proto
# plugin: python-betterproto
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import (
    TYPE_CHECKING,
    AsyncIterable,
    AsyncIterator,
    Dict,
    Iterable,
    List,
    Optional,
    Union,
)

import betterproto
import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf
import grpclib
from betterproto.grpc.grpclib_server import ServiceBase

from ....google import rpc as ___google_rpc__
from ... import client as __client__

if TYPE_CHECKING:
    import grpclib.server
    from betterproto.grpc.grpclib_client import MetadataLike
    from grpclib.metadata import Deadline


class ReadReqOptionsReadDirection(betterproto.Enum):
    Forwards = 0
    Backwards = 1


@dataclass(eq=False, repr=False)
class ReadReq(betterproto.Message):
    options: "ReadReqOptions" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class ReadReqOptions(betterproto.Message):
    stream: "ReadReqOptionsStreamOptions" = betterproto.message_field(
        1, group="stream_option"
    )
    all: "ReadReqOptionsAllOptions" = betterproto.message_field(
        2, group="stream_option"
    )
    read_direction: "ReadReqOptionsReadDirection" = betterproto.enum_field(3)
    resolve_links: bool = betterproto.bool_field(4)
    count: int = betterproto.uint64_field(5, group="count_option")
    subscription: "ReadReqOptionsSubscriptionOptions" = betterproto.message_field(
        6, group="count_option"
    )
    filter: "ReadReqOptionsFilterOptions" = betterproto.message_field(
        7, group="filter_option"
    )
    no_filter: "__client__.Empty" = betterproto.message_field(8, group="filter_option")
    uuid_option: "ReadReqOptionsUuidOption" = betterproto.message_field(9)
    control_option: "ReadReqOptionsControlOption" = betterproto.message_field(10)


@dataclass(eq=False, repr=False)
class ReadReqOptionsStreamOptions(betterproto.Message):
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(1)
    revision: int = betterproto.uint64_field(2, group="revision_option")
    start: "__client__.Empty" = betterproto.message_field(3, group="revision_option")
    end: "__client__.Empty" = betterproto.message_field(4, group="revision_option")


@dataclass(eq=False, repr=False)
class ReadReqOptionsAllOptions(betterproto.Message):
    position: "ReadReqOptionsPosition" = betterproto.message_field(
        1, group="all_option"
    )
    start: "__client__.Empty" = betterproto.message_field(2, group="all_option")
    end: "__client__.Empty" = betterproto.message_field(3, group="all_option")


@dataclass(eq=False, repr=False)
class ReadReqOptionsSubscriptionOptions(betterproto.Message):
    pass


@dataclass(eq=False, repr=False)
class ReadReqOptionsPosition(betterproto.Message):
    commit_position: int = betterproto.uint64_field(1)
    prepare_position: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class ReadReqOptionsFilterOptions(betterproto.Message):
    stream_identifier: "ReadReqOptionsFilterOptionsExpression" = (
        betterproto.message_field(1, group="filter")
    )
    event_type: "ReadReqOptionsFilterOptionsExpression" = betterproto.message_field(
        2, group="filter"
    )
    max: int = betterproto.uint32_field(3, group="window")
    count: "__client__.Empty" = betterproto.message_field(4, group="window")
    checkpoint_interval_multiplier: int = betterproto.uint32_field(5)


@dataclass(eq=False, repr=False)
class ReadReqOptionsFilterOptionsExpression(betterproto.Message):
    regex: str = betterproto.string_field(1)
    prefix: List[str] = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class ReadReqOptionsUuidOption(betterproto.Message):
    structured: "__client__.Empty" = betterproto.message_field(1, group="content")
    string: "__client__.Empty" = betterproto.message_field(2, group="content")


@dataclass(eq=False, repr=False)
class ReadReqOptionsControlOption(betterproto.Message):
    compatibility: int = betterproto.uint32_field(1)


@dataclass(eq=False, repr=False)
class ReadResp(betterproto.Message):
    event: "ReadRespReadEvent" = betterproto.message_field(1, group="content")
    confirmation: "ReadRespSubscriptionConfirmation" = betterproto.message_field(
        2, group="content"
    )
    checkpoint: "ReadRespCheckpoint" = betterproto.message_field(3, group="content")
    stream_not_found: "ReadRespStreamNotFound" = betterproto.message_field(
        4, group="content"
    )
    first_stream_position: int = betterproto.uint64_field(5, group="content")
    last_stream_position: int = betterproto.uint64_field(6, group="content")
    last_all_stream_position: "__client__.AllStreamPosition" = (
        betterproto.message_field(7, group="content")
    )


@dataclass(eq=False, repr=False)
class ReadRespReadEvent(betterproto.Message):
    event: "ReadRespReadEventRecordedEvent" = betterproto.message_field(1)
    link: "ReadRespReadEventRecordedEvent" = betterproto.message_field(2)
    commit_position: int = betterproto.uint64_field(3, group="position")
    no_position: "__client__.Empty" = betterproto.message_field(4, group="position")


@dataclass(eq=False, repr=False)
class ReadRespReadEventRecordedEvent(betterproto.Message):
    id: "__client__.Uuid" = betterproto.message_field(1)
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(2)
    stream_revision: int = betterproto.uint64_field(3)
    prepare_position: int = betterproto.uint64_field(4)
    commit_position: int = betterproto.uint64_field(5)
    metadata: Dict[str, str] = betterproto.map_field(
        6, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    custom_metadata: bytes = betterproto.bytes_field(7)
    data: bytes = betterproto.bytes_field(8)


@dataclass(eq=False, repr=False)
class ReadRespSubscriptionConfirmation(betterproto.Message):
    subscription_id: str = betterproto.string_field(1)


@dataclass(eq=False, repr=False)
class ReadRespCheckpoint(betterproto.Message):
    commit_position: int = betterproto.uint64_field(1)
    prepare_position: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class ReadRespStreamNotFound(betterproto.Message):
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class AppendReq(betterproto.Message):
    options: "AppendReqOptions" = betterproto.message_field(1, group="content")
    proposed_message: "AppendReqProposedMessage" = betterproto.message_field(
        2, group="content"
    )


@dataclass(eq=False, repr=False)
class AppendReqOptions(betterproto.Message):
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(1)
    revision: int = betterproto.uint64_field(2, group="expected_stream_revision")
    no_stream: "__client__.Empty" = betterproto.message_field(
        3, group="expected_stream_revision"
    )
    any: "__client__.Empty" = betterproto.message_field(
        4, group="expected_stream_revision"
    )
    stream_exists: "__client__.Empty" = betterproto.message_field(
        5, group="expected_stream_revision"
    )


@dataclass(eq=False, repr=False)
class AppendReqProposedMessage(betterproto.Message):
    id: "__client__.Uuid" = betterproto.message_field(1)
    metadata: Dict[str, str] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    custom_metadata: bytes = betterproto.bytes_field(3)
    data: bytes = betterproto.bytes_field(4)


@dataclass(eq=False, repr=False)
class AppendResp(betterproto.Message):
    success: "AppendRespSuccess" = betterproto.message_field(1, group="result")
    wrong_expected_version: "AppendRespWrongExpectedVersion" = (
        betterproto.message_field(2, group="result")
    )


@dataclass(eq=False, repr=False)
class AppendRespPosition(betterproto.Message):
    commit_position: int = betterproto.uint64_field(1)
    prepare_position: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class AppendRespSuccess(betterproto.Message):
    current_revision: int = betterproto.uint64_field(1, group="current_revision_option")
    no_stream: "__client__.Empty" = betterproto.message_field(
        2, group="current_revision_option"
    )
    position: "AppendRespPosition" = betterproto.message_field(
        3, group="position_option"
    )
    no_position: "__client__.Empty" = betterproto.message_field(
        4, group="position_option"
    )


@dataclass(eq=False, repr=False)
class AppendRespWrongExpectedVersion(betterproto.Message):
    current_revision_20_6_0: int = betterproto.uint64_field(
        1, group="current_revision_option_20_6_0"
    )
    no_stream_20_6_0: "__client__.Empty" = betterproto.message_field(
        2, group="current_revision_option_20_6_0"
    )
    expected_revision_20_6_0: int = betterproto.uint64_field(
        3, group="expected_revision_option_20_6_0"
    )
    any_20_6_0: "__client__.Empty" = betterproto.message_field(
        4, group="expected_revision_option_20_6_0"
    )
    stream_exists_20_6_0: "__client__.Empty" = betterproto.message_field(
        5, group="expected_revision_option_20_6_0"
    )
    current_revision: int = betterproto.uint64_field(6, group="current_revision_option")
    current_no_stream: "__client__.Empty" = betterproto.message_field(
        7, group="current_revision_option"
    )
    expected_revision: int = betterproto.uint64_field(
        8, group="expected_revision_option"
    )
    expected_any: "__client__.Empty" = betterproto.message_field(
        9, group="expected_revision_option"
    )
    expected_stream_exists: "__client__.Empty" = betterproto.message_field(
        10, group="expected_revision_option"
    )
    expected_no_stream: "__client__.Empty" = betterproto.message_field(
        11, group="expected_revision_option"
    )


@dataclass(eq=False, repr=False)
class BatchAppendReq(betterproto.Message):
    correlation_id: "__client__.Uuid" = betterproto.message_field(1)
    options: "BatchAppendReqOptions" = betterproto.message_field(2)
    proposed_messages: List[
        "BatchAppendReqProposedMessage"
    ] = betterproto.message_field(3)
    is_final: bool = betterproto.bool_field(4)


@dataclass(eq=False, repr=False)
class BatchAppendReqOptions(betterproto.Message):
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(1)
    stream_position: int = betterproto.uint64_field(2, group="expected_stream_position")
    no_stream: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        3, group="expected_stream_position"
    )
    any: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        4, group="expected_stream_position"
    )
    stream_exists: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        5, group="expected_stream_position"
    )
    deadline_21_10_0: datetime = betterproto.message_field(6, group="deadline_option")
    deadline: timedelta = betterproto.message_field(7, group="deadline_option")


@dataclass(eq=False, repr=False)
class BatchAppendReqProposedMessage(betterproto.Message):
    id: "__client__.Uuid" = betterproto.message_field(1)
    metadata: Dict[str, str] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    custom_metadata: bytes = betterproto.bytes_field(3)
    data: bytes = betterproto.bytes_field(4)


@dataclass(eq=False, repr=False)
class BatchAppendResp(betterproto.Message):
    correlation_id: "__client__.Uuid" = betterproto.message_field(1)
    error: "___google_rpc__.Status" = betterproto.message_field(2, group="result")
    success: "BatchAppendRespSuccess" = betterproto.message_field(3, group="result")
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(4)
    stream_position: int = betterproto.uint64_field(5, group="expected_stream_position")
    no_stream: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        6, group="expected_stream_position"
    )
    any: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        7, group="expected_stream_position"
    )
    stream_exists: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        8, group="expected_stream_position"
    )


@dataclass(eq=False, repr=False)
class BatchAppendRespSuccess(betterproto.Message):
    current_revision: int = betterproto.uint64_field(1, group="current_revision_option")
    no_stream: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        2, group="current_revision_option"
    )
    position: "__client__.AllStreamPosition" = betterproto.message_field(
        3, group="position_option"
    )
    no_position: "betterproto_lib_google_protobuf.Empty" = betterproto.message_field(
        4, group="position_option"
    )


@dataclass(eq=False, repr=False)
class DeleteReq(betterproto.Message):
    options: "DeleteReqOptions" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class DeleteReqOptions(betterproto.Message):
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(1)
    revision: int = betterproto.uint64_field(2, group="expected_stream_revision")
    no_stream: "__client__.Empty" = betterproto.message_field(
        3, group="expected_stream_revision"
    )
    any: "__client__.Empty" = betterproto.message_field(
        4, group="expected_stream_revision"
    )
    stream_exists: "__client__.Empty" = betterproto.message_field(
        5, group="expected_stream_revision"
    )


@dataclass(eq=False, repr=False)
class DeleteResp(betterproto.Message):
    position: "DeleteRespPosition" = betterproto.message_field(
        1, group="position_option"
    )
    no_position: "__client__.Empty" = betterproto.message_field(
        2, group="position_option"
    )


@dataclass(eq=False, repr=False)
class DeleteRespPosition(betterproto.Message):
    commit_position: int = betterproto.uint64_field(1)
    prepare_position: int = betterproto.uint64_field(2)


@dataclass(eq=False, repr=False)
class TombstoneReq(betterproto.Message):
    options: "TombstoneReqOptions" = betterproto.message_field(1)


@dataclass(eq=False, repr=False)
class TombstoneReqOptions(betterproto.Message):
    stream_identifier: "__client__.StreamIdentifier" = betterproto.message_field(1)
    revision: int = betterproto.uint64_field(2, group="expected_stream_revision")
    no_stream: "__client__.Empty" = betterproto.message_field(
        3, group="expected_stream_revision"
    )
    any: "__client__.Empty" = betterproto.message_field(
        4, group="expected_stream_revision"
    )
    stream_exists: "__client__.Empty" = betterproto.message_field(
        5, group="expected_stream_revision"
    )


@dataclass(eq=False, repr=False)
class TombstoneResp(betterproto.Message):
    position: "TombstoneRespPosition" = betterproto.message_field(
        1, group="position_option"
    )
    no_position: "__client__.Empty" = betterproto.message_field(
        2, group="position_option"
    )


@dataclass(eq=False, repr=False)
class TombstoneRespPosition(betterproto.Message):
    commit_position: int = betterproto.uint64_field(1)
    prepare_position: int = betterproto.uint64_field(2)


class StreamsStub(betterproto.ServiceStub):
    async def read(
        self,
        read_req: "ReadReq",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["ReadResp"]:
        async for response in self._unary_stream(
            "/event_store.client.streams.Streams/Read",
            read_req,
            ReadResp,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    async def append(
        self,
        append_req_iterator: Union[AsyncIterable["AppendReq"], Iterable["AppendReq"]],
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "AppendResp":
        return await self._stream_unary(
            "/event_store.client.streams.Streams/Append",
            append_req_iterator,
            AppendReq,
            AppendResp,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete(
        self,
        delete_req: "DeleteReq",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "DeleteResp":
        return await self._unary_unary(
            "/event_store.client.streams.Streams/Delete",
            delete_req,
            DeleteResp,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def tombstone(
        self,
        tombstone_req: "TombstoneReq",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "TombstoneResp":
        return await self._unary_unary(
            "/event_store.client.streams.Streams/Tombstone",
            tombstone_req,
            TombstoneResp,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def batch_append(
        self,
        batch_append_req_iterator: Union[
            AsyncIterable["BatchAppendReq"], Iterable["BatchAppendReq"]
        ],
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["BatchAppendResp"]:
        async for response in self._stream_stream(
            "/event_store.client.streams.Streams/BatchAppend",
            batch_append_req_iterator,
            BatchAppendReq,
            BatchAppendResp,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response


class StreamsBase(ServiceBase):
    async def read(self, read_req: "ReadReq") -> AsyncIterator["ReadResp"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def append(
        self, append_req_iterator: AsyncIterator["AppendReq"]
    ) -> "AppendResp":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete(self, delete_req: "DeleteReq") -> "DeleteResp":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def tombstone(self, tombstone_req: "TombstoneReq") -> "TombstoneResp":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def batch_append(
        self, batch_append_req_iterator: AsyncIterator["BatchAppendReq"]
    ) -> AsyncIterator["BatchAppendResp"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_read(
        self, stream: "grpclib.server.Stream[ReadReq, ReadResp]"
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.read,
            stream,
            request,
        )

    async def __rpc_append(
        self, stream: "grpclib.server.Stream[AppendReq, AppendResp]"
    ) -> None:
        request = stream.__aiter__()
        response = await self.append(request)
        await stream.send_message(response)

    async def __rpc_delete(
        self, stream: "grpclib.server.Stream[DeleteReq, DeleteResp]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete(request)
        await stream.send_message(response)

    async def __rpc_tombstone(
        self, stream: "grpclib.server.Stream[TombstoneReq, TombstoneResp]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.tombstone(request)
        await stream.send_message(response)

    async def __rpc_batch_append(
        self, stream: "grpclib.server.Stream[BatchAppendReq, BatchAppendResp]"
    ) -> None:
        request = stream.__aiter__()
        await self._call_rpc_handler_server_stream(
            self.batch_append,
            stream,
            request,
        )

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/event_store.client.streams.Streams/Read": grpclib.const.Handler(
                self.__rpc_read,
                grpclib.const.Cardinality.UNARY_STREAM,
                ReadReq,
                ReadResp,
            ),
            "/event_store.client.streams.Streams/Append": grpclib.const.Handler(
                self.__rpc_append,
                grpclib.const.Cardinality.STREAM_UNARY,
                AppendReq,
                AppendResp,
            ),
            "/event_store.client.streams.Streams/Delete": grpclib.const.Handler(
                self.__rpc_delete,
                grpclib.const.Cardinality.UNARY_UNARY,
                DeleteReq,
                DeleteResp,
            ),
            "/event_store.client.streams.Streams/Tombstone": grpclib.const.Handler(
                self.__rpc_tombstone,
                grpclib.const.Cardinality.UNARY_UNARY,
                TombstoneReq,
                TombstoneResp,
            ),
            "/event_store.client.streams.Streams/BatchAppend": grpclib.const.Handler(
                self.__rpc_batch_append,
                grpclib.const.Cardinality.STREAM_STREAM,
                BatchAppendReq,
                BatchAppendResp,
            ),
        }
