

# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: blickfeld/diagnostics/services/health.proto, blickfeld/diagnostics/services/log.proto, blickfeld/diagnostics/services/report.proto, blickfeld/diagnostics/services/self_test.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 HealthGetResponse(betterproto.Message):
    """Response to health get request."""

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


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

    health: "_data__.Health" = betterproto.message_field(2)
    """Aggregated health"""


@dataclass(eq=False, repr=False)
class LogStreamRequest(betterproto.Message):
    """Stream request"""

    cursor: "_data__.LogEntryCursor" = betterproto.message_field(1)
    """
    The cursor pointing to the log entry from which to start the stream from.
    This field is optional. If it is not set the stream will start from the
    tail of the journal.   NOTE: To be able to set this field and to specify a
    valid start position in the journal, first, a valid cursor needs to be
    received via the response to this request. Further requests can then stream
    relatively to the received cursor.
    """

    time_direction: "_config__.LogTimeDirection" = betterproto.enum_field(2)
    """
    The streaming direction is used to specify if the service should stream the
    log entries towards older or more recent messages: i.e. backward or forward
    in time. This way, the client can either continuously fetch log messages
    one-by-one from the most recent to the oldest or wait for the occurrence of
    new log entires.
    """


@dataclass(eq=False, repr=False)
class LogStreamResponse(betterproto.Message):
    """Stream response"""

    entry: "_data__.LogEntry" = betterproto.message_field(1)
    """The requested log entry."""


@dataclass(eq=False, repr=False)
class ReportGenerateResponse(betterproto.Message):
    """Stream of the encrypted report in chunks of binary data."""

    binary_chunk: bytes = betterproto.bytes_field(1)
    """Binary chunk of the diagnostics report."""


@dataclass(eq=False, repr=False)
class SelfTestRunRequest(betterproto.Message):
    """The self test run can be configured with this request"""

    self_tests: List["_config__.SelfTest"] = betterproto.enum_field(1)
    """
    Specify self tests which should be executed. If not set, the default set
    will be executed.
    """


@dataclass(eq=False, repr=False)
class SelfTestRunResponse(betterproto.Message):
    """
    The response provides the self test report.   [NOTE] The method will not
    throw an exception on API level if tests failed or have warnings. The
    success flag in the report must be checked.
    """

    report: "_data__.SelfTestReport" = betterproto.message_field(1)
    """Test report"""


class Health(betterproto.ServiceStub):
    """
    This service provides the aggregated health state information of all Qb2
    software modules (only state and state reason are included). Service can be
    used to get an instant overview of the overall Qb2 device health.
    """

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

        request = betterproto_lib_google_protobuf.Empty()

        return await self._unary_unary(
            "/blickfeld.diagnostics.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 aggregated health status of Qb2 software modules.
        """

        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"]:
        """
        Returns the aggregated health status stream of Qb2 software modules.
        """

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.diagnostics.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"]:
        """
        Returns the aggregated health status stream of Qb2 software modules.
        """

        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 Log(betterproto.ServiceStub):
    """
    The Log service provides methods to access the logs of selected software
    modules running on the device. Via this service, the client is able to
    monitor events that happen on the device during operation. This allows to
    asses the state of the device or to have additional information if the
    sensor is in a failed state.
    """

    async def async_stream(
        self,
        *,
        cursor: "_data__.LogEntryCursor" = None,
        time_direction: "_config__.LogTimeDirection" = 0,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> AsyncIterator["LogStreamResponse"]:
        """
        Is used to request a stream of log entries from the logs of the device.
        """

        request = LogStreamRequest()
        if cursor is not None:
            request.cursor = cursor
        request.time_direction = time_direction

        async for response in self._unary_stream(
            "/blickfeld.diagnostics.services.Log/Stream",
            request,
            LogStreamResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def stream(
        self,
        *,
        cursor: "_data__.LogEntryCursor" = None,
        time_direction: "_config__.LogTimeDirection" = 0,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> Iterator["LogStreamResponse"]:
        """
        Is used to request a stream of log entries from the logs of the device.
        """

        loop = asyncio.get_event_loop()
        ait = self.async_stream(
            cursor=cursor,
            time_direction=time_direction,
            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 Report(betterproto.ServiceStub):
    """
    The Report service generates an encrypted diagnostics report containing
    information about the state and health information of the Qb2 device.
    """

    async def async_generate(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> AsyncIterator["ReportGenerateResponse"]:
        """Returns a stream of the report's binary chunks."""

        request = betterproto_lib_google_protobuf.Empty()

        async for response in self._unary_stream(
            "/blickfeld.diagnostics.services.Report/Generate",
            request,
            ReportGenerateResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        ):
            yield response

    def generate(
        self,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None,
    ) -> Iterator["ReportGenerateResponse"]:
        """Returns a stream of the report's binary chunks."""

        loop = asyncio.get_event_loop()
        ait = self.async_generate(
            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 SelfTest(betterproto.ServiceStub):
    """
    The SelfTest service offers methods to trigger test routines. The routines
    focus on automatic self tests without user interaction. The reports give an
    indication what the potential root cause for an found issue could be.
    """

    async def async_run(
        self,
        *,
        self_tests: Optional[List["_config__.SelfTest"]] = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "SelfTestRunResponse":
        """This triggers the default test case routine"""

        self_tests = self_tests or []

        request = SelfTestRunRequest()
        request.self_tests = self_tests

        return await self._unary_unary(
            "/blickfeld.diagnostics.services.SelfTest/Run",
            request,
            SelfTestRunResponse,
            timeout=timeout,
            deadline=deadline,
            metadata=metadata,
        )

    def run(
        self,
        *,
        self_tests: Optional[List["_config__.SelfTest"]] = None,
        timeout: Optional[float] = None,
        deadline: Optional["Deadline"] = None,
        metadata: Optional["MetadataLike"] = None
    ) -> "SelfTestRunResponse":
        """This triggers the default test case routine"""

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