# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: api/synerex.proto
# plugin: python-betterproto
from dataclasses import dataclass
from datetime import datetime, timedelta
from typing import AsyncGenerator, List, Optional

import betterproto
import grpclib


class GatewayType(betterproto.Enum):
    BIDIRECTIONAL = 0
    WRITE_ONLY = 1
    READ_ONLY = 2


class MsgType(betterproto.Enum):
    DEMAND = 0
    SUPPLY = 1
    TARGET = 2
    MBUS = 3
    MBUSMSG = 4


@dataclass
class Response(betterproto.Message):
    ok: bool = betterproto.bool_field(1)
    err: str = betterproto.string_field(2)


@dataclass
class ConfirmResponse(betterproto.Message):
    ok: bool = betterproto.bool_field(1)
    mbus_id: float = betterproto.fixed64_field(2)
    wait: timedelta = betterproto.message_field(3)
    err: str = betterproto.string_field(4)


@dataclass
class Content(betterproto.Message):
    entity: bytes = betterproto.bytes_field(1)


@dataclass
class Supply(betterproto.Message):
    id: float = betterproto.fixed64_field(1)
    sender_id: float = betterproto.fixed64_field(2)
    target_id: float = betterproto.fixed64_field(3)
    channel_type: int = betterproto.uint32_field(4)
    supply_name: str = betterproto.string_field(5)
    ts: datetime = betterproto.message_field(6)
    arg_json: str = betterproto.string_field(7)
    mbus_id: float = betterproto.fixed64_field(8)
    cdata: "Content" = betterproto.message_field(9)


@dataclass
class Demand(betterproto.Message):
    id: float = betterproto.fixed64_field(1)
    sender_id: float = betterproto.fixed64_field(2)
    target_id: float = betterproto.fixed64_field(3)
    channel_type: int = betterproto.uint32_field(4)
    demand_name: str = betterproto.string_field(5)
    ts: datetime = betterproto.message_field(6)
    arg_json: str = betterproto.string_field(7)
    mbus_id: float = betterproto.fixed64_field(8)
    cdata: "Content" = betterproto.message_field(9)


@dataclass
class Target(betterproto.Message):
    id: float = betterproto.fixed64_field(1)
    sender_id: float = betterproto.fixed64_field(2)
    target_id: float = betterproto.fixed64_field(3)
    channel_type: int = betterproto.uint32_field(4)
    wait: timedelta = betterproto.message_field(5)
    mbus_id: float = betterproto.fixed64_field(6)


@dataclass
class Channel(betterproto.Message):
    client_id: float = betterproto.fixed64_field(1)
    channel_type: int = betterproto.uint32_field(2)
    arg_json: str = betterproto.string_field(3)


@dataclass
class Mbus(betterproto.Message):
    client_id: float = betterproto.fixed64_field(1)
    mbus_id: float = betterproto.fixed64_field(2)
    arg_json: str = betterproto.string_field(3)


@dataclass
class MbusMsg(betterproto.Message):
    msg_id: float = betterproto.fixed64_field(1)
    sender_id: float = betterproto.fixed64_field(2)
    target_id: float = betterproto.fixed64_field(3)
    mbus_id: float = betterproto.fixed64_field(4)
    msg_type: int = betterproto.uint32_field(5)
    msg_info: str = betterproto.string_field(6)
    arg_json: str = betterproto.string_field(7)


@dataclass
class GatewayInfo(betterproto.Message):
    client_id: float = betterproto.fixed64_field(1)
    gateway_type: "GatewayType" = betterproto.enum_field(2)
    channels: List[int] = betterproto.uint32_field(3)


@dataclass
class GatewayMsg(betterproto.Message):
    """Subscribe from Gateway to SynerexServer"""

    src_synerex_id: float = betterproto.fixed64_field(1)
    msg_type: "MsgType" = betterproto.enum_field(2)
    demand: "Demand" = betterproto.message_field(3, group="msg_oneof")
    supply: "Supply" = betterproto.message_field(4, group="msg_oneof")
    target: "Target" = betterproto.message_field(5, group="msg_oneof")
    mbus: "Mbus" = betterproto.message_field(6, group="msg_oneof")
    mbus_msg: "MbusMsg" = betterproto.message_field(7, group="msg_oneof")


@dataclass
class ProviderID(betterproto.Message):
    client_id: float = betterproto.fixed64_field(1)
    arg_json: str = betterproto.string_field(3)


