# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: blickfeld/percept_processing/services/health.proto, blickfeld/percept_processing/services/pipeline.proto, blickfeld/percept_processing/services/point_cloud.proto, blickfeld/percept_processing/services/states.proto, blickfeld/percept_processing/services/volume_map.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 ...core_processing import data as __core_processing_data__
from ...percept_pipeline import data as __percept_pipeline_data__
from .. import 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 StatesStreamResponse(betterproto.Message):
    """
    A response for getting a stream of states messages from the running
    pipeline
    """

    states: "_data__.States" = betterproto.message_field(1)
    """The current states with the information detected in the scene."""


@dataclass(eq=False, repr=False)
class VolumeMapStreamRequest(betterproto.Message):
    """A request to receive a stream of state list messages"""

    zone_uuid: str = betterproto.string_field(2)
    """Volume zone uuid"""


@dataclass(eq=False, repr=False)
class VolumeMapStreamResponse(betterproto.Message):
    """
    A response for getting a stream of volume map messages from the running
    pipeline
    """

    volume_map: "_data__.VolumeMap" = betterproto.message_field(1)
    """The current volume map of the requested zone"""


@dataclass(eq=False, repr=False)
class PipelineStartRequest(betterproto.Message):
    """A request to start a headless pipeline."""

    pass


@dataclass(eq=False, repr=False)
class PipelineStartResponse(betterproto.Message):
    """
    A response to PipelineStartRequest that contains the list of available
    streams for the started pipeline.
    """

    data_types: List["_data__.DataType"] = betterproto.enum_field(1)
    """List of available streams"""


@dataclass(eq=False, repr=False)
class PipelineListAvailableDataResponse(betterproto.Message):
    """
    A response containing the list of the data types available for streaming in
    the running pipeline
    """

    data_types: List["_data__.DataType"] = betterproto.enum_field(1)
    """A list of the data types available for streaming"""


@dataclass(eq=False, repr=False)
class HealthWatchResponse(betterproto.Message):
    """
    A response for getting a stream of health messages about the pipeline
    """

    health: "_data__.Health" = betterproto.message_field(1)
    """
    The current health message with information about the state of the pipeline
    """


@dataclass(eq=False, repr=False)
class HealthGetResponse(betterproto.Message):
    """A response for getting an health message about the pipeline"""

    health: "_data__.Health" = betterproto.message_field(1)
    """
    The current health message with information about the state of the pipeline
    """


@dataclass(eq=False, repr=False)
class PointCloudStreamRequest(betterproto.Message):
    """
    A request to receive a stream of point cloud messages. Different point
    clouds can be streamed depending on the set fields: - combined point cloud
    (the full point cloud of all the available devices combined) in the map
    coordinate system - the foreground of the combined point cloud in the map
    coordinate system - the complete raw point cloud coming from one device,
    but only in map coordinate system.
    """

    point_cloud_type: "__percept_pipeline_data__.PointCloudType" = (
        betterproto.enum_field(1)
    )
    """The type of point cloud to stream"""

    coordinate_system: "__percept_pipeline_data__.CoordinateSystem" = (
        betterproto.enum_field(2)
    )
    """
    The coordinate system the point cloud should be expressed in (local or
    transformed/map)
    """

    fqdn: str = betterproto.string_field(3, group="point_cloud_source")
    """fqdn of the data source to get the point cloud from"""


@dataclass(eq=False, repr=False)
class PointCloudStreamResponse(betterproto.Message):
    """A response for getting a stream of point cloud messages"""

    point_cloud: "__core_processing_data__.Frame" = betterproto.message_field(1)
    """The required point cloud, based on the fields set in the request"""


