#
# 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/queues/v1/queues.proto
# plugin: python-betterproto
# This file has been @generated

from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    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 QueueEnqueueRequest(betterproto.Message):
    queue_name: str = betterproto.string_field(1)
    """
    The Nitric name for the queue this will automatically be resolved to the
    provider specific queue identifier.
    """

    messages: List["QueueMessage"] = betterproto.message_field(2)
    """Array of messages to push to the queue"""


@dataclass(eq=False, repr=False)
class QueueEnqueueResponse(betterproto.Message):
    """Response for sending messages to a queue"""

    failed_messages: List["FailedEnqueueMessage"] = betterproto.message_field(1)
    """A list of messages that failed to be queued"""


@dataclass(eq=False, repr=False)
class QueueDequeueRequest(betterproto.Message):
    queue_name: str = betterproto.string_field(1)
    """
    The nitric name for the queue this will automatically be resolved to the
    provider specific queue identifier.
    """

    depth: int = betterproto.int32_field(2)
    """
    The max number of messages to pop off the queue, may be capped by provider
    specific limitations
    """


@dataclass(eq=False, repr=False)
class QueueDequeueResponse(betterproto.Message):
    messages: List["DequeuedMessage"] = betterproto.message_field(1)
    """Array of messages popped off the queue"""


@dataclass(eq=False, repr=False)
class QueueCompleteRequest(betterproto.Message):
    queue_name: str = betterproto.string_field(1)
    """
    The nitric name for the queue  this will automatically be resolved to the
    provider specific queue identifier.
    """

    lease_id: str = betterproto.string_field(2)
    """Lease id of the message to be completed"""


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


@dataclass(eq=False, repr=False)
class QueueMessage(betterproto.Message):
    """An message to be sent to a queue."""

    struct_payload: "betterproto_lib_google_protobuf.Struct" = (
        betterproto.message_field(1, group="content")
    )


@dataclass(eq=False, repr=False)
class DequeuedMessage(betterproto.Message):
    lease_id: str = betterproto.string_field(1)
    message: "QueueMessage" = betterproto.message_field(2)


@dataclass(eq=False, repr=False)
class FailedEnqueueMessage(betterproto.Message):
    message: "QueueMessage" = betterproto.message_field(1)
    """The message that failed to be pushed"""

    details: str = betterproto.string_field(2)
    """A description of the failure"""


class QueuesStub(betterproto.ServiceStub):
    async def enqueue(
        self,
        queue_enqueue_request: "QueueEnqueueRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "QueueEnqueueResponse":
        return await self._unary_unary(
            "/nitric.proto.queues.v1.Queues/Enqueue",
            queue_enqueue_request,
            QueueEnqueueResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def dequeue(
        self,
        queue_dequeue_request: "QueueDequeueRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "QueueDequeueResponse":
        return await self._unary_unary(
            "/nitric.proto.queues.v1.Queues/Dequeue",
            queue_dequeue_request,
            QueueDequeueResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    async def complete(
        self,
        queue_complete_request: "QueueCompleteRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "QueueCompleteResponse":
        return await self._unary_unary(
            "/nitric.proto.queues.v1.Queues/Complete",
            queue_complete_request,
            QueueCompleteResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )


class QueuesBase(ServiceBase):
    async def enqueue(
        self, queue_enqueue_request: "QueueEnqueueRequest"
    ) -> "QueueEnqueueResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def dequeue(
        self, queue_dequeue_request: "QueueDequeueRequest"
    ) -> "QueueDequeueResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def complete(
        self, queue_complete_request: "QueueCompleteRequest"
    ) -> "QueueCompleteResponse":
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_enqueue(
        self, stream: "grpclib.server.Stream[QueueEnqueueRequest, QueueEnqueueResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.enqueue(request)
        await stream.send_message(response)

    async def __rpc_dequeue(
        self, stream: "grpclib.server.Stream[QueueDequeueRequest, QueueDequeueResponse]"
    ) -> None:
        request = await stream.recv_message()
        response = await self.dequeue(request)
        await stream.send_message(response)

    async def __rpc_complete(
        self,
        stream: "grpclib.server.Stream[QueueCompleteRequest, QueueCompleteResponse]",
    ) -> None:
        request = await stream.recv_message()
        response = await self.complete(request)
        await stream.send_message(response)

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/nitric.proto.queues.v1.Queues/Enqueue": grpclib.const.Handler(
                self.__rpc_enqueue,
                grpclib.const.Cardinality.UNARY_UNARY,
                QueueEnqueueRequest,
                QueueEnqueueResponse,
            ),
            "/nitric.proto.queues.v1.Queues/Dequeue": grpclib.const.Handler(
                self.__rpc_dequeue,
                grpclib.const.Cardinality.UNARY_UNARY,
                QueueDequeueRequest,
                QueueDequeueResponse,
            ),
            "/nitric.proto.queues.v1.Queues/Complete": grpclib.const.Handler(
                self.__rpc_complete,
                grpclib.const.Cardinality.UNARY_UNARY,
                QueueCompleteRequest,
                QueueCompleteResponse,
            ),
        }