class SynerexStub(betterproto.ServiceStub):
    async def notify_demand(
        self,
        *,
        id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        channel_type: int = 0,
        demand_name: str = "",
        ts: Optional[datetime] = None,
        arg_json: str = "",
        mbus_id: float = 0,
        cdata: Optional["Content"] = None,
    ) -> Response:
        request = Demand()
        request.id = id
        request.sender_id = sender_id
        request.target_id = target_id
        request.channel_type = channel_type
        request.demand_name = demand_name
        if ts is not None:
            request.ts = ts
        request.arg_json = arg_json
        request.mbus_id = mbus_id
        if cdata is not None:
            request.cdata = cdata

        return await self._unary_unary("/api.Synerex/NotifyDemand", request, Response,)

    async def notify_supply(
        self,
        *,
        id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        channel_type: int = 0,
        supply_name: str = "",
        ts: Optional[datetime] = None,
        arg_json: str = "",
        mbus_id: float = 0,
        cdata: Optional["Content"] = None,
    ) -> Response:
        request = Supply()
        request.id = id
        request.sender_id = sender_id
        request.target_id = target_id
        request.channel_type = channel_type
        request.supply_name = supply_name
        if ts is not None:
            request.ts = ts
        request.arg_json = arg_json
        request.mbus_id = mbus_id
        if cdata is not None:
            request.cdata = cdata

        return await self._unary_unary("/api.Synerex/NotifySupply", request, Response,)

    async def propose_demand(
        self,
        *,
        id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        channel_type: int = 0,
        demand_name: str = "",
        ts: Optional[datetime] = None,
        arg_json: str = "",
        mbus_id: float = 0,
        cdata: Optional["Content"] = None,
    ) -> Response:
        request = Demand()
        request.id = id
        request.sender_id = sender_id
        request.target_id = target_id
        request.channel_type = channel_type
        request.demand_name = demand_name
        if ts is not None:
            request.ts = ts
        request.arg_json = arg_json
        request.mbus_id = mbus_id
        if cdata is not None:
            request.cdata = cdata

        return await self._unary_unary("/api.Synerex/ProposeDemand", request, Response,)

    async def propose_supply(
        self,
        *,
        id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        channel_type: int = 0,
        supply_name: str = "",
        ts: Optional[datetime] = None,
        arg_json: str = "",
        mbus_id: float = 0,
        cdata: Optional["Content"] = None,
    ) -> Response:
        request = Supply()
        request.id = id
        request.sender_id = sender_id
        request.target_id = target_id
        request.channel_type = channel_type
        request.supply_name = supply_name
        if ts is not None:
            request.ts = ts
        request.arg_json = arg_json
        request.mbus_id = mbus_id
        if cdata is not None:
            request.cdata = cdata

        return await self._unary_unary("/api.Synerex/ProposeSupply", request, Response,)

    async def select_supply(
        self,
        *,
        id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        channel_type: int = 0,
        wait: Optional[timedelta] = None,
        mbus_id: float = 0,
    ) -> ConfirmResponse:
        request = Target()
        request.id = id
        request.sender_id = sender_id
        request.target_id = target_id
        request.channel_type = channel_type
        if wait is not None:
            request.wait = wait
        request.mbus_id = mbus_id

        return await self._unary_unary(
            "/api.Synerex/SelectSupply", request, ConfirmResponse,
        )

    async def select_demand(
        self,
        *,
        id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        channel_type: int = 0,
        wait: Optional[timedelta] = None,
        mbus_id: float = 0,
    ) -> ConfirmResponse:
        request = Target()
        request.id = id
        request.sender_id = sender_id
        request.target_id = target_id
        request.channel_type = channel_type
        if wait is not None:
            request.wait = wait
        request.mbus_id = mbus_id

        return await self._unary_unary(
            "/api.Synerex/SelectDemand", request, ConfirmResponse,
        )

    async def confirm(
        self,
        *,
        id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        channel_type: int = 0,
        wait: Optional[timedelta] = None,
        mbus_id: float = 0,
    ) -> Response:
        request = Target()
        request.id = id
        request.sender_id = sender_id
        request.target_id = target_id
        request.channel_type = channel_type
        if wait is not None:
            request.wait = wait
        request.mbus_id = mbus_id

        return await self._unary_unary("/api.Synerex/Confirm", request, Response,)

    async def subscribe_demand(
        self, *, client_id: float = 0, channel_type: int = 0, arg_json: str = ""
    ) -> AsyncGenerator[Demand, None]:
        request = Channel()
        request.client_id = client_id
        request.channel_type = channel_type
        request.arg_json = arg_json

        async for response in self._unary_stream(
            "/api.Synerex/SubscribeDemand", request, Demand,
        ):
            yield response

    async def subscribe_supply(
        self, *, client_id: float = 0, channel_type: int = 0, arg_json: str = ""
    ) -> AsyncGenerator[Supply, None]:
        request = Channel()
        request.client_id = client_id
        request.channel_type = channel_type
        request.arg_json = arg_json

        async for response in self._unary_stream(
            "/api.Synerex/SubscribeSupply", request, Supply,
        ):
            yield response

    async def subscribe_mbus(
        self, *, client_id: float = 0, mbus_id: float = 0, arg_json: str = ""
    ) -> AsyncGenerator[MbusMsg, None]:
        request = Mbus()
        request.client_id = client_id
        request.mbus_id = mbus_id
        request.arg_json = arg_json

        async for response in self._unary_stream(
            "/api.Synerex/SubscribeMbus", request, MbusMsg,
        ):
            yield response

    async def send_msg(
        self,
        *,
        msg_id: float = 0,
        sender_id: float = 0,
        target_id: float = 0,
        mbus_id: float = 0,
        msg_type: int = 0,
        msg_info: str = "",
        arg_json: str = "",
    ) -> Response:
        request = MbusMsg()
        request.msg_id = msg_id
        request.sender_id = sender_id
        request.target_id = target_id
        request.mbus_id = mbus_id
        request.msg_type = msg_type
        request.msg_info = msg_info
        request.arg_json = arg_json

        return await self._unary_unary("/api.Synerex/SendMsg", request, Response,)

    async def close_mbus(
        self, *, client_id: float = 0, mbus_id: float = 0, arg_json: str = ""
    ) -> Response:
        request = Mbus()
        request.client_id = client_id
        request.mbus_id = mbus_id
        request.arg_json = arg_json

        return await self._unary_unary("/api.Synerex/CloseMbus", request, Response,)

    async def subscribe_gateway(
        self,
        *,
        client_id: float = 0,
        gateway_type: "GatewayType" = 0,
        channels: List[int] = [],
    ) -> AsyncGenerator[GatewayMsg, None]:
        request = GatewayInfo()
        request.client_id = client_id
        request.gateway_type = gateway_type
        request.channels = channels

        async for response in self._unary_stream(
            "/api.Synerex/SubscribeGateway", request, GatewayMsg,
        ):
            yield response

    async def forward_to_gateway(
        self,
        *,
        src_synerex_id: float = 0,
        msg_type: "MsgType" = 0,
        demand: Optional["Demand"] = None,
        supply: Optional["Supply"] = None,
        target: Optional["Target"] = None,
        mbus: Optional["Mbus"] = None,
        mbus_msg: Optional["MbusMsg"] = None,
    ) -> Response:
        request = GatewayMsg()
        request.src_synerex_id = src_synerex_id
        request.msg_type = msg_type
        if demand is not None:
            request.demand = demand
        if supply is not None:
            request.supply = supply
        if target is not None:
            request.target = target
        if mbus is not None:
            request.mbus = mbus
        if mbus_msg is not None:
            request.mbus_msg = mbus_msg

        return await self._unary_unary(
            "/api.Synerex/ForwardToGateway", request, Response,
        )

    async def close_demand_channel(
        self, *, client_id: float = 0, channel_type: int = 0, arg_json: str = ""
    ) -> Response:
        request = Channel()
        request.client_id = client_id
        request.channel_type = channel_type
        request.arg_json = arg_json

        return await self._unary_unary(
            "/api.Synerex/CloseDemandChannel", request, Response,
        )

    async def close_supply_channel(
        self, *, client_id: float = 0, channel_type: int = 0, arg_json: str = ""
    ) -> Response:
        request = Channel()
        request.client_id = client_id
        request.channel_type = channel_type
        request.arg_json = arg_json

        return await self._unary_unary(
            "/api.Synerex/CloseSupplyChannel", request, Response,
        )

    async def close_all_channels(
        self, *, client_id: float = 0, arg_json: str = ""
    ) -> Response:
        request = ProviderID()
        request.client_id = client_id
        request.arg_json = arg_json

        return await self._unary_unary(
            "/api.Synerex/CloseAllChannels", request, Response,
        )
