# coding: utf-8

"""
    Event Detection API

    Event detection occurs when ThousandEyes identifies that error signals related to a component (proxy, network node, AS, server etc) have deviated from the baselines established by events. * To determine this, ThousandEyes takes the test results from all accounts groups within an organization, and analyzes that data. * Noisy test results (those that have too many errors in a short window) are removed until they stabilize, and the rest of the results are tagged with the components associated with that test result (for example, proxy, network, or server). * Next, any increase in failures from the test results and each component helps in determining the problem domain and which component may be at fault. * When this failure rate increases beyond a pre-defined threshold (set by the algorithm), an event is triggered and an email notification is sent to the user (if they've enabled email alerts).  With the Events API, you can perform the following tasks on the ThousandEyes platform: * **Retrieve Events**: Obtain a list of events and detailed information for each event. For more information about events, see [Event Detection](https://docs.thousandeyes.com/product-documentation/event-detection). 

    Generated by OpenAPI Generator (https://openapi-generator.tech)

    Do not edit the class manually.
"""  # noqa: E501


from __future__ import annotations
import json
import pprint
from pydantic import BaseModel, ConfigDict, Field, StrictStr, ValidationError, field_validator
from typing import Any, List, Optional
from thousandeyes_sdk.event_detection.models.agent_local_event_detail import AgentLocalEventDetail
from thousandeyes_sdk.event_detection.models.dns_event_detail import DnsEventDetail
from thousandeyes_sdk.event_detection.models.network_event_detail import NetworkEventDetail
from thousandeyes_sdk.event_detection.models.network_pop_event_detail import NetworkPopEventDetail
from thousandeyes_sdk.event_detection.models.proxy_event_detail import ProxyEventDetail
from thousandeyes_sdk.event_detection.models.target_event_detail import TargetEventDetail
from thousandeyes_sdk.event_detection.models.target_network_event_detail import TargetNetworkEventDetail
from pydantic import StrictStr, Field, model_serializer
from typing import Union, List, Set, Optional, Dict
from typing_extensions import Literal, Self

EVENTDETAIL_ONE_OF_SCHEMAS = ["AgentLocalEventDetail", "DnsEventDetail", "NetworkEventDetail", "NetworkPopEventDetail", "ProxyEventDetail", "TargetEventDetail", "TargetNetworkEventDetail"]

class EventDetail(BaseModel):
    """
    EventDetail
    """
    # data type: TargetEventDetail
    oneof_schema_1_validator: Optional[TargetEventDetail] = None
    # data type: TargetNetworkEventDetail
    oneof_schema_2_validator: Optional[TargetNetworkEventDetail] = None
    # data type: ProxyEventDetail
    oneof_schema_3_validator: Optional[ProxyEventDetail] = None
    # data type: DnsEventDetail
    oneof_schema_4_validator: Optional[DnsEventDetail] = None
    # data type: AgentLocalEventDetail
    oneof_schema_5_validator: Optional[AgentLocalEventDetail] = None
    # data type: NetworkEventDetail
    oneof_schema_6_validator: Optional[NetworkEventDetail] = None
    # data type: NetworkPopEventDetail
    oneof_schema_7_validator: Optional[NetworkPopEventDetail] = None
    actual_instance: Optional[Union[AgentLocalEventDetail, DnsEventDetail, NetworkEventDetail, NetworkPopEventDetail, ProxyEventDetail, TargetEventDetail, TargetNetworkEventDetail]] = None
    one_of_schemas: Set[str] = { "AgentLocalEventDetail", "DnsEventDetail", "NetworkEventDetail", "NetworkPopEventDetail", "ProxyEventDetail", "TargetEventDetail", "TargetNetworkEventDetail" }

    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)

    @field_validator('actual_instance')
    def actual_instance_must_validate_oneof(cls, v):
        instance = EventDetail.model_construct()
        error_messages = []
        match = 0
        # validate data type: TargetEventDetail
        if not isinstance(v, TargetEventDetail):
            error_messages.append(f"Error! Input type `{type(v)}` is not `TargetEventDetail`")
        else:
            match += 1
        # validate data type: TargetNetworkEventDetail
        if not isinstance(v, TargetNetworkEventDetail):
            error_messages.append(f"Error! Input type `{type(v)}` is not `TargetNetworkEventDetail`")
        else:
            match += 1
        # validate data type: ProxyEventDetail
        if not isinstance(v, ProxyEventDetail):
            error_messages.append(f"Error! Input type `{type(v)}` is not `ProxyEventDetail`")
        else:
            match += 1
        # validate data type: DnsEventDetail
        if not isinstance(v, DnsEventDetail):
            error_messages.append(f"Error! Input type `{type(v)}` is not `DnsEventDetail`")
        else:
            match += 1
        # validate data type: AgentLocalEventDetail
        if not isinstance(v, AgentLocalEventDetail):
            error_messages.append(f"Error! Input type `{type(v)}` is not `AgentLocalEventDetail`")
        else:
            match += 1
        # validate data type: NetworkEventDetail
        if not isinstance(v, NetworkEventDetail):
            error_messages.append(f"Error! Input type `{type(v)}` is not `NetworkEventDetail`")
        else:
            match += 1
        # validate data type: NetworkPopEventDetail
        if not isinstance(v, NetworkPopEventDetail):
            error_messages.append(f"Error! Input type `{type(v)}` is not `NetworkPopEventDetail`")
        else:
            match += 1
        if match > 1:
            # more than 1 match
            raise ValueError("Multiple matches found when setting `actual_instance` in EventDetail with oneOf schemas: AgentLocalEventDetail, DnsEventDetail, NetworkEventDetail, NetworkPopEventDetail, ProxyEventDetail, TargetEventDetail, TargetNetworkEventDetail. Details: " + ", ".join(error_messages))
        elif match == 0:
            # no match
            raise ValueError("No match found when setting `actual_instance` in EventDetail with oneOf schemas: AgentLocalEventDetail, DnsEventDetail, NetworkEventDetail, NetworkPopEventDetail, ProxyEventDetail, TargetEventDetail, TargetNetworkEventDetail. Details: " + ", ".join(error_messages))
        else:
            return v

    @classmethod
    def from_dict(cls, obj: Union[str, Dict[str, Any]]) -> Self:
        return cls.from_json(json.dumps(obj))

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

        # deserialize data into TargetEventDetail
        try:
            instance.actual_instance = TargetEventDetail.from_json(json_str)
            match += 1
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # deserialize data into TargetNetworkEventDetail
        try:
            instance.actual_instance = TargetNetworkEventDetail.from_json(json_str)
            match += 1
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # deserialize data into ProxyEventDetail
        try:
            instance.actual_instance = ProxyEventDetail.from_json(json_str)
            match += 1
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # deserialize data into DnsEventDetail
        try:
            instance.actual_instance = DnsEventDetail.from_json(json_str)
            match += 1
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # deserialize data into AgentLocalEventDetail
        try:
            instance.actual_instance = AgentLocalEventDetail.from_json(json_str)
            match += 1
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # deserialize data into NetworkEventDetail
        try:
            instance.actual_instance = NetworkEventDetail.from_json(json_str)
            match += 1
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # deserialize data into NetworkPopEventDetail
        try:
            instance.actual_instance = NetworkPopEventDetail.from_json(json_str)
            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 EventDetail with oneOf schemas: AgentLocalEventDetail, DnsEventDetail, NetworkEventDetail, NetworkPopEventDetail, ProxyEventDetail, TargetEventDetail, TargetNetworkEventDetail. Details: " + ", ".join(error_messages))
        elif match == 0:
            # no match
            raise ValueError("No match found when deserializing the JSON string into EventDetail with oneOf schemas: AgentLocalEventDetail, DnsEventDetail, NetworkEventDetail, NetworkPopEventDetail, ProxyEventDetail, TargetEventDetail, TargetNetworkEventDetail. Details: " + ", ".join(error_messages))
        else:
            return instance

    @model_serializer(when_used="json")
    def serialize_model(self):
        return json.loads(self.to_json())

    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], AgentLocalEventDetail, DnsEventDetail, NetworkEventDetail, NetworkPopEventDetail, ProxyEventDetail, TargetEventDetail, TargetNetworkEventDetail]]:
        """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())


