# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: proto/document/v1/document.proto
# plugin: python-betterproto
from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    AsyncIterator,
    Dict,
    List,
    Optional,
)

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


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


@dataclass(eq=False, repr=False)
class Collection(betterproto.Message):
    """Provides a Collection type for storing documents"""

    name: str = betterproto.string_field(1)
    """The collection name"""

    parent: "Key" = betterproto.message_field(2)
    """
    Optional parent key, required when the collection is a sub-collection of
    another document
    """


@dataclass(eq=False, repr=False)
class Key(betterproto.Message):
    """Provides a document identifying key type"""

    collection: "Collection" = betterproto.message_field(1)
    """The item collection"""

    id: str = betterproto.string_field(2)
    """The items unique id"""


@dataclass(eq=False, repr=False)
class Document(betterproto.Message):
    """Provides a return document type"""

    content: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(1)
    """The document content (JSON object)"""

    key: "Key" = betterproto.message_field(2)
    """The document's unique key, including collection/sub-collections"""


@dataclass(eq=False, repr=False)
class ExpressionValue(betterproto.Message):
    int_value: int = betterproto.int64_field(1, group="kind")
    """Represents an integer value."""

    double_value: float = betterproto.double_field(2, group="kind")
    """Represents a double value."""

    string_value: str = betterproto.string_field(3, group="kind")
    """Represents a string value."""

    bool_value: bool = betterproto.bool_field(4, group="kind")
    """Represents a boolean value."""


@dataclass(eq=False, repr=False)
class Expression(betterproto.Message):
    """Provides a query expression type"""

    operand: str = betterproto.string_field(1)
    """The query operand or attribute"""

    operator: str = betterproto.string_field(2)
    """The query operator [ == | < | <= | > | >= | startsWith ]"""

    value: "ExpressionValue" = betterproto.message_field(3)
    """The query expression value"""


@dataclass(eq=False, repr=False)
class DocumentGetRequest(betterproto.Message):
    key: "Key" = betterproto.message_field(1)
    """Key of the document to retrieve"""


@dataclass(eq=False, repr=False)
class DocumentGetResponse(betterproto.Message):
    document: "Document" = betterproto.message_field(1)
    """The retrieved value"""


@dataclass(eq=False, repr=False)
class DocumentSetRequest(betterproto.Message):
    key: "Key" = betterproto.message_field(1)
    """Key of the document to set"""

    content: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(3)
    """The document content to store (JSON object)"""


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


@dataclass(eq=False, repr=False)
class DocumentDeleteRequest(betterproto.Message):
    key: "Key" = betterproto.message_field(1)
    """Key of the document to delete"""


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


@dataclass(eq=False, repr=False)
class DocumentQueryRequest(betterproto.Message):
    collection: "Collection" = betterproto.message_field(1)
    """The collection to query"""

    expressions: List["Expression"] = betterproto.message_field(3)
    """Optional query expressions"""

    limit: int = betterproto.int32_field(4)
    """Optional query fetch limit"""

    paging_token: Dict[str, str] = betterproto.map_field(
        5, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    """Optional query paging continuation token"""


@dataclass(eq=False, repr=False)
class DocumentQueryResponse(betterproto.Message):
    documents: List["Document"] = betterproto.message_field(1)
    """The retrieved values"""

    paging_token: Dict[str, str] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )
    """
    The query paging continuation token, when empty no further results are
    available
    """


@dataclass(eq=False, repr=False)
class DocumentQueryStreamRequest(betterproto.Message):
    collection: "Collection" = betterproto.message_field(1)
    """The collection to query"""

    expressions: List["Expression"] = betterproto.message_field(3)
    """Optional query expressions"""

    limit: int = betterproto.int32_field(4)
    """Optional query fetch limit"""


@dataclass(eq=False, repr=False)
class DocumentQueryStreamResponse(betterproto.Message):
    document: "Document" = betterproto.message_field(1)
    """The stream document"""


class DocumentServiceStub(betterproto.ServiceStub):
    async def get(
        self,
        document_get_request: "DocumentGetRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "DocumentGetResponse":
        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Get",
            document_get_request,
            DocumentGetResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def set(
        self,
        document_set_request: "DocumentSetRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "DocumentSetResponse":
        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Set",
            document_set_request,
            DocumentSetResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete(
        self,
        document_delete_request: "DocumentDeleteRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "DocumentDeleteResponse":
        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Delete",
            document_delete_request,
            DocumentDeleteResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def query(
        self,
        document_query_request: "DocumentQueryRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "DocumentQueryResponse":
        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Query",
            document_query_request,
            DocumentQueryResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def query_stream(
        self,
        document_query_stream_request: "DocumentQueryStreamRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["DocumentQueryStreamResponse"]:
        async for response in self._unary_stream(
            "/nitric.document.v1.DocumentService/QueryStream",
            document_query_stream_request,
            DocumentQueryStreamResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response


class DocumentServiceBase(ServiceBase):
    async def get(
        self, document_get_request: "DocumentGetRequest"
    ) -> "DocumentGetResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def set(
        self, document_set_request: "DocumentSetRequest"
    ) -> "DocumentSetResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete(
        self, document_delete_request: "DocumentDeleteRequest"
    ) -> "DocumentDeleteResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def query(
        self, document_query_request: "DocumentQueryRequest"
    ) -> "DocumentQueryResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def query_stream(
        self, document_query_stream_request: "DocumentQueryStreamRequest"
    ) -> AsyncIterator["DocumentQueryStreamResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get(
        self, stream: "grpclib.server.Stream[DocumentGetRequest, DocumentGetResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.get(request)
        await stream.send_message(response)

    async def __rpc_set(
        self, stream: "grpclib.server.Stream[DocumentSetRequest, DocumentSetResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.set(request)
        await stream.send_message(response)

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

    async def __rpc_query(
        self,
        stream: "grpclib.server.Stream[DocumentQueryRequest, DocumentQueryResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.query(request)
        await stream.send_message(response)

    async def __rpc_query_stream(
        self,
        stream: "grpclib.server.Stream[DocumentQueryStreamRequest, DocumentQueryStreamResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.query_stream,
            stream,
            request,
        )

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nitric.document.v1.DocumentService/Get": grpclib.const.Handler(
                self.__rpc_get,
                grpclib.const.Cardinality.UNARY_UNARY,
                DocumentGetRequest,
                DocumentGetResponse,
            ),
            "/nitric.document.v1.DocumentService/Set": grpclib.const.Handler(
                self.__rpc_set,
                grpclib.const.Cardinality.UNARY_UNARY,
                DocumentSetRequest,
                DocumentSetResponse,
            ),
            "/nitric.document.v1.DocumentService/Delete": grpclib.const.Handler(
                self.__rpc_delete,
                grpclib.const.Cardinality.UNARY_UNARY,
                DocumentDeleteRequest,
                DocumentDeleteResponse,
            ),
            "/nitric.document.v1.DocumentService/Query": grpclib.const.Handler(
                self.__rpc_query,
                grpclib.const.Cardinality.UNARY_UNARY,
                DocumentQueryRequest,
                DocumentQueryResponse,
            ),
            "/nitric.document.v1.DocumentService/QueryStream": grpclib.const.Handler(
                self.__rpc_query_stream,
                grpclib.const.Cardinality.UNARY_STREAM,
                DocumentQueryStreamRequest,
                DocumentQueryStreamResponse,
            ),
        }
