# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: blickfeld/core_processing/services/acceleration.proto, blickfeld/core_processing/services/health.proto, blickfeld/core_processing/services/point_cloud.proto
# plugin: python-betterproto
import asyncio
from dataclasses import dataclass
from typing import (
    TYPE_CHECKING,
    AsyncIterator,
    Dict,
    Iterator,
    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 AccelerationStreamResponse(betterproto.Message):
    """Stream response to acceleration stream request"""

    buffer: "_data__.AccelerationBuffer" = betterproto.message_field(1)
    """Buffer with acceleration"""


@dataclass(eq=False, repr=False)
class AccelerationGetFilteredResponse(betterproto.Message):
    """Response to acceleration get filtered request"""

    acceleration: "_data__.Acceleration" = betterproto.message_field(1)
    """Single filtered acceleration"""


@dataclass(eq=False, repr=False)
class PointCloudStreamResponse(betterproto.Message):
    """Stream response to point cloud stream request"""

    frame: "_data__.Frame" = betterproto.message_field(1)
    """Point cloud frame"""


@dataclass(eq=False, repr=False)
class PointCloudGetResponse(betterproto.Message):
    """Response to point cloud get request"""

    frame: "_data__.Frame" = betterproto.message_field(1)
    """Point cloud frame"""


@dataclass(eq=False, repr=False)
class PointCloudEnableDemoRequest(betterproto.Message):
    """Response to point cloud enable demo request"""

    recording: "_config__.DemoRecording" = betterproto.enum_field(1)
    """Select demo recording"""


@dataclass(eq=False, repr=False)
class HealthGetResponse(betterproto.Message):
    """Response to health get request"""

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


@dataclass(eq=False, repr=False)
class HealthWatchResponse(betterproto.Message):
    """Stream response to health watch request"""

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


class Acceleration(betterproto.ServiceStub):
    """
    The Acceleration Service provides access to the accelerometer of the
    device.
    """

    async def async_stream(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["AccelerationStreamResponse"]:
        """
        Streams raw data from accelerometer [WARNING] Raw data is acquired with
        a high sampling frequency and sent out in larger chunks. To estimate
        the static state of the device the GetFiltered method should be used.
        """

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.core_processing.services.Acceleration/Stream",
            request,
            AccelerationStreamResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def stream(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["AccelerationStreamResponse"]:
        """
        Streams raw data from accelerometer [WARNING] Raw data is acquired with
        a high sampling frequency and sent out in larger chunks. To estimate
        the static state of the device the GetFiltered method should be used.
        """

        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

    async def async_get_filtered(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "AccelerationGetFilteredResponse":
        """Get filtered sample from accelerometer"""

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.core_processing.services.Acceleration/GetFiltered",
            request,
            AccelerationGetFilteredResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def get_filtered(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "AccelerationGetFilteredResponse":
        """Get filtered sample from accelerometer"""

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


class PointCloud(betterproto.ServiceStub):
    """
    Point Cloud service for core point cloud stream. It is the direct result of
    the internal processing pipeline. The output is not post-processed further.
    The post-processed output can be retrieved from the percept-processing
    PointCloud service.
    """

    async def async_stream(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["PointCloudStreamResponse"]:
        """
        Stream a point cloud stream NOTE: This activates the sensor if it is
        currently idle.
        """

        request = betterproto_lib_google_protobuf.Empty()

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

    def stream(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["PointCloudStreamResponse"]:
        """
        Stream a point cloud stream NOTE: This activates the sensor if it is
        currently idle.
        """

        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

    async def async_get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PointCloudGetResponse":
        """
        Get a single point cloud NOTE: This activates the sensor if it is
        currently idle.
        """

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.core_processing.services.PointCloud/Get",
            request,
            PointCloudGetResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def get(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> "PointCloudGetResponse":
        """
        Get a single point cloud NOTE: This activates the sensor if it is
        currently idle.
        """

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

    async def async_enable_demo(
        self,
        *,
        recording: "_config__.DemoRecording" = 0,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Enable demo data set It will be re-played on Stream requests"""

        request = PointCloudEnableDemoRequest()
        request.recording = recording

        return await self._unary_unary(
            "/blickfeld.core_processing.services.PointCloud/EnableDemo",
            request,
            betterproto_lib_google_protobuf.Empty,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def enable_demo(
        self,
        *,
        recording: "_config__.DemoRecording" = 0,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "betterproto_lib_google_protobuf.Empty":
        """Enable demo data set It will be re-played on Stream requests"""

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


class Health(betterproto.ServiceStub):
    """
    The health service provides methods to monitor operational status of the
    core_processing module
    """

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

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.core_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":
        """Returns the current health status of the core_processing module"""

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

    async def async_watch(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["HealthWatchResponse"]:
        """
        Can be used to attach to the health monitoring status information of
        the core_processing module
        """

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.core_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"]:
        """
        Can be used to attach to the health monitoring status information of
        the core_processing module
        """

        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
