# coding: utf-8

"""
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 __future__ import annotations
import json
import pprint
from pydantic import (
    BaseModel,
    ConfigDict,
    ValidationError,
)
from typing import Any, Optional
from binance_sdk_spot.websocket_api.models.balance_update import BalanceUpdate
from binance_sdk_spot.websocket_api.models.event_stream_terminated import (
    EventStreamTerminated,
)
from binance_sdk_spot.websocket_api.models.execution_report import ExecutionReport
from binance_sdk_spot.websocket_api.models.external_lock_update import (
    ExternalLockUpdate,
)
from binance_sdk_spot.websocket_api.models.list_status import ListStatus
from binance_sdk_spot.websocket_api.models.outbound_account_position import (
    OutboundAccountPosition,
)
from typing import Union, Set, Dict
from typing_extensions import Self

USERDATASTREAMEVENTSRESPONSE_ONE_OF_SCHEMAS = [
    "BalanceUpdate",
    "EventStreamTerminated",
    "ExecutionReport",
    "ExternalLockUpdate",
    "ListStatus",
    "OutboundAccountPosition",
]


class UserDataStreamEventsResponse(BaseModel):
    """
    UserDataStreamEventsResponse
    """

    # data type: OutboundAccountPosition
    oneof_schema_1_validator: Optional[OutboundAccountPosition] = None
    # data type: BalanceUpdate
    oneof_schema_2_validator: Optional[BalanceUpdate] = None
    # data type: ExecutionReport
    oneof_schema_3_validator: Optional[ExecutionReport] = None
    # data type: ListStatus
    oneof_schema_4_validator: Optional[ListStatus] = None
    # data type: EventStreamTerminated
    oneof_schema_5_validator: Optional[EventStreamTerminated] = None
    # data type: ExternalLockUpdate
    oneof_schema_6_validator: Optional[ExternalLockUpdate] = None
    actual_instance: Optional[
        Union[
            OutboundAccountPosition,
            BalanceUpdate,
            ExecutionReport,
            ListStatus,
            EventStreamTerminated,
            ExternalLockUpdate,
        ]
    ] = None
    one_of_schemas: Set[str] = {
        "BalanceUpdate",
        "EventStreamTerminated",
        "ExecutionReport",
        "ExternalLockUpdate",
        "ListStatus",
        "OutboundAccountPosition",
    }

    model_config = ConfigDict(
        validate_assignment=True,
        protected_namespaces=(),
    )

    discriminator_value_class_map: Dict[str, str] = {}

    def __init__(self, *args, **kwargs) -> None:
        if args:
            if len(args) > 1:
                raise ValueError(
                    "If a position argument is used, only 1 is allowed to set `actual_instance`"
                )
            if kwargs:
                raise ValueError(
                    "If a position argument is used, keyword arguments cannot be used."
                )
            super().__init__(actual_instance=args[0])
        else:
            super().__init__(**kwargs)

    @classmethod
    def is_oneof_model(cls) -> bool:
        return True

    @classmethod
    def from_dict(cls, parsed) -> Self:
        """Returns the object represented by the json string"""
        instance = cls.model_construct()
        error_messages = []
        match = 0

        is_list = isinstance(parsed, list)

        # deserialize data into OutboundAccountPosition
        if is_list == OutboundAccountPosition.is_array():
            try:
                instance.actual_instance = OutboundAccountPosition.from_dict(parsed)
                match += 1
            except (ValidationError, ValueError) as e:
                error_messages.append(str(e))
        # deserialize data into BalanceUpdate
        if is_list == BalanceUpdate.is_array():
            try:
                instance.actual_instance = BalanceUpdate.from_dict(parsed)
                match += 1
            except (ValidationError, ValueError) as e:
                error_messages.append(str(e))
        # deserialize data into ExecutionReport
        if is_list == ExecutionReport.is_array():
            try:
                instance.actual_instance = ExecutionReport.from_dict(parsed)
                match += 1
            except (ValidationError, ValueError) as e:
                error_messages.append(str(e))
        # deserialize data into ListStatus
        if is_list == ListStatus.is_array():
            try:
                instance.actual_instance = ListStatus.from_dict(parsed)
                match += 1
            except (ValidationError, ValueError) as e:
                error_messages.append(str(e))
        # deserialize data into EventStreamTerminated
        if is_list == EventStreamTerminated.is_array():
            try:
                instance.actual_instance = EventStreamTerminated.from_dict(parsed)
                match += 1
            except (ValidationError, ValueError) as e:
                error_messages.append(str(e))
        # deserialize data into ExternalLockUpdate
        if is_list == ExternalLockUpdate.is_array():
            try:
                instance.actual_instance = ExternalLockUpdate.from_dict(parsed)
                match += 1
            except (ValidationError, ValueError) as e:
                error_messages.append(str(e))

        if match > 1:
            # more than 1 match
            raise ValueError(
                "Multiple matches found when deserializing the JSON string into UserDataStreamEventsResponse with oneOf schemas: BalanceUpdate, EventStreamTerminated, ExecutionReport, ExternalLockUpdate, ListStatus, OutboundAccountPosition. Details: "
                + ", ".join(error_messages)
            )
        elif match == 0:
            # no match
            raise ValueError(
                "No match found when deserializing the JSON string into UserDataStreamEventsResponse with oneOf schemas: BalanceUpdate, EventStreamTerminated, ExecutionReport, ExternalLockUpdate, ListStatus, OutboundAccountPosition. Details: "
                + ", ".join(error_messages)
            )
        else:
            return instance

    def to_json(self) -> str:
        """Returns the JSON representation of the actual instance"""
        if self.actual_instance is None:
            return "null"

        if hasattr(self.actual_instance, "to_json") and callable(
            self.actual_instance.to_json
        ):
            return self.actual_instance.to_json()
        else:
            return json.dumps(self.actual_instance)

    def to_dict(
        self,
    ) -> Optional[
        Union[
            Dict[str, Any],
            BalanceUpdate,
            EventStreamTerminated,
            ExecutionReport,
            ExternalLockUpdate,
            ListStatus,
            OutboundAccountPosition,
        ]
    ]:
        """Returns the dict representation of the actual instance"""
        if self.actual_instance is None:
            return None

        if hasattr(self.actual_instance, "to_dict") and callable(
            self.actual_instance.to_dict
        ):
            return self.actual_instance.to_dict()
        else:
            # primitive type
            return self.actual_instance

    def to_str(self) -> str:
        """Returns the string representation of the actual instance"""
        return pprint.pformat(self.model_dump())
