"""
Binance Spot WebSocket API

OpenAPI Specifications for the Binance Spot WebSocket API

API documents:
  - [Github web-socket-api documentation file](https://github.com/binance/binance-spot-api-docs/blob/master/web-socket-api.md)
  - [General API information for web-socket-api on website](https://developers.binance.com/docs/binance-spot-api-docs/web-socket-api/general-api-information)

The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

from binance_common.models import WebsocketApiResponse
from binance_common.signature import Signers
from binance_common.websocket import WebSocketAPIBase

from ..models import SessionSubscriptionsResponse
from ..models import UserDataStreamSubscribeResponse
from ..models import UserDataStreamSubscribeSignatureResponse
from ..models import UserDataStreamUnsubscribeResponse


from typing import Optional


class UserDataStreamApi:
    """API Client for UserDataStreamApi endpoints."""

    def __init__(
        self,
        websocket_api: WebSocketAPIBase,
        signer: Signers = None,
    ) -> None:
        self.websocket_api = websocket_api
        self.signer = signer

    async def session_subscriptions(
        self,
        id: Optional[str] = None,
    ) -> WebsocketApiResponse[SessionSubscriptionsResponse]:
        """
            WebSocket Listing all subscriptions
            /session.subscriptions
            https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-Data-Stream-requests#listing-all-subscriptions


        Weight: 2

        **Data Source**:
        Memory

            Args:
                    id (Optional[str] = None): Unique WebSocket request ID.

            Returns:
                WebsocketApiResponse[SessionSubscriptionsResponse]

            Raises:
                RequiredError: If a required parameter is missing.

        """

        params = {
            **({"id": id} if id is not None else {}),
        }

        payload = {
            "method": "/session.subscriptions".replace("/", "", 1),
            "params": params,
        }

        return await self.websocket_api.send_message(
            payload=payload, response_model=SessionSubscriptionsResponse
        )

    async def user_data_stream_subscribe(
        self,
        id: Optional[str] = None,
    ) -> WebsocketApiResponse[UserDataStreamSubscribeResponse]:
        """
            WebSocket Subscribe to User Data Stream
            /userDataStream.subscribe
            https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-Data-Stream-requests#subscribe-to-user-data-stream-user_stream

            Subscribe to the User Data Stream in the current WebSocket connection.
        Weight: 2

            Args:
                    id (Optional[str] = None): Unique WebSocket request ID.

            Returns:
                WebsocketApiResponse[UserDataStreamSubscribeResponse]

            Raises:
                RequiredError: If a required parameter is missing.

        """

        params = {
            **({"id": id} if id is not None else {}),
        }

        payload = {
            "method": "/userDataStream.subscribe".replace("/", "", 1),
            "params": params,
        }

        return await self.websocket_api.send_message(
            payload=payload, response_model=UserDataStreamSubscribeResponse
        )

    async def user_data_stream_subscribe_signature(
        self,
        id: Optional[str] = None,
    ) -> WebsocketApiResponse[UserDataStreamSubscribeSignatureResponse]:
        """
            WebSocket Subscribe to User Data Stream through signature subscription
            /userDataStream.subscribe.signature
            https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-Data-Stream-requests#subscribe-to-user-data-stream-through-signature-subscription-user_stream


        Weight: 2

            Args:
                    id (Optional[str] = None): Unique WebSocket request ID.

            Returns:
                WebsocketApiResponse[UserDataStreamSubscribeSignatureResponse]

            Raises:
                RequiredError: If a required parameter is missing.

        """

        params = {
            **({"id": id} if id is not None else {}),
        }

        payload = {
            "method": "/userDataStream.subscribe.signature".replace("/", "", 1),
            "params": params,
        }

        return await self.websocket_api.send_signed_message(
            payload=payload,
            response_model=UserDataStreamSubscribeSignatureResponse,
            signer=self.signer,
        )

    async def user_data_stream_unsubscribe(
        self,
        id: Optional[str] = None,
        subscription_id: Optional[int] = None,
    ) -> WebsocketApiResponse[UserDataStreamUnsubscribeResponse]:
        """
            WebSocket Unsubscribe from User Data Stream
            /userDataStream.unsubscribe
            https://developers.binance.com/docs/binance-spot-api-docs/websocket-api/user-Data-Stream-requests#unsubscribe-from-user-data-stream

            Stop listening to the User Data Stream in the current WebSocket connection.

        Note that `session.logout` will only close the subscription created with `userdataStream.subscribe` but not subscriptions opened with `userDataStream.subscribe.signature`.
        Weight: 2

            Args:
                    id (Optional[str] = None): Unique WebSocket request ID.
                    subscription_id (Optional[int] = None): When called with no parameter, this will close all subscriptions. <br>When called with the `subscriptionId` parameter, this will attempt to close the subscription with that subscription id, if it exists.

            Returns:
                WebsocketApiResponse[UserDataStreamUnsubscribeResponse]

            Raises:
                RequiredError: If a required parameter is missing.

        """

        params = {
            **({"id": id} if id is not None else {}),
            **(
                {"subscription_id": subscription_id}
                if subscription_id is not None
                else {}
            ),
        }

        payload = {
            "method": "/userDataStream.unsubscribe".replace("/", "", 1),
            "params": params,
        }

        return await self.websocket_api.send_message(
            payload=payload, response_model=UserDataStreamUnsubscribeResponse
        )
