# coding: utf-8

"""
TrueFoundry ML API

No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)

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

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

from __future__ import annotations

import json
import pprint
import re  # noqa: F401
from typing import TYPE_CHECKING, Any, List, Optional, Union

from truefoundry.ml._autogen.client.models.fast_ai_framework import FastAIFramework
from truefoundry.ml._autogen.client.models.gluon_framework import GluonFramework
from truefoundry.ml._autogen.client.models.h2_o_framework import H2OFramework
from truefoundry.ml._autogen.client.models.keras_framework import KerasFramework
from truefoundry.ml._autogen.client.models.light_gbm_framework import LightGBMFramework
from truefoundry.ml._autogen.client.models.onnx_framework import ONNXFramework
from truefoundry.ml._autogen.client.models.paddle_framework import PaddleFramework
from truefoundry.ml._autogen.client.models.py_torch_framework import PyTorchFramework
from truefoundry.ml._autogen.client.models.sklearn_framework import SklearnFramework
from truefoundry.ml._autogen.client.models.spa_cy_framework import SpaCyFramework
from truefoundry.ml._autogen.client.models.stats_models_framework import (
    StatsModelsFramework,
)
from truefoundry.ml._autogen.client.models.tensor_flow_framework import (
    TensorFlowFramework,
)
from truefoundry.ml._autogen.client.models.transformers_framework import (
    TransformersFramework,
)
from truefoundry.ml._autogen.client.models.xg_boost_framework import XGBoostFramework
from truefoundry.pydantic_v1 import (
    BaseModel,
    Field,
    ValidationError,
    validator,
)

FRAMEWORK_ANY_OF_SCHEMAS = [
    "FastAIFramework",
    "GluonFramework",
    "H2OFramework",
    "KerasFramework",
    "LightGBMFramework",
    "ONNXFramework",
    "PaddleFramework",
    "PyTorchFramework",
    "SklearnFramework",
    "SpaCyFramework",
    "StatsModelsFramework",
    "TensorFlowFramework",
    "TransformersFramework",
    "XGBoostFramework",
]


class Framework(BaseModel):
    """
    Framework for the model version like Transformers, PyTorch, Sklearn, Xgboost etc with framework specific metadata. This will be used to infer model deployment configuration
    """

    # data type: TransformersFramework
    anyof_schema_1_validator: Optional[TransformersFramework] = None
    # data type: TensorFlowFramework
    anyof_schema_2_validator: Optional[TensorFlowFramework] = None
    # data type: SklearnFramework
    anyof_schema_3_validator: Optional[SklearnFramework] = None
    # data type: PyTorchFramework
    anyof_schema_4_validator: Optional[PyTorchFramework] = None
    # data type: KerasFramework
    anyof_schema_5_validator: Optional[KerasFramework] = None
    # data type: XGBoostFramework
    anyof_schema_6_validator: Optional[XGBoostFramework] = None
    # data type: LightGBMFramework
    anyof_schema_7_validator: Optional[LightGBMFramework] = None
    # data type: FastAIFramework
    anyof_schema_8_validator: Optional[FastAIFramework] = None
    # data type: H2OFramework
    anyof_schema_9_validator: Optional[H2OFramework] = None
    # data type: ONNXFramework
    anyof_schema_10_validator: Optional[ONNXFramework] = None
    # data type: SpaCyFramework
    anyof_schema_11_validator: Optional[SpaCyFramework] = None
    # data type: StatsModelsFramework
    anyof_schema_12_validator: Optional[StatsModelsFramework] = None
    # data type: GluonFramework
    anyof_schema_13_validator: Optional[GluonFramework] = None
    # data type: PaddleFramework
    anyof_schema_14_validator: Optional[PaddleFramework] = None
    if TYPE_CHECKING:
        actual_instance: Union[
            FastAIFramework,
            GluonFramework,
            H2OFramework,
            KerasFramework,
            LightGBMFramework,
            ONNXFramework,
            PaddleFramework,
            PyTorchFramework,
            SklearnFramework,
            SpaCyFramework,
            StatsModelsFramework,
            TensorFlowFramework,
            TransformersFramework,
            XGBoostFramework,
        ]
    else:
        actual_instance: Any
    any_of_schemas: List[str] = Field(FRAMEWORK_ANY_OF_SCHEMAS, const=True)

    class Config:
        validate_assignment = True

    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)

    @validator("actual_instance")
    def actual_instance_must_validate_anyof(cls, v):
        instance = Framework.construct()
        error_messages = []
        # validate data type: TransformersFramework
        if not isinstance(v, TransformersFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `TransformersFramework`"
            )
        else:
            return v

        # validate data type: TensorFlowFramework
        if not isinstance(v, TensorFlowFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `TensorFlowFramework`"
            )
        else:
            return v

        # validate data type: SklearnFramework
        if not isinstance(v, SklearnFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `SklearnFramework`"
            )
        else:
            return v

        # validate data type: PyTorchFramework
        if not isinstance(v, PyTorchFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `PyTorchFramework`"
            )
        else:
            return v

        # validate data type: KerasFramework
        if not isinstance(v, KerasFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `KerasFramework`"
            )
        else:
            return v

        # validate data type: XGBoostFramework
        if not isinstance(v, XGBoostFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `XGBoostFramework`"
            )
        else:
            return v

        # validate data type: LightGBMFramework
        if not isinstance(v, LightGBMFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `LightGBMFramework`"
            )
        else:
            return v

        # validate data type: FastAIFramework
        if not isinstance(v, FastAIFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `FastAIFramework`"
            )
        else:
            return v

        # validate data type: H2OFramework
        if not isinstance(v, H2OFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `H2OFramework`"
            )
        else:
            return v

        # validate data type: ONNXFramework
        if not isinstance(v, ONNXFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `ONNXFramework`"
            )
        else:
            return v

        # validate data type: SpaCyFramework
        if not isinstance(v, SpaCyFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `SpaCyFramework`"
            )
        else:
            return v

        # validate data type: StatsModelsFramework
        if not isinstance(v, StatsModelsFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `StatsModelsFramework`"
            )
        else:
            return v

        # validate data type: GluonFramework
        if not isinstance(v, GluonFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `GluonFramework`"
            )
        else:
            return v

        # validate data type: PaddleFramework
        if not isinstance(v, PaddleFramework):
            error_messages.append(
                f"Error! Input type `{type(v)}` is not `PaddleFramework`"
            )
        else:
            return v

        if error_messages:
            # no match
            raise ValueError(
                "No match found when setting the actual_instance in Framework with anyOf schemas: FastAIFramework, GluonFramework, H2OFramework, KerasFramework, LightGBMFramework, ONNXFramework, PaddleFramework, PyTorchFramework, SklearnFramework, SpaCyFramework, StatsModelsFramework, TensorFlowFramework, TransformersFramework, XGBoostFramework. Details: "
                + ", ".join(error_messages)
            )
        else:
            return v

    @classmethod
    def from_dict(cls, obj: dict) -> Framework:
        return cls.from_json(json.dumps(obj))

    @classmethod
    def from_json(cls, json_str: str) -> Framework:
        """Returns the object represented by the json string"""
        instance = Framework.construct()
        error_messages = []
        # anyof_schema_1_validator: Optional[TransformersFramework] = None
        try:
            instance.actual_instance = TransformersFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_2_validator: Optional[TensorFlowFramework] = None
        try:
            instance.actual_instance = TensorFlowFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_3_validator: Optional[SklearnFramework] = None
        try:
            instance.actual_instance = SklearnFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_4_validator: Optional[PyTorchFramework] = None
        try:
            instance.actual_instance = PyTorchFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_5_validator: Optional[KerasFramework] = None
        try:
            instance.actual_instance = KerasFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_6_validator: Optional[XGBoostFramework] = None
        try:
            instance.actual_instance = XGBoostFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_7_validator: Optional[LightGBMFramework] = None
        try:
            instance.actual_instance = LightGBMFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_8_validator: Optional[FastAIFramework] = None
        try:
            instance.actual_instance = FastAIFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_9_validator: Optional[H2OFramework] = None
        try:
            instance.actual_instance = H2OFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_10_validator: Optional[ONNXFramework] = None
        try:
            instance.actual_instance = ONNXFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_11_validator: Optional[SpaCyFramework] = None
        try:
            instance.actual_instance = SpaCyFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_12_validator: Optional[StatsModelsFramework] = None
        try:
            instance.actual_instance = StatsModelsFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_13_validator: Optional[GluonFramework] = None
        try:
            instance.actual_instance = GluonFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))
        # anyof_schema_14_validator: Optional[PaddleFramework] = None
        try:
            instance.actual_instance = PaddleFramework.from_json(json_str)
            return instance
        except (ValidationError, ValueError) as e:
            error_messages.append(str(e))

        if error_messages:
            # no match
            raise ValueError(
                "No match found when deserializing the JSON string into Framework with anyOf schemas: FastAIFramework, GluonFramework, H2OFramework, KerasFramework, LightGBMFramework, ONNXFramework, PaddleFramework, PyTorchFramework, SklearnFramework, SpaCyFramework, StatsModelsFramework, TensorFlowFramework, TransformersFramework, XGBoostFramework. 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"

        to_json = getattr(self.actual_instance, "to_json", None)
        if callable(to_json):
            return self.actual_instance.to_json()
        else:
            return json.dumps(self.actual_instance)

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

        to_json = getattr(self.actual_instance, "to_json", None)
        if callable(to_json):
            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.dict())