class States(betterproto.ServiceStub):
    """
    An RPC service to request a stream of states messages. If a pipeline is
    already running, it will be used to stream the data. If no pipeline is
    running, it will be started first and then the stream will start. NOTE: in
    this second case, the pipeline will also be automatically stopped once
    there are no more clients requesting any stream type from the module.
    """

    async def async_stream(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["StatesStreamResponse"]:
        """A method to get a stream of states messages from the pipeline"""

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.percept_processing.services.States/Stream",
            request,
            StatesStreamResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def stream(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["StatesStreamResponse"]:
        """A method to get a stream of states messages from the pipeline"""

        loop = asyncio.get_event_loop()
        ait = self.async_stream(
            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 VolumeMap(betterproto.ServiceStub):
    """An RPC service to request a stream of volume map messages."""

    async def async_stream(
        self,
        *,
        zone_uuid: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["VolumeMapStreamResponse"]:
        """
        A method to get a stream of volume map messages of one volume zone from
        the pipeline
        """

        request = VolumeMapStreamRequest()
        request.zone_uuid = zone_uuid

        async for response in self._unary_stream(
            "/blickfeld.percept_processing.services.VolumeMap/Stream",
            request,
            VolumeMapStreamResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def stream(
        self,
        *,
        zone_uuid: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> Iterator["VolumeMapStreamResponse"]:
        """
        A method to get a stream of volume map messages of one volume zone from
        the pipeline
        """

        loop = asyncio.get_event_loop()
        ait = self.async_stream(
            zone_uuid=zone_uuid,
            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 Pipeline(betterproto.ServiceStub):
    """
    An RPC service to start and stop pipelines. Note that currently it is
    impossible to run more than one pipeline at the same time.
    """

    async def async_start(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PipelineStartResponse":
        """
        A method to start a headless pipeline. This means that a pipeline
        started with this method will only be stopped once the Stop method is
        explicitly called
        """

        request = PipelineStartRequest()

        return await self._unary_unary(
            "/blickfeld.percept_processing.services.Pipeline/Start",
            request,
            PipelineStartResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def start(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PipelineStartResponse":
        """
        A method to start a headless pipeline. This means that a pipeline
        started with this method will only be stopped once the Stop method is
        explicitly called
        """

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

    async def async_stop(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "betterproto_lib_google_protobuf.Empty":
        """
        A method to stop the running pipeline. This will force-stop the
        pipeline, no matter how the pipeline was created and no matter how many
        clients are streaming from it.
        """

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_processing.services.Pipeline/Stop",
            request,
            betterproto_lib_google_protobuf.Empty,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def stop(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "betterproto_lib_google_protobuf.Empty":
        """
        A method to stop the running pipeline. This will force-stop the
        pipeline, no matter how the pipeline was created and no matter how many
        clients are streaming from it.
        """

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

    async def async_list_available_data(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PipelineListAvailableDataResponse":
        """
        A method to get the list of the data streams available for the running
        pipeline
        """

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_processing.services.Pipeline/ListAvailableData",
            request,
            PipelineListAvailableDataResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def list_available_data(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PipelineListAvailableDataResponse":
        """
        A method to get the list of the data streams available for the running
        pipeline
        """

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


class Health(betterproto.ServiceStub):
    """
    An RPC service to request information about the state of the pipeline and
    of the module.
    """

    async def async_watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["HealthWatchResponse"]:
        """
        A method to get a stream of health messages, containing information
        about the state of the pipeline
        """

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.percept_processing.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"]:
        """
        A method to get a stream of health messages, containing information
        about the state of the pipeline
        """

        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":
        """
        A method to get one health message, containing information about the
        state of the pipeline
        """

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.percept_processing.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":
        """
        A method to get one health message, containing information about the
        state of the pipeline
        """

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


class PointCloud(betterproto.ServiceStub):
    """
    An RPC service to request a stream of point cloud messages. If a pipeline
    is already running, it will be used to stream the data. If no pipeline is
    running, it will be started first and then the stream will start. NOTE: in
    this second case, the pipeline will also be automatically stopped once the
    this second case, the pipeline will also be automatically stopped once
    there are no more clients requesting any stream type from the module.
    """

    async def async_stream(
        self,
        *,
        point_cloud_type: "__percept_pipeline_data__.PointCloudType" = 0,
        coordinate_system: "__percept_pipeline_data__.CoordinateSystem" = 0,
        fqdn: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["PointCloudStreamResponse"]:
        """
        A method to get a stream of point cloud messages from the pipeline. It
        is possible to stream different point clouds, depending on the fields
        set in the request
        """

        request = PointCloudStreamRequest()
        request.point_cloud_type = point_cloud_type
        request.coordinate_system = coordinate_system
        request.fqdn = fqdn

        async for response in self._unary_stream(
            "/blickfeld.percept_processing.services.PointCloud/Stream",
            request,
            PointCloudStreamResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def stream(
        self,
        *,
        point_cloud_type: "__percept_pipeline_data__.PointCloudType" = 0,
        coordinate_system: "__percept_pipeline_data__.CoordinateSystem" = 0,
        fqdn: str = "",
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> Iterator["PointCloudStreamResponse"]:
        """
        A method to get a stream of point cloud messages from the pipeline. It
        is possible to stream different point clouds, depending on the fields
        set in the request
        """

        loop = asyncio.get_event_loop()
        ait = self.async_stream(
            point_cloud_type=point_cloud_type,
            coordinate_system=coordinate_system,
            fqdn=fqdn,
            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
