# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: blickfeld/percept_pipeline/services/data_source.proto, blickfeld/percept_pipeline/services/health.proto, blickfeld/percept_pipeline/services/perception.proto, blickfeld/percept_pipeline/services/runtime_action.proto, blickfeld/percept_pipeline/services/zone.proto
# plugin: python-betterproto
import asyncio
from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    AsyncIterator,
    Dict,
    Iterator,
    List,
    Optional,
)

import blickfeld_qb2.betterproto as betterproto
import blickfeld_qb2.betterproto.lib.google.protobuf as betterproto_lib_google_protobuf
import grpclib
from blickfeld_qb2.betterproto.grpc.grpclib_server import ServiceBase

from .. import (
    config as _config__,
    data as _data__,
)


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


@dataclass(eq=False, repr=False)
class DataSourceGetResponse(betterproto.Message):
    """Response containing the current data source"""

    data_source: "_config__.DataSource" = betterproto.message_field(1)
    """The currently set data source"""


@dataclass(eq=False, repr=False)
class DataSourceSetRequest(betterproto.Message):
    """Request for setting the data source"""

    data_source: "_config__.DataSource" = betterproto.message_field(1)
    """The data source to be set"""


@dataclass(eq=False, repr=False)
class DataSourceWatchResponse(betterproto.Message):
    """Continuous response on data source changes"""

    data_source: "_config__.DataSource" = betterproto.message_field(1)
    """The currently set data source"""


@dataclass(eq=False, repr=False)
class RuntimeActionGetTareVolumeRequest(betterproto.Message):
    """Request for the raw volume to be used for taring a volume zone"""

    zone_uuid: str = betterproto.string_field(1)
    """The uuid of the volume zone"""


@dataclass(eq=False, repr=False)
class RuntimeActionGetTareVolumeResponse(betterproto.Message):
    """Response containing the raw volume of the requested zone"""

    tare_volume: float = betterproto.float_field(1)
    """
    The raw volume of the volume zone without any offsets/modifications. The
    value is supposed to be configured as 'empty_volume' value of a volume
    zone. As a result the current volume of the zone will be '0' until more
    volume is added.
    """


@dataclass(eq=False, repr=False)
class RuntimeActionResetBackgroundRequest(betterproto.Message):
    """
    Request to reset the background model of one, multiple or all devices
    """

    fqdns: List[str] = betterproto.string_field(1)
    """
    If the list is empty, the background models of all data sources are reset.
    If the background models of only specific devices should be rebuilt, the
    'fqdn' of the respective devices has to be mentioned in the 'fqdns' list.
    """


@dataclass(eq=False, repr=False)
class PerceptionGetResponse(betterproto.Message):
    """Response containing the current perception configuration"""

    perception: "_config__.Perception" = betterproto.message_field(1)
    """The current perception configuration"""


@dataclass(eq=False, repr=False)
class PerceptionSetRequest(betterproto.Message):
    """Request for setting the perception configuration"""

    template_name: str = betterproto.string_field(1, group="set_type")
    """
    Use a template to set the configuration, templates are predefined
    perception configurations
    """

    perception: "_config__.Perception" = betterproto.message_field(2, group="set_type")
    """Use the specified configuration"""


@dataclass(eq=False, repr=False)
class PerceptionWatchResponse(betterproto.Message):
    """Continuous response on perception configuration changes"""

    perception: "_config__.Perception" = betterproto.message_field(1)
    """The current set perception configuration"""


@dataclass(eq=False, repr=False)
class PerceptionListTemplatesResponse(betterproto.Message):
    """Response containing perception configuration templates"""

    named_templates: Dict[str, "_config__.Perception"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    """
    Mapping from a template name to the template itself. The template can be
    used to configure the perception algorithms for certain use-cases.
    """


@dataclass(eq=False, repr=False)
class HealthWatchResponse(betterproto.Message):
    """Stream response containing health of the module"""

    health: "_data__.Health" = betterproto.message_field(1)
    """The module health"""


@dataclass(eq=False, repr=False)
class HealthGetResponse(betterproto.Message):
    """Get response containing health of the module"""

    health: "_data__.Health" = betterproto.message_field(1)
    """The module health"""


@dataclass(eq=False, repr=False)
class ZoneListResponse(betterproto.Message):
    """Response containing the configured list of zones"""

    zones: List["_config__.ZoneAlgorithm"] = betterproto.message_field(1)
    """The currently configured zones"""


@dataclass(eq=False, repr=False)
class ZoneStoreRequest(betterproto.Message):
    """Request to store or update an existing zone"""

    zone: "_config__.ZoneAlgorithm" = betterproto.message_field(1)
    """
    The new zone to be added. If there is a zone with the same uuid, that zone
    will get updated with this configuration.
    """


@dataclass(eq=False, repr=False)
class ZoneDeleteRequest(betterproto.Message):
    """Request to delete a zone"""

    uuid: str = betterproto.string_field(1)
    """The uuid of the zone to be deleted"""


@dataclass(eq=False, repr=False)
class ZoneWatchResponse(betterproto.Message):
    """Continuous response on zone list changes"""

    zones: List["_config__.ZoneAlgorithm"] = betterproto.message_field(1)
    """The current/updated list of zones"""


class DataSource(betterproto.ServiceStub):
    """
    The data source service allows getting, configuring and receiving updates
    of the data source used for processing pipelines. The data source
    configuration specifies where to retrieve the point cloud data for further
    processing.
    """

    async def async_get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "DataSourceGetResponse":
        """Get current data_source Configuration"""

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.DataSource/Get",
            request,
            DataSourceGetResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "DataSourceGetResponse":
        """Get current data_source Configuration"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_get(
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_set(
        self,
        *,
        data_source: "_config__.DataSource" = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Set configuration for data_source"""

        request = DataSourceSetRequest()
        if data_source is not None:
            request.data_source = data_source

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.DataSource/Set",
            request,
            betterproto_lib_google_protobuf.Empty,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def set(
        self,
        *,
        data_source: "_config__.DataSource" = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Set configuration for data_source"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_set(
                data_source=data_source,
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["DataSourceWatchResponse"]:
        """Watch configuration for data_source"""

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.percept_pipeline.services.DataSource/Watch",
            request,
            DataSourceWatchResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["DataSourceWatchResponse"]:
        """Watch configuration for data_source"""

        loop = asyncio.get_event_loop()
        ait = self.async_watch(
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ).__aiter__()

        async def get_next():
            try:
                obj = await ait.__anext__()
                return False, obj
            except StopAsyncIteration:
                return True, None

        while True:
            done, obj = loop.run_until_complete(get_next())
            if done:
                break
            yield obj


class RuntimeAction(betterproto.ServiceStub):
    """
    The RuntimeAction service enables the system to execute runtime actions and
    updates on a running pipeline.
    """

    async def async_get_tare_volume(
        self,
        *,
        zone_uuid: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "RuntimeActionGetTareVolumeResponse":
        """Computes raw volume within a volume zone without any offsets."""

        request = RuntimeActionGetTareVolumeRequest()
        request.zone_uuid = zone_uuid

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.RuntimeAction/GetTareVolume",
            request,
            RuntimeActionGetTareVolumeResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def get_tare_volume(
        self,
        *,
        zone_uuid: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "RuntimeActionGetTareVolumeResponse":
        """Computes raw volume within a volume zone without any offsets."""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_get_tare_volume(
                zone_uuid=zone_uuid,
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_reset_background(
        self,
        *,
        fqdns: Optional[List[str]] = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Resets the background of one, multiple or all devices"""

        fqdns = fqdns or []

        request = RuntimeActionResetBackgroundRequest()
        request.fqdns = fqdns

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.RuntimeAction/ResetBackground",
            request,
            betterproto_lib_google_protobuf.Empty,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def reset_background(
        self,
        *,
        fqdns: Optional[List[str]] = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Resets the background of one, multiple or all devices"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_reset_background(
                fqdns=fqdns,
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )


class Perception(betterproto.ServiceStub):
    """
    The perception service allows getting, configuring and receiving updates of
    the perception configurations. Perception configurations specify the
    algorithms used for e.g. for background subtraction etc.
    """

    async def async_get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PerceptionGetResponse":
        """Get current perception configuration"""

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.Perception/Get",
            request,
            PerceptionGetResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PerceptionGetResponse":
        """Get current perception configuration"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_get(
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_set(
        self,
        *,
        template_name: str = "",
        perception: "_config__.Perception" = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Set the perception configuration"""

        request = PerceptionSetRequest()
        request.template_name = template_name
        if perception is not None:
            request.perception = perception

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.Perception/Set",
            request,
            betterproto_lib_google_protobuf.Empty,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def set(
        self,
        *,
        template_name: str = "",
        perception: "_config__.Perception" = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Set the perception configuration"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_set(
                template_name=template_name,
                perception=perception,
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["PerceptionWatchResponse"]:
        """Watch changes of perception configuration"""

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.percept_pipeline.services.Perception/Watch",
            request,
            PerceptionWatchResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["PerceptionWatchResponse"]:
        """Watch changes of perception configuration"""

        loop = asyncio.get_event_loop()
        ait = self.async_watch(
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ).__aiter__()

        async def get_next():
            try:
                obj = await ait.__anext__()
                return False, obj
            except StopAsyncIteration:
                return True, None

        while True:
            done, obj = loop.run_until_complete(get_next())
            if done:
                break
            yield obj

    async def async_list_templates(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PerceptionListTemplatesResponse":
        """Return list of names for named templates"""

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.Perception/ListTemplates",
            request,
            PerceptionListTemplatesResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def list_templates(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PerceptionListTemplatesResponse":
        """Return list of names for named templates"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_list_templates(
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )


class Health(betterproto.ServiceStub):
    """Reports the health of the pipeline module."""

    async def async_watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["HealthWatchResponse"]:
        """
        Streams health information on a regular cadence or if certain incidents
        happen
        """

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.percept_pipeline.services.Health/Watch",
            request,
            HealthWatchResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["HealthWatchResponse"]:
        """
        Streams health information on a regular cadence or if certain incidents
        happen
        """

        loop = asyncio.get_event_loop()
        ait = self.async_watch(
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ).__aiter__()

        async def get_next():
            try:
                obj = await ait.__anext__()
                return False, obj
            except StopAsyncIteration:
                return True, None

        while True:
            done, obj = loop.run_until_complete(get_next())
            if done:
                break
            yield obj

    async def async_get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "HealthGetResponse":
        """Returns the current health information"""

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.Health/Get",
            request,
            HealthGetResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "HealthGetResponse":
        """Returns the current health information"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_get(
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )


class Zone(betterproto.ServiceStub):
    """
    The zone service allows getting, configuring, deleting and receiving
    updates of the configured zones.
    """

    async def async_list(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "ZoneListResponse":
        """Returns the configured zones"""

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.Zone/List",
            request,
            ZoneListResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def list(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "ZoneListResponse":
        """Returns the configured zones"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_list(
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_store(
        self,
        *,
        zone: "_config__.ZoneAlgorithm" = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Store / Update a zone"""

        request = ZoneStoreRequest()
        if zone is not None:
            request.zone = zone

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.Zone/Store",
            request,
            betterproto_lib_google_protobuf.Empty,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def store(
        self,
        *,
        zone: "_config__.ZoneAlgorithm" = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Store / Update a zone"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_store(
                zone=zone,
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_delete(
        self,
        *,
        uuid: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Delete a zone"""

        request = ZoneDeleteRequest()
        request.uuid = uuid

        return await self._unary_unary(
            "/blickfeld.percept_pipeline.services.Zone/Delete",
            request,
            betterproto_lib_google_protobuf.Empty,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def delete(
        self,
        *,
        uuid: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Delete a zone"""

        loop = asyncio.get_event_loop()
        return loop.run_until_complete(
            self.async_delete(
                uuid=uuid,
                timeout=timeout,
                deadline=deadline,
                metadata=metadata,
            )
        )

    async def async_watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["ZoneWatchResponse"]:
        """Watch configuration for zone list"""

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.percept_pipeline.services.Zone/Watch",
            request,
            ZoneWatchResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["ZoneWatchResponse"]:
        """Watch configuration for zone list"""

        loop = asyncio.get_event_loop()
        ait = self.async_watch(
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ).__aiter__()

        async def get_next():
            try:
                obj = await ait.__anext__()
                return False, obj
            except StopAsyncIteration:
                return True, None

        while True:
            done, obj = loop.run_until_complete(get_next())
            if done:
                break
            yield obj
