#
# Copyright (c) 2021 Nitric Technologies Pty Ltd.
#
# This file is part of Nitric Python 3 SDK.
# See https://github.com/nitrictech/python-sdk for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: nitric/proto/kvstore/v1/kvstore.proto
# plugin: python-betterproto
# This file has been @generated

from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    AsyncIterator,
    Dict,
    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 Store(betterproto.Message):
    """Provides a Key/Value Store"""

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


@dataclass(eq=False, repr=False)
class ValueRef(betterproto.Message):
    """ValueRef provides a unique identifier for a value"""

    store: str = betterproto.string_field(1)
    """The key/value store name"""

    key: str = betterproto.string_field(2)
    """The item's unique key within the store"""


@dataclass(eq=False, repr=False)
class Value(betterproto.Message):
    """Value provides a return value type"""

    ref: "ValueRef" = betterproto.message_field(1)
    """ValueRef of the key/value pair, which includes the store and key"""

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


@dataclass(eq=False, repr=False)
class KvStoreGetValueRequest(betterproto.Message):
    ref: "ValueRef" = betterproto.message_field(1)
    """
    ValueRef of the key/value pair to get, which includes the store and key
    """


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


@dataclass(eq=False, repr=False)
class KvStoreSetValueRequest(betterproto.Message):
    ref: "ValueRef" = betterproto.message_field(1)
    """
    ValueRef of the key/value pair to set, which includes the store and key
    """

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


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


@dataclass(eq=False, repr=False)
class KvStoreDeleteKeyRequest(betterproto.Message):
    ref: "ValueRef" = betterproto.message_field(1)
    """
    ValueRef of the key/value pair to delete, which includes the store and key
    """


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


@dataclass(eq=False, repr=False)
class KvStoreScanKeysRequest(betterproto.Message):
    store: "Store" = betterproto.message_field(1)
    """The store to iterate over"""

    prefix: str = betterproto.string_field(2)
    """The prefix to filter keys by"""


@dataclass(eq=False, repr=False)
class KvStoreScanKeysResponse(betterproto.Message):
    key: str = betterproto.string_field(1)
    """The key of the key/value pair"""


class KvStoreStub(betterproto.ServiceStub):
    async def get_value(
        self,
        kv_store_get_value_request: "KvStoreGetValueRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "KvStoreGetValueResponse":
        return await self._unary_unary(
            "/nitric.proto.kvstore.v1.KvStore/GetValue",
            kv_store_get_value_request,
            KvStoreGetValueResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def set_value(
        self,
        kv_store_set_value_request: "KvStoreSetValueRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "KvStoreSetValueResponse":
        return await self._unary_unary(
            "/nitric.proto.kvstore.v1.KvStore/SetValue",
            kv_store_set_value_request,
            KvStoreSetValueResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def delete_key(
        self,
        kv_store_delete_key_request: "KvStoreDeleteKeyRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "KvStoreDeleteKeyResponse":
        return await self._unary_unary(
            "/nitric.proto.kvstore.v1.KvStore/DeleteKey",
            kv_store_delete_key_request,
            KvStoreDeleteKeyResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def scan_keys(
        self,
        kv_store_scan_keys_request: "KvStoreScanKeysRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["KvStoreScanKeysResponse"]:
        async for response in self._unary_stream(
            "/nitric.proto.kvstore.v1.KvStore/ScanKeys",
            kv_store_scan_keys_request,
            KvStoreScanKeysResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response


class KvStoreBase(ServiceBase):
    async def get_value(
        self, kv_store_get_value_request: "KvStoreGetValueRequest"
    ) -> "KvStoreGetValueResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def set_value(
        self, kv_store_set_value_request: "KvStoreSetValueRequest"
    ) -> "KvStoreSetValueResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete_key(
        self, kv_store_delete_key_request: "KvStoreDeleteKeyRequest"
    ) -> "KvStoreDeleteKeyResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def scan_keys(
        self, kv_store_scan_keys_request: "KvStoreScanKeysRequest"
    ) -> AsyncIterator["KvStoreScanKeysResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)
        yield KvStoreScanKeysResponse()

    async def __rpc_get_value(
        self,
        stream: "grpclib.server.Stream[KvStoreGetValueRequest, KvStoreGetValueResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.get_value(request)
        await stream.send_message(response)

    async def __rpc_set_value(
        self,
        stream: "grpclib.server.Stream[KvStoreSetValueRequest, KvStoreSetValueResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.set_value(request)
        await stream.send_message(response)

    async def __rpc_delete_key(
        self,
        stream: "grpclib.server.Stream[KvStoreDeleteKeyRequest, KvStoreDeleteKeyResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.delete_key(request)
        await stream.send_message(response)

    async def __rpc_scan_keys(
        self,
        stream: "grpclib.server.Stream[KvStoreScanKeysRequest, KvStoreScanKeysResponse]",
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.scan_keys,
            stream,
            request,
        )

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nitric.proto.kvstore.v1.KvStore/GetValue": grpclib.const.Handler(
                self.__rpc_get_value,
                grpclib.const.Cardinality.UNARY_UNARY,
                KvStoreGetValueRequest,
                KvStoreGetValueResponse,
            ),
            "/nitric.proto.kvstore.v1.KvStore/SetValue": grpclib.const.Handler(
                self.__rpc_set_value,
                grpclib.const.Cardinality.UNARY_UNARY,
                KvStoreSetValueRequest,
                KvStoreSetValueResponse,
            ),
            "/nitric.proto.kvstore.v1.KvStore/DeleteKey": grpclib.const.Handler(
                self.__rpc_delete_key,
                grpclib.const.Cardinality.UNARY_UNARY,
                KvStoreDeleteKeyRequest,
                KvStoreDeleteKeyResponse,
            ),
            "/nitric.proto.kvstore.v1.KvStore/ScanKeys": grpclib.const.Handler(
                self.__rpc_scan_keys,
                grpclib.const.Cardinality.UNARY_STREAM,
                KvStoreScanKeysRequest,
                KvStoreScanKeysResponse,
            ),
        }
