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

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

from ..cloud import types as _cloud_types__


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


class Result(betterproto.Enum):
    RESULT_UNSPECIFIED = 0
    SUCCESS = 1
    """Success codes (1-99)"""

    ERROR_UNKNOWN = 100
    """Error codes (100+)"""

    ERROR_UNKNOWN_MAPPING_KEY = 101
    ERROR_TIMEOUT = 103
    ERROR_HOST_UNREACHABLE = 104
    ERROR_VALUE_TYPE_CHANGE = 120
    ERROR_VALUE_ARRAY_INDEX_INVALID = 121
    ERROR_VALUE_TYPE_INVALID = 122
    ERROR_VALUE_TYPE_UNSUPPORTED = 123
    ERROR_VALUE_NOT_ARRAY = 124
    ERROR_VALUE_OUT_OF_RANGE = 125
    ERROR_VALUE_WRITE_ACCESS_DENIED = 126
    ERROR_DEVICE_OTHER = 150
    ERROR_DEVICE_NO_WRITE_SUPPORT = 151
    ERROR_DEVICE_ACCESS_DENIED = 152


@dataclass(eq=False, repr=False)
class WritePropsRequest(betterproto.Message):
    values: List["MappingKeyAndValue"] = betterproto.message_field(1)
    """The property value(s) to write"""

    timeout_per_device_in_ms: int = betterproto.uint32_field(2)
    """
    The timeout for each request to each subtended device in milliseconds NOTE:
    UGAgent makes every attempt to parallelize these, but some devices don't
    support       writing multiple properties at once, which means write
    requests must be serialized
    """

    simulate: bool = betterproto.bool_field(100)
    """
    Simulate the command by only validating the input and logging do not send
    actual commands over the wire
    """


@dataclass(eq=False, repr=False)
class WritePropsResponse(betterproto.Message):
    request_id: str = betterproto.string_field(1)
    """
    The unique ID of this request to be provided to Mapped Support for
    troubleshooting in the case of unexpected errors
    """

    results: List["MappingKeyAndResult"] = betterproto.message_field(2)
    """The result of each property write"""


@dataclass(eq=False, repr=False)
class MappingKeyAndValue(betterproto.Message):
    mapping_key: str = betterproto.string_field(1)
    """
    The mappingKey where the value originated from or is to be written to
    """

    value: "_cloud_types__.TypedValue" = betterproto.message_field(2)
    """
    The value read or to be written  NOTE: The value *type* must NOT change
    type between a read and a write
    """


@dataclass(eq=False, repr=False)
class MappingKeyAndResult(betterproto.Message):
    mapping_key: str = betterproto.string_field(1)
    """The mappingKey where the this result originated from"""

    result: "Result" = betterproto.enum_field(2)
    """The result code"""

    error_description: str = betterproto.string_field(3)
    """Error description (if available)"""

    protocol_error_class: int = betterproto.int64_field(4)
    """
    Protocol-specific error class, for protocols that split class/code - like
    BACnet
    """

    protocol_error_code: int = betterproto.int64_field(5)
    """Protocol-specific error code"""


@dataclass(eq=False, repr=False)
class RedisPoint(betterproto.Message):
    """RedisPoint is used for edge present value streams in Redis"""

    present_value: "_cloud_types__.TypedValue" = betterproto.message_field(1)
    """The present value of this point"""

    last_update: datetime = betterproto.message_field(2)
    """The timestamp of when the point was last updated in the Mapped UG"""

    network_error_start: datetime = betterproto.message_field(3)
    """
    The timestamp of when network errors started for this point (or really, the
    deivce that owns this point) A zero value (seconds==0; nanos==0) means
    there are no network issues
    """

    consecutive_network_error_count: int = betterproto.uint32_field(4)
    """
    A count of how many consecutive network errors have been observed since
    `network_error_start` A zero value (==0) here means there are there were no
    network errors in the last update to this point
    """


class EdgeControlServiceStub(betterproto.ServiceStub):
    async def write_props(
        self,
        write_props_request: "WritePropsRequest",
        *,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["WritePropsResponse"]:
        async for response in self._unary_stream(
            "/mapped.gateway.EdgeControlService/WriteProps",
            write_props_request,
            WritePropsResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response


class EdgeControlServiceBase(ServiceBase):
    async def write_props(
        self, write_props_request: "WritePropsRequest"
    ) -> AsyncIterator["WritePropsResponse"]:
        raise grpclib.GRPCError(grpclib.const.Status.UNIMPLEMENTED)

    async def __rpc_write_props(
        self, stream: "grpclib.server.Stream[WritePropsRequest, WritePropsResponse]"
    ) -> None:
        request = await stream.recv_message()
        await self._call_rpc_handler_server_stream(
            self.write_props,
            stream,
            request,
        )

    def __mapping__(self) -> Dict[str, grpclib.const.Handler]:
        return {
            "/mapped.gateway.EdgeControlService/WriteProps": grpclib.const.Handler(
                self.__rpc_write_props,
                grpclib.const.Cardinality.UNARY_STREAM,
                WritePropsRequest,
                WritePropsResponse,
            ),
        }
