#
# 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: storage/v1/storage.proto
# plugin: python-betterproto
from dataclasses import dataclass
from typing import Dict

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


@dataclass(eq=False, repr=False)
class StorageWriteRequest(betterproto.Message):
    """Request to put (create/update) a storage item"""

    # Nitric name of the bucket to store in  this will be automatically resolved
    # to the provider specific bucket identifier.
    bucket_name: str = betterproto.string_field(1)
    # Key to store the item under
    key: str = betterproto.string_field(2)
    # bytes array to store
    body: bytes = betterproto.bytes_field(3)


@dataclass(eq=False, repr=False)
class StorageWriteResponse(betterproto.Message):
    """Result of putting a storage item"""

    pass


@dataclass(eq=False, repr=False)
class StorageReadRequest(betterproto.Message):
    """Request to retrieve a storage item"""

    # Nitric name of the bucket to retrieve from  this will be automatically
    # resolved to the provider specific bucket identifier.
    bucket_name: str = betterproto.string_field(1)
    # Key of item to retrieve
    key: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class StorageReadResponse(betterproto.Message):
    """Returned storage item"""

    # The body bytes of the retrieved storage item
    body: bytes = betterproto.bytes_field(1)


@dataclass(eq=False, repr=False)
class StorageDeleteRequest(betterproto.Message):
    """Request to delete a storage item"""

    # Name of the bucket to delete from
    bucket_name: str = betterproto.string_field(1)
    # Key of item to delete
    key: str = betterproto.string_field(2)


@dataclass(eq=False, repr=False)
class StorageDeleteResponse(betterproto.Message):
    """Result of deleting a storage item"""

    pass


class StorageServiceStub(betterproto.ServiceStub):
    async def read(
        self, *, bucket_name: str = "", key: str = ""
    ) -> "StorageReadResponse":

        request = StorageReadRequest()
        request.bucket_name = bucket_name
        request.key = key

        return await self._unary_unary(
            "/nitric.storage.v1.StorageService/Read", request, StorageReadResponse
        )

    async def write(
        self, *, bucket_name: str = "", key: str = "", body: bytes = b""
    ) -> "StorageWriteResponse":

        request = StorageWriteRequest()
        request.bucket_name = bucket_name
        request.key = key
        request.body = body

        return await self._unary_unary(
            "/nitric.storage.v1.StorageService/Write", request, StorageWriteResponse
        )

    async def delete(
        self, *, bucket_name: str = "", key: str = ""
    ) -> "StorageDeleteResponse":

        request = StorageDeleteRequest()
        request.bucket_name = bucket_name
        request.key = key

        return await self._unary_unary(
            "/nitric.storage.v1.StorageService/Delete", request, StorageDeleteResponse
        )


class StorageServiceBase(ServiceBase):
    async def read(self, bucket_name: str, key: str) -> "StorageReadResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def write(
        self, bucket_name: str, key: str, body: bytes
    ) -> "StorageWriteResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def delete(self, bucket_name: str, key: str) -> "StorageDeleteResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

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

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

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

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

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

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

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

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

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

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nitric.storage.v1.StorageService/Read": grpclib.const.Handler(
                self.__rpc_read,
                grpclib.const.Cardinality.UNARY_UNARY,
                StorageReadRequest,
                StorageReadResponse,
            ),
            "/nitric.storage.v1.StorageService/Write": grpclib.const.Handler(
                self.__rpc_write,
                grpclib.const.Cardinality.UNARY_UNARY,
                StorageWriteRequest,
                StorageWriteResponse,
            ),
            "/nitric.storage.v1.StorageService/Delete": grpclib.const.Handler(
                self.__rpc_delete,
                grpclib.const.Cardinality.UNARY_UNARY,
                StorageDeleteRequest,
                StorageDeleteResponse,
            ),
        }
