"""
Snowflake User Defined Function API.

The Snowflake User Defined Function API is a REST API that you can use to access, update, and perform certain actions on User Defined Function resource in a Snowflake database.  # noqa: E501

The version of the OpenAPI document: 0.0.1
Contact: support@snowflake.com
Generated by: https://openapi-generator.tech

Do not edit this file manually.
"""

from __future__ import annotations

import json
import pprint
import re  # noqa: F401

from typing import Any, ClassVar, Dict, Optional, Union

from pydantic import BaseModel, ConfigDict, StrictBool

import snowflake.core.user_defined_function._generated.models

from snowflake.core.user_defined_function._generated.models import *  # noqa: F403


class FunctionLanguage(BaseModel):
    """A model object representing the FunctionLanguage resource.

    Constructs an object of type FunctionLanguage with the provided properties.

    Parameters
    __________
    called_on_null_input : bool, optional
        Decide if the function/procedure can receive null input
    is_volatile : bool, optional
         Specifies the behavior of the UDF when returning results. This Field is deprecated for Procedure.

                    If true, UDF might return different values for different rows, even for the same input.
                    This field is deprecated for Procedure.

                    If false, UDF assumes that the function, when called with the same inputs, will always return the same result.
                    This guarantee is not checked. Specifying IMMUTABLE for a UDF that returns different values for the same input will result in undefined behavior.
    """

    called_on_null_input: Optional[StrictBool] = None

    is_volatile: Optional[StrictBool] = None

    __properties = ["language", "called_on_null_input", "is_volatile"]

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

    # JSON field name that stores the object type
    __discriminator_property_name: ClassVar[str] = "language"

    # discriminator mappings
    __discriminator_value_class_map: ClassVar[Dict[str, str]] = {
        "JAVA": "JavaFunction",
        "JAVASCRIPT": "JavaScriptFunction",
        "PYTHON": "PythonFunction",
        "SCALA": "ScalaFunction",
        "SQL": "SQLFunction",
        "BaseLanguage": "BaseLanguage",
    }

    @classmethod
    def get_discriminator_value(cls, obj: dict[str, Any]) -> Optional[str]:
        """Returns the discriminator value (object type) of the data."""
        discriminator_value = obj[cls.__discriminator_property_name]
        if discriminator_value:
            return cls.__discriminator_value_class_map.get(discriminator_value)
        else:
            return None

    __discriminator_value_to_type: ClassVar[Dict[str, str]] = {
        "JavaFunction": "JAVA",
        "JavaScriptFunction": "JAVASCRIPT",
        "PythonFunction": "PYTHON",
        "ScalaFunction": "SCALA",
        "SQLFunction": "SQL",
        "BaseLanguage": "BaseLanguage",
    }

    @classmethod
    def get_child_model_discriminator_value(cls, child_model: str) -> str:
        return cls.__discriminator_value_to_type[child_model]

    def to_str(self) -> str:
        """Returns the string representation of the model using alias."""
        return pprint.pformat(self.dict(by_alias=True))

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias."""
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(
        cls, json_str: str
    ) -> Union[BaseLanguage, JavaFunction, JavaScriptFunction, PythonFunction, SQLFunction, ScalaFunction]:
        """Create an instance of FunctionLanguage from a JSON string."""
        return cls.from_dict(json.loads(json_str))

    def to_dict(
        self,
        hide_readonly_properties: bool = False,
    ) -> dict[str, Any]:
        """Returns the dictionary representation of the model using alias."""
        exclude_properties = set()

        if hide_readonly_properties:
            exclude_properties.update({})

        _dict = self.model_dump(serialize_as_any=True, by_alias=True, exclude=exclude_properties, exclude_none=True)

        return _dict

    def to_dict_without_readonly_properties(self) -> dict[str, Any]:
        """Return the dictionary representation of the model without readonly properties."""
        return self.to_dict(hide_readonly_properties=True)

    @classmethod
    def from_dict(
        cls, obj: dict
    ) -> Union[BaseLanguage, JavaFunction, JavaScriptFunction, PythonFunction, SQLFunction, ScalaFunction]:
        """Create an instance of FunctionLanguage from a dict."""
        # look up the object type based on discriminator mapping
        object_type = cls.get_discriminator_value(obj)
        if object_type:
            klass = getattr(snowflake.core.user_defined_function._generated.models, object_type)
            return klass.from_dict(obj)
        else:
            raise ValueError(
                "FunctionLanguage failed to lookup discriminator value from "
                + json.dumps(obj)
                + ". Discriminator property name: "
                + cls.__discriminator_property_name
                + ", mapping: "
                + json.dumps(cls.__discriminator_value_class_map)
            )


class FunctionLanguageModel:
    def __init__(
        self,  # optional properties
        called_on_null_input: Optional[bool] = None,
        is_volatile: Optional[bool] = None,
    ):
        """A model object representing the FunctionLanguage resource.

        Constructs an object of type FunctionLanguage with the provided properties.

        Parameters
        __________
        called_on_null_input : bool, optional
            Decide if the function/procedure can receive null input
        is_volatile : bool, optional
             Specifies the behavior of the UDF when returning results. This Field is deprecated for Procedure.

            If true, UDF might return different values for different rows, even for the same input.
            This field is deprecated for Procedure.

            If false, UDF assumes that the function, when called with the same inputs, will always return the same result.
            This guarantee is not checked. Specifying IMMUTABLE for a UDF that returns different values for the same input will result in undefined behavior.
        """
        self.called_on_null_input = called_on_null_input
        self.is_volatile = is_volatile

    __properties = ["language", "called_on_null_input", "is_volatile"]

    def __repr__(self) -> str:
        return repr(self._to_model())

    def _to_model(self):
        return FunctionLanguage(
            called_on_null_input=self.called_on_null_input,
            is_volatile=self.is_volatile,
        )

    @classmethod
    def _from_model(cls, model) -> FunctionLanguageModel:
        return model.__class__._model_class._from_model(model)

    def to_dict(self):
        """Create a dictionary of the properties from a FunctionLanguage.

        This method constructs a dictionary with the key-value entries corresponding to the properties of the FunctionLanguage object.

        Returns
        _______
        dict
            A dictionary object created using the input model.
        """
        return self._to_model().to_dict()

    @classmethod
    def from_dict(
        cls, obj: dict
    ) -> Union[
        BaseLanguageModel,
        JavaFunctionModel,
        JavaScriptFunctionModel,
        PythonFunctionModel,
        SQLFunctionModel,
        ScalaFunctionModel,
    ]:
        """Create an instance of FunctionLanguage from a dict.

        This method constructs a FunctionLanguage object from a dictionary with the key-value pairs of its properties.

        Parameters
        ----------
        obj : dict
            A dictionary whose keys and values correspond to the properties of the resource object.

        Returns
        _______
        FunctionLanguage
            A FunctionLanguage object created using the input dictionary; this will fail if the required properties are missing.
        """
        return cls._from_model(FunctionLanguage.from_dict(obj))


FunctionLanguage._model_class = FunctionLanguageModel
