"""
Binance Spot WebSocket Streams

OpenAPI Specifications for the Binance Spot WebSocket Streams

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

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

Do not edit the class manually.
"""

from pydantic import BaseModel
from typing import Callable, Optional, TypeVar, Union

from binance_common.configuration import ConfigurationWebSocketStreams
from binance_common.websocket import (
    WebSocketStreamBase,
    WebSocketConnection,
    RequestStreamHandle,
)


from .streams.web_socket_streams_api import WebSocketStreamsApi


from .models import AllMarketRollingWindowTickerWindowSizeEnum
from .models import KlineIntervalEnum
from .models import KlineOffsetIntervalEnum
from .models import PartialBookDepthLevelsEnum
from .models import RollingWindowTickerWindowSizeEnum

T = TypeVar("T", bound=BaseModel)


class SpotWebSocketStreams(WebSocketStreamBase):
    def __init__(
        self,
        configuration: ConfigurationWebSocketStreams,
    ) -> None:

        super().__init__(configuration)
        self.configuration = configuration

        self._webSocketStreamsApi = WebSocketStreamsApi(self)

    async def ping_server(self, connection: WebSocketConnection):
        """Sends a ping message to the WebSocket server to check the connection status.

        Args:
            connection (WebSocketConnection): The WebSocket connection to send the ping message to.
        """

        if self.session:
            await super().ping_ws_stream(connection=connection)
        else:
            raise ValueError("WebSocket session is not initialized.")

    async def subscribe(self, streams, response_model: Optional[T] = None):
        """Subscribes to the specified WebSocket streams.

        Args:
            streams (list): A list of WebSocket streams to subscribe to.
            response_model (Optional[T]): The Pydantic model to validate the response against.
        """

        await super().subscribe(streams, response_model=response_model)

    async def unsubscribe(self, streams):
        """Unsubscribes from the specified WebSocket streams.

        Args:
            streams (list): A list of WebSocket streams to unsubscribe from.
        """

        await super().unsubscribe(streams)

    def on(self, event: str, callback: Callable[[T], None], stream: str):
        """Registers a callback function for a specific WebSocket event.

        Args:
            event (str): The event type to listen for (e.g., 'message', 'error').
            callback (Callable[[T], None]): The callback function to be called when the event occurs.
            stream (str): The specific WebSocket stream to listen to.
        """

        super().on(event, callback, stream)

    async def list_subscribe(self) -> dict:
        """Lists all currently subscribed WebSocket streams.

        Returns:
            dict: A dictionary containing the current subscriptions.
        """

        return await super().list_subscribe()

    async def close_connection(
        self, connection: WebSocketConnection = None, close_session: bool = True
    ):
        """Closes the WebSocket connection and optionally the session.

        Args:
            connection (WebSocketConnection, optional): The WebSocket connection to close. If None, the current session's connection is used.
            close_session (bool, optional): Whether to close the session after closing the connection. Defaults to True.
        """

        await super().close_connection(connection, close_session)

    async def agg_trade(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Aggregate Trade Streams

        The Aggregate Trade Streams push trade information that is aggregated for a single taker order.

        Args:
            symbol (Union[str, None]): Symbol to query
            id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.agg_trade(symbol, id)

    async def all_market_rolling_window_ticker(
        self,
        window_size: Union[AllMarketRollingWindowTickerWindowSizeEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
                WebSocket All Market Rolling Window Statistics Streams

                Rolling window ticker statistics for all market symbols, computed over multiple windows.
        Note that only tickers that have changed will be present in the array.

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

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.all_market_rolling_window_ticker(
            window_size, id
        )

    async def all_mini_ticker(
        self,
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket All Market Mini Tickers Stream

        24hr rolling window mini-ticker statistics for all symbols that changed in an array. These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs. Note that only tickers that have changed will be present in the array.

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

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.all_mini_ticker(id)

    async def avg_price(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Average Price

        Average price streams push changes in the average price over a fixed time interval.

        Args:
            symbol (Union[str, None]): Symbol to query
            id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.avg_price(symbol, id)

    async def book_ticker(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
                WebSocket Individual Symbol Book Ticker Streams

                Pushes any update to the best bid or ask's price or quantity in real-time for a specified symbol.
        Multiple `<symbol>@bookTicker` streams can be subscribed to over one connection.

                Args:
                    symbol (Union[str, None]): Symbol to query
                    id (Optional[str] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.book_ticker(symbol, id)

    async def diff_book_depth(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
        update_speed: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Diff. Depth Stream

        Order book price and quantity depth updates used to locally manage an order book.

        Args:
            symbol (Union[str, None]): Symbol to query
            id (Optional[str] = None): Unique WebSocket request ID.
            update_speed (Optional[str] = None): 1000ms or 100ms

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.diff_book_depth(symbol, id, update_speed)

    async def kline(
        self,
        symbol: Union[str, None],
        interval: Union[KlineIntervalEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
                WebSocket Kline/Candlestick Streams for UTC

                The Kline/Candlestick Stream push updates to the current klines/candlestick every second in `UTC+0` timezone

        <a id="kline-intervals"></a>

                Args:
                    symbol (Union[str, None]): Symbol to query
                    interval (Union[KlineIntervalEnum, None]):
                    id (Optional[str] = None): Unique WebSocket request ID.

                Returns:
                    RequestStreamHandle

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.kline(symbol, interval, id)

    async def kline_offset(
        self,
        symbol: Union[str, None],
        interval: Union[KlineOffsetIntervalEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Kline/Candlestick Streams with timezone offset

        The Kline/Candlestick Stream push updates to the current klines/candlestick every second in `UTC+8` timezone

        Args:
            symbol (Union[str, None]): Symbol to query
            interval (Union[KlineOffsetIntervalEnum, None]):
            id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.kline_offset(symbol, interval, id)

    async def mini_ticker(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Individual Symbol Mini Ticker Stream

        24hr rolling window mini-ticker statistics. These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.

        Args:
            symbol (Union[str, None]): Symbol to query
            id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.mini_ticker(symbol, id)

    async def partial_book_depth(
        self,
        symbol: Union[str, None],
        levels: Union[PartialBookDepthLevelsEnum, None],
        id: Optional[str] = None,
        update_speed: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Partial Book Depth Streams

        Top **\<levels\>** bids and asks, pushed every second. Valid **\<levels\>** are 5, 10, or 20.

        Args:
            symbol (Union[str, None]): Symbol to query
            levels (Union[PartialBookDepthLevelsEnum, None]):
            id (Optional[str] = None): Unique WebSocket request ID.
            update_speed (Optional[str] = None): 1000ms or 100ms

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.partial_book_depth(
            symbol, levels, id, update_speed
        )

    async def rolling_window_ticker(
        self,
        symbol: Union[str, None],
        window_size: Union[RollingWindowTickerWindowSizeEnum, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Individual Symbol Rolling Window Statistics Streams

        Rolling window ticker statistics for a single symbol, computed over multiple windows.

        Args:
            symbol (Union[str, None]): Symbol to query
            window_size (Union[RollingWindowTickerWindowSizeEnum, None]):
            id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.rolling_window_ticker(
            symbol, window_size, id
        )

    async def ticker(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Individual Symbol Ticker Streams

        24hr rolling window ticker statistics for a single symbol. These are NOT the statistics of the UTC day, but a 24hr rolling window for the previous 24hrs.

        Args:
            symbol (Union[str, None]): Symbol to query
            id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.ticker(symbol, id)

    async def trade(
        self,
        symbol: Union[str, None],
        id: Optional[str] = None,
    ) -> RequestStreamHandle:
        r"""
        WebSocket Trade Streams

        The Trade Streams push raw trade information; each trade has a unique buyer and seller.

        Args:
            symbol (Union[str, None]): Symbol to query
            id (Optional[str] = None): Unique WebSocket request ID.

        Returns:
            RequestStreamHandle

        Raises:
            RequiredError: If a required parameter is missing.

        """

        return await self._webSocketStreamsApi.trade(symbol, id)
