# 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 AsyncIterator, Dict, List, Optional

import betterproto
from betterproto.grpc.grpclib_server import ServiceBase
import grpclib


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

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


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

    # The item collection
    collection: "Collection" = betterproto.message_field(1)
    # The items unique id
    id: str = betterproto.string_field(2)


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

    # The document content (JSON object)
    content: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(1)
    # The document's unique key, including collection/sub-collections
    key: "Key" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class ExpressionValue(betterproto.Message):
    # Represents an integer value.
    int_value: int = betterproto.int64_field(1, group="kind")
    # Represents a double value.
    double_value: float = betterproto.double_field(2, group="kind")
    # Represents a string value.
    string_value: str = betterproto.string_field(3, group="kind")
    # Represents a boolean value.
    bool_value: bool = betterproto.bool_field(4, group="kind")


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

    # The query operand or attribute
    operand: str = betterproto.string_field(1)
    # The query operator [ == | < | <= | > | >= | startsWith ]
    operator: str = betterproto.string_field(2)
    # The query expression value
    value: "ExpressionValue" = betterproto.message_field(3)


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


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


@dataclass(eq=False, repr=False)
class DocumentSetRequest(betterproto.Message):
    # Key of the document to set
    key: "Key" = betterproto.message_field(1)
    # The document content to store (JSON object)
    content: "betterproto_lib_google_protobuf.Struct" = betterproto.message_field(3)


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


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


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


@dataclass(eq=False, repr=False)
class DocumentQueryRequest(betterproto.Message):
    # The collection to query
    collection: "Collection" = betterproto.message_field(1)
    # Optional query expressions
    expressions: List["Expression"] = betterproto.message_field(3)
    # Optional query fetch limit
    limit: int = betterproto.int32_field(4)
    # Optional query paging continuation token
    paging_token: Dict[str, str] = betterproto.map_field(
        5, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )


@dataclass(eq=False, repr=False)
class DocumentQueryResponse(betterproto.Message):
    # The retrieved values
    documents: List["Document"] = betterproto.message_field(1)
    # The query paging continuation token, when empty no further results are
    # available
    paging_token: Dict[str, str] = betterproto.map_field(
        2, betterproto.TYPE_STRING, betterproto.TYPE_STRING
    )


@dataclass(eq=False, repr=False)
class DocumentQueryStreamRequest(betterproto.Message):
    # The collection to query
    collection: "Collection" = betterproto.message_field(1)
    # Optional query expressions
    expressions: List["Expression"] = betterproto.message_field(3)
    # Optional query fetch limit
    limit: int = betterproto.int32_field(4)


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


class DocumentServiceStub(betterproto.ServiceStub):
    async def get(self, *, key: "Key" = None) -> "DocumentGetResponse":

        request = DocumentGetRequest()
        if key is not None:
            request.key = key

        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Get", request, DocumentGetResponse
        )

    async def set(
        self,
        *,
        key: "Key" = None,
        content: "betterproto_lib_google_protobuf.Struct" = None,
    ) -> "DocumentSetResponse":

        request = DocumentSetRequest()
        if key is not None:
            request.key = key
        if content is not None:
            request.content = content

        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Set", request, DocumentSetResponse
        )

    async def delete(self, *, key: "Key" = None) -> "DocumentDeleteResponse":

        request = DocumentDeleteRequest()
        if key is not None:
            request.key = key

        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Delete",
            request,
            DocumentDeleteResponse,
        )

    async def query(
        self,
        *,
        collection: "Collection" = None,
        expressions: Optional[List["Expression"]] = None,
        limit: int = 0,
        paging_token: Dict[str, str] = None,
    ) -> "DocumentQueryResponse":
        expressions = expressions or []

        request = DocumentQueryRequest()
        if collection is not None:
            request.collection = collection
        if expressions is not None:
            request.expressions = expressions
        request.limit = limit
        request.paging_token = paging_token

        return await self._unary_unary(
            "/nitric.document.v1.DocumentService/Query", request, DocumentQueryResponse
        )

    async def query_stream(
        self,
        *,
        collection: "Collection" = None,
        expressions: Optional[List["Expression"]] = None,
        limit: int = 0,
    ) -> AsyncIterator["DocumentQueryStreamResponse"]:
        expressions = expressions or []

        request = DocumentQueryStreamRequest()
        if collection is not None:
            request.collection = collection
        if expressions is not None:
            request.expressions = expressions
        request.limit = limit

        async for response in self._unary_stream(
            "/nitric.document.v1.DocumentService/QueryStream",
            request,
            DocumentQueryStreamResponse,
        ):
            yield response


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

    async def set(
        self, key: "Key", content: "betterproto_lib_google_protobuf.Struct"
    ) -> "DocumentSetResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

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

    async def query(
        self,
        collection: "Collection",
        expressions: Optional[List["Expression"]],
        limit: int,
        paging_token: Dict[str, str],
    ) -> "DocumentQueryResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def query_stream(
        self,
        collection: "Collection",
        expressions: Optional[List["Expression"]],
        limit: int,
    ) -> AsyncIterator["DocumentQueryStreamResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_get(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "key": request.key,
        }

        response = await self.get(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_set(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "key": request.key,
            "content": request.content,
        }

        response = await self.set(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_delete(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "key": request.key,
        }

        response = await self.delete(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_query(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection": request.collection,
            "expressions": request.expressions,
            "limit": request.limit,
            "paging_token": request.paging_token,
        }

        response = await self.query(**request_kwargs)
        await stream.send_message(response)

    async def __rpc_query_stream(self, stream: grpclib.server.Stream) -> None:
        request = await stream.recv_message()

        request_kwargs = {
            "collection": request.collection,
            "expressions": request.expressions,
            "limit": request.limit,
        }

        await self._call_rpc_handler_server_stream(
            self.query_stream,
            stream,
            request_kwargs,
        )

    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,
            ),
        }


import betterproto.lib.google.protobuf as betterproto_lib_google_protobuf
