# coding: utf-8

"""
    Kubeflow Spark Operator OpenAPI Spec

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

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

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


from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from kubeflow_spark_api.models.io_k8s_api_core_v1_volume import IoK8sApiCoreV1Volume
from kubeflow_spark_api.models.spark_v1beta2_batch_scheduler_configuration import SparkV1beta2BatchSchedulerConfiguration
from kubeflow_spark_api.models.spark_v1beta2_dependencies import SparkV1beta2Dependencies
from kubeflow_spark_api.models.spark_v1beta2_driver_ingress_configuration import SparkV1beta2DriverIngressConfiguration
from kubeflow_spark_api.models.spark_v1beta2_driver_spec import SparkV1beta2DriverSpec
from kubeflow_spark_api.models.spark_v1beta2_dynamic_allocation import SparkV1beta2DynamicAllocation
from kubeflow_spark_api.models.spark_v1beta2_executor_spec import SparkV1beta2ExecutorSpec
from kubeflow_spark_api.models.spark_v1beta2_monitoring_spec import SparkV1beta2MonitoringSpec
from kubeflow_spark_api.models.spark_v1beta2_restart_policy import SparkV1beta2RestartPolicy
from kubeflow_spark_api.models.spark_v1beta2_spark_ui_configuration import SparkV1beta2SparkUIConfiguration
from typing import Optional, Set
from typing_extensions import Self

class SparkV1beta2SparkApplicationSpec(BaseModel):
    """
    SparkApplicationSpec defines the desired state of SparkApplication It carries every pieces of information a spark-submit command takes and recognizes.
    """ # noqa: E501
    arguments: Optional[List[StrictStr]] = Field(default=None, description="Arguments is a list of arguments to be passed to the application.")
    batch_scheduler: Optional[StrictStr] = Field(default=None, description="BatchScheduler configures which batch scheduler will be used for scheduling", alias="batchScheduler")
    batch_scheduler_options: Optional[SparkV1beta2BatchSchedulerConfiguration] = Field(default=None, description="BatchSchedulerOptions provides fine-grained control on how to batch scheduling.", alias="batchSchedulerOptions")
    deps: Optional[SparkV1beta2Dependencies] = Field(default=None, description="Deps captures all possible types of dependencies of a Spark application.")
    driver: SparkV1beta2DriverSpec = Field(description="Driver is the driver specification.")
    driver_ingress_options: Optional[List[SparkV1beta2DriverIngressConfiguration]] = Field(default=None, description="DriverIngressOptions allows configuring the Service and the Ingress to expose ports inside Spark Driver", alias="driverIngressOptions")
    dynamic_allocation: Optional[SparkV1beta2DynamicAllocation] = Field(default=None, description="DynamicAllocation configures dynamic allocation that becomes available for the Kubernetes scheduler backend since Spark 3.0.", alias="dynamicAllocation")
    executor: SparkV1beta2ExecutorSpec = Field(description="Executor is the executor specification.")
    failure_retries: Optional[StrictInt] = Field(default=None, description="FailureRetries is the number of times to retry a failed application before giving up. This is best effort and actual retry attempts can be >= the value specified.", alias="failureRetries")
    hadoop_conf: Optional[Dict[str, StrictStr]] = Field(default=None, description="HadoopConf carries user-specified Hadoop configuration properties as they would use the \"--conf\" option in spark-submit. The SparkApplication controller automatically adds prefix \"spark.hadoop.\" to Hadoop configuration properties.", alias="hadoopConf")
    hadoop_config_map: Optional[StrictStr] = Field(default=None, description="HadoopConfigMap carries the name of the ConfigMap containing Hadoop configuration files such as core-site.xml. The controller will add environment variable HADOOP_CONF_DIR to the path where the ConfigMap is mounted to.", alias="hadoopConfigMap")
    image: Optional[StrictStr] = Field(default=None, description="Image is the container image for the driver, executor, and init-container. Any custom container images for the driver, executor, or init-container takes precedence over this.")
    image_pull_policy: Optional[StrictStr] = Field(default=None, description="ImagePullPolicy is the image pull policy for the driver, executor, and init-container.", alias="imagePullPolicy")
    image_pull_secrets: Optional[List[StrictStr]] = Field(default=None, description="ImagePullSecrets is the list of image-pull secrets.", alias="imagePullSecrets")
    main_application_file: StrictStr = Field(description="MainFile is the path to a bundled JAR, Python, or R file of the application.", alias="mainApplicationFile")
    main_class: Optional[StrictStr] = Field(default=None, description="MainClass is the fully-qualified main class of the Spark application. This only applies to Java/Scala Spark applications.", alias="mainClass")
    memory_overhead_factor: Optional[StrictStr] = Field(default=None, description="This sets the Memory Overhead Factor that will allocate memory to non-JVM memory. For JVM-based jobs this value will default to 0.10, for non-JVM jobs 0.40. Value of this field will be overridden by `Spec.Driver.MemoryOverhead` and `Spec.Executor.MemoryOverhead` if they are set.", alias="memoryOverheadFactor")
    mode: Optional[StrictStr] = Field(default=None, description="Mode is the deployment mode of the Spark application.")
    monitoring: Optional[SparkV1beta2MonitoringSpec] = Field(default=None, description="Monitoring configures how monitoring is handled.")
    node_selector: Optional[Dict[str, StrictStr]] = Field(default=None, description="NodeSelector is the Kubernetes node selector to be added to the driver and executor pods. This field is mutually exclusive with nodeSelector at podSpec level (driver or executor). This field will be deprecated in future versions (at SparkApplicationSpec level).", alias="nodeSelector")
    proxy_user: Optional[StrictStr] = Field(default=None, description="ProxyUser specifies the user to impersonate when submitting the application. It maps to the command-line flag \"--proxy-user\" in spark-submit.", alias="proxyUser")
    python_version: Optional[StrictStr] = Field(default=None, description="This sets the major Python version of the docker image used to run the driver and executor containers. Can either be 2 or 3, default 2.", alias="pythonVersion")
    restart_policy: Optional[SparkV1beta2RestartPolicy] = Field(default=None, description="RestartPolicy defines the policy on if and in which conditions the controller should restart an application.", alias="restartPolicy")
    retry_interval: Optional[StrictInt] = Field(default=None, description="RetryInterval is the unit of intervals in seconds between submission retries.", alias="retryInterval")
    spark_conf: Optional[Dict[str, StrictStr]] = Field(default=None, description="SparkConf carries user-specified Spark configuration properties as they would use the  \"--conf\" option in spark-submit.", alias="sparkConf")
    spark_config_map: Optional[StrictStr] = Field(default=None, description="SparkConfigMap carries the name of the ConfigMap containing Spark configuration files such as log4j.properties. The controller will add environment variable SPARK_CONF_DIR to the path where the ConfigMap is mounted to.", alias="sparkConfigMap")
    spark_ui_options: Optional[SparkV1beta2SparkUIConfiguration] = Field(default=None, description="SparkUIOptions allows configuring the Service and the Ingress to expose the sparkUI", alias="sparkUIOptions")
    spark_version: StrictStr = Field(description="SparkVersion is the version of Spark the application uses.", alias="sparkVersion")
    suspend: Optional[StrictBool] = Field(default=None, description="Suspend indicates whether the SparkApplication should be suspended. When true, the controller skips submitting the Spark job. If a SparkApplication is suspended after creation (i.e. the flag goes from false to true), the Spark operator will delete all active Pods associated with this SparkApplication. Users must design their Spark application to gracefully handle this.")
    time_to_live_seconds: Optional[StrictInt] = Field(default=None, description="TimeToLiveSeconds defines the Time-To-Live (TTL) duration in seconds for this SparkApplication after its termination. The SparkApplication object will be garbage collected if the current time is more than the TimeToLiveSeconds since its termination.", alias="timeToLiveSeconds")
    type: StrictStr = Field(description="Type tells the type of the Spark application.")
    volumes: Optional[List[IoK8sApiCoreV1Volume]] = Field(default=None, description="Volumes is the list of Kubernetes volumes that can be mounted by the driver and/or executors.")
    __properties: ClassVar[List[str]] = ["arguments", "batchScheduler", "batchSchedulerOptions", "deps", "driver", "driverIngressOptions", "dynamicAllocation", "executor", "failureRetries", "hadoopConf", "hadoopConfigMap", "image", "imagePullPolicy", "imagePullSecrets", "mainApplicationFile", "mainClass", "memoryOverheadFactor", "mode", "monitoring", "nodeSelector", "proxyUser", "pythonVersion", "restartPolicy", "retryInterval", "sparkConf", "sparkConfigMap", "sparkUIOptions", "sparkVersion", "suspend", "timeToLiveSeconds", "type", "volumes"]

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


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

    def to_json(self) -> str:
        """Returns the JSON representation of the model using alias"""
        # TODO: pydantic v2: use .model_dump_json(by_alias=True, exclude_unset=True) instead
        return json.dumps(self.to_dict())

    @classmethod
    def from_json(cls, json_str: str) -> Optional[Self]:
        """Create an instance of SparkV1beta2SparkApplicationSpec from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self) -> Dict[str, Any]:
        """Return the dictionary representation of the model using alias.

        This has the following differences from calling pydantic's
        `self.model_dump(by_alias=True)`:

        * `None` is only added to the output dict for nullable fields that
          were set at model initialization. Other fields with value `None`
          are ignored.
        """
        excluded_fields: Set[str] = set([
        ])

        _dict = self.model_dump(
            by_alias=True,
            exclude=excluded_fields,
            exclude_none=True,
        )
        # override the default output from pydantic by calling `to_dict()` of batch_scheduler_options
        if self.batch_scheduler_options:
            _dict['batchSchedulerOptions'] = self.batch_scheduler_options.to_dict()
        # override the default output from pydantic by calling `to_dict()` of deps
        if self.deps:
            _dict['deps'] = self.deps.to_dict()
        # override the default output from pydantic by calling `to_dict()` of driver
        if self.driver:
            _dict['driver'] = self.driver.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in driver_ingress_options (list)
        _items = []
        if self.driver_ingress_options:
            for _item_driver_ingress_options in self.driver_ingress_options:
                if _item_driver_ingress_options:
                    _items.append(_item_driver_ingress_options.to_dict())
            _dict['driverIngressOptions'] = _items
        # override the default output from pydantic by calling `to_dict()` of dynamic_allocation
        if self.dynamic_allocation:
            _dict['dynamicAllocation'] = self.dynamic_allocation.to_dict()
        # override the default output from pydantic by calling `to_dict()` of executor
        if self.executor:
            _dict['executor'] = self.executor.to_dict()
        # override the default output from pydantic by calling `to_dict()` of monitoring
        if self.monitoring:
            _dict['monitoring'] = self.monitoring.to_dict()
        # override the default output from pydantic by calling `to_dict()` of restart_policy
        if self.restart_policy:
            _dict['restartPolicy'] = self.restart_policy.to_dict()
        # override the default output from pydantic by calling `to_dict()` of spark_ui_options
        if self.spark_ui_options:
            _dict['sparkUIOptions'] = self.spark_ui_options.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in volumes (list)
        _items = []
        if self.volumes:
            for _item_volumes in self.volumes:
                if _item_volumes:
                    _items.append(_item_volumes.to_dict())
            _dict['volumes'] = _items
        return _dict

    @classmethod
    def from_dict(cls, obj: Optional[Dict[str, Any]]) -> Optional[Self]:
        """Create an instance of SparkV1beta2SparkApplicationSpec from a dict"""
        if obj is None:
            return None

        if not isinstance(obj, dict):
            return cls.model_validate(obj)

        _obj = cls.model_validate({
            "arguments": obj.get("arguments"),
            "batchScheduler": obj.get("batchScheduler"),
            "batchSchedulerOptions": SparkV1beta2BatchSchedulerConfiguration.from_dict(obj["batchSchedulerOptions"]) if obj.get("batchSchedulerOptions") is not None else None,
            "deps": SparkV1beta2Dependencies.from_dict(obj["deps"]) if obj.get("deps") is not None else None,
            "driver": SparkV1beta2DriverSpec.from_dict(obj["driver"]) if obj.get("driver") is not None else None,
            "driverIngressOptions": [SparkV1beta2DriverIngressConfiguration.from_dict(_item) for _item in obj["driverIngressOptions"]] if obj.get("driverIngressOptions") is not None else None,
            "dynamicAllocation": SparkV1beta2DynamicAllocation.from_dict(obj["dynamicAllocation"]) if obj.get("dynamicAllocation") is not None else None,
            "executor": SparkV1beta2ExecutorSpec.from_dict(obj["executor"]) if obj.get("executor") is not None else None,
            "failureRetries": obj.get("failureRetries"),
            "hadoopConf": obj.get("hadoopConf"),
            "hadoopConfigMap": obj.get("hadoopConfigMap"),
            "image": obj.get("image"),
            "imagePullPolicy": obj.get("imagePullPolicy"),
            "imagePullSecrets": obj.get("imagePullSecrets"),
            "mainApplicationFile": obj.get("mainApplicationFile"),
            "mainClass": obj.get("mainClass"),
            "memoryOverheadFactor": obj.get("memoryOverheadFactor"),
            "mode": obj.get("mode"),
            "monitoring": SparkV1beta2MonitoringSpec.from_dict(obj["monitoring"]) if obj.get("monitoring") is not None else None,
            "nodeSelector": obj.get("nodeSelector"),
            "proxyUser": obj.get("proxyUser"),
            "pythonVersion": obj.get("pythonVersion"),
            "restartPolicy": SparkV1beta2RestartPolicy.from_dict(obj["restartPolicy"]) if obj.get("restartPolicy") is not None else None,
            "retryInterval": obj.get("retryInterval"),
            "sparkConf": obj.get("sparkConf"),
            "sparkConfigMap": obj.get("sparkConfigMap"),
            "sparkUIOptions": SparkV1beta2SparkUIConfiguration.from_dict(obj["sparkUIOptions"]) if obj.get("sparkUIOptions") is not None else None,
            "sparkVersion": obj.get("sparkVersion") if obj.get("sparkVersion") is not None else '',
            "suspend": obj.get("suspend"),
            "timeToLiveSeconds": obj.get("timeToLiveSeconds"),
            "type": obj.get("type") if obj.get("type") is not None else '',
            "volumes": [IoK8sApiCoreV1Volume.from_dict(_item) for _item in obj["volumes"]] if obj.get("volumes") is not None else None
        })
        return _obj


