# 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_affinity import IoK8sApiCoreV1Affinity
from kubeflow_spark_api.models.io_k8s_api_core_v1_container import IoK8sApiCoreV1Container
from kubeflow_spark_api.models.io_k8s_api_core_v1_env_from_source import IoK8sApiCoreV1EnvFromSource
from kubeflow_spark_api.models.io_k8s_api_core_v1_env_var import IoK8sApiCoreV1EnvVar
from kubeflow_spark_api.models.io_k8s_api_core_v1_host_alias import IoK8sApiCoreV1HostAlias
from kubeflow_spark_api.models.io_k8s_api_core_v1_pod_dns_config import IoK8sApiCoreV1PodDNSConfig
from kubeflow_spark_api.models.io_k8s_api_core_v1_pod_security_context import IoK8sApiCoreV1PodSecurityContext
from kubeflow_spark_api.models.io_k8s_api_core_v1_pod_template_spec import IoK8sApiCoreV1PodTemplateSpec
from kubeflow_spark_api.models.io_k8s_api_core_v1_security_context import IoK8sApiCoreV1SecurityContext
from kubeflow_spark_api.models.io_k8s_api_core_v1_toleration import IoK8sApiCoreV1Toleration
from kubeflow_spark_api.models.io_k8s_api_core_v1_volume_mount import IoK8sApiCoreV1VolumeMount
from kubeflow_spark_api.models.spark_v1beta2_gpu_spec import SparkV1beta2GPUSpec
from kubeflow_spark_api.models.spark_v1beta2_name_key import SparkV1beta2NameKey
from kubeflow_spark_api.models.spark_v1beta2_name_path import SparkV1beta2NamePath
from kubeflow_spark_api.models.spark_v1beta2_secret_info import SparkV1beta2SecretInfo
from typing import Optional, Set
from typing_extensions import Self

class SparkV1beta2SparkPodSpec(BaseModel):
    """
    SparkPodSpec defines common things that can be customized for a Spark driver or executor pod.
    """ # noqa: E501
    affinity: Optional[IoK8sApiCoreV1Affinity] = Field(default=None, description="Affinity specifies the affinity/anti-affinity settings for the pod.")
    annotations: Optional[Dict[str, StrictStr]] = Field(default=None, description="Annotations are the Kubernetes annotations to be added to the pod.")
    config_maps: Optional[List[SparkV1beta2NamePath]] = Field(default=None, description="ConfigMaps carries information of other ConfigMaps to add to the pod.", alias="configMaps")
    core_limit: Optional[StrictStr] = Field(default=None, description="CoreLimit specifies a hard limit on CPU cores for the pod. Optional", alias="coreLimit")
    cores: Optional[StrictInt] = Field(default=None, description="Cores maps to `spark.driver.cores` or `spark.executor.cores` for the driver and executors, respectively.")
    dns_config: Optional[IoK8sApiCoreV1PodDNSConfig] = Field(default=None, description="DnsConfig dns settings for the pod, following the Kubernetes specifications.", alias="dnsConfig")
    env: Optional[List[IoK8sApiCoreV1EnvVar]] = Field(default=None, description="Env carries the environment variables to add to the pod.")
    env_from: Optional[List[IoK8sApiCoreV1EnvFromSource]] = Field(default=None, description="EnvFrom is a list of sources to populate environment variables in the container.", alias="envFrom")
    env_secret_key_refs: Optional[Dict[str, SparkV1beta2NameKey]] = Field(default=None, description="EnvSecretKeyRefs holds a mapping from environment variable names to SecretKeyRefs. Deprecated. Consider using `env` instead.", alias="envSecretKeyRefs")
    env_vars: Optional[Dict[str, StrictStr]] = Field(default=None, description="EnvVars carries the environment variables to add to the pod. Deprecated. Consider using `env` instead.", alias="envVars")
    gpu: Optional[SparkV1beta2GPUSpec] = Field(default=None, description="GPU specifies GPU requirement for the pod.")
    host_aliases: Optional[List[IoK8sApiCoreV1HostAlias]] = Field(default=None, description="HostAliases settings for the pod, following the Kubernetes specifications.", alias="hostAliases")
    host_network: Optional[StrictBool] = Field(default=None, description="HostNetwork indicates whether to request host networking for the pod or not.", alias="hostNetwork")
    image: Optional[StrictStr] = Field(default=None, description="Image is the container image to use. Overrides Spec.Image if set.")
    init_containers: Optional[List[IoK8sApiCoreV1Container]] = Field(default=None, description="InitContainers is a list of init-containers that run to completion before the main Spark container.", alias="initContainers")
    labels: Optional[Dict[str, StrictStr]] = Field(default=None, description="Labels are the Kubernetes labels to be added to the pod.")
    memory: Optional[StrictStr] = Field(default=None, description="Memory is the amount of memory to request for the pod.")
    memory_limit: Optional[StrictStr] = Field(default=None, description="MemoryLimit overrides the memory limit of the pod.", alias="memoryLimit")
    memory_overhead: Optional[StrictStr] = Field(default=None, description="MemoryOverhead is the amount of off-heap memory to allocate in cluster mode, in MiB unless otherwise specified.", alias="memoryOverhead")
    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 SparkApplication level (which will be deprecated).", alias="nodeSelector")
    pod_security_context: Optional[IoK8sApiCoreV1PodSecurityContext] = Field(default=None, description="PodSecurityContext specifies the PodSecurityContext to apply.", alias="podSecurityContext")
    scheduler_name: Optional[StrictStr] = Field(default=None, description="SchedulerName specifies the scheduler that will be used for scheduling", alias="schedulerName")
    secrets: Optional[List[SparkV1beta2SecretInfo]] = Field(default=None, description="Secrets carries information of secrets to add to the pod.")
    security_context: Optional[IoK8sApiCoreV1SecurityContext] = Field(default=None, description="SecurityContext specifies the container's SecurityContext to apply.", alias="securityContext")
    service_account: Optional[StrictStr] = Field(default=None, description="ServiceAccount is the name of the custom Kubernetes service account used by the pod.", alias="serviceAccount")
    share_process_namespace: Optional[StrictBool] = Field(default=None, description="ShareProcessNamespace settings for the pod, following the Kubernetes specifications.", alias="shareProcessNamespace")
    sidecars: Optional[List[IoK8sApiCoreV1Container]] = Field(default=None, description="Sidecars is a list of sidecar containers that run along side the main Spark container.")
    template: Optional[IoK8sApiCoreV1PodTemplateSpec] = Field(default=None, description="Template is a pod template that can be used to define the driver or executor pod configurations that Spark configurations do not support. Spark version >= 3.0.0 is required. Ref: https://spark.apache.org/docs/latest/running-on-kubernetes.html#pod-template.")
    termination_grace_period_seconds: Optional[StrictInt] = Field(default=None, description="Termination grace period seconds for the pod", alias="terminationGracePeriodSeconds")
    tolerations: Optional[List[IoK8sApiCoreV1Toleration]] = Field(default=None, description="Tolerations specifies the tolerations listed in \".spec.tolerations\" to be applied to the pod.")
    volume_mounts: Optional[List[IoK8sApiCoreV1VolumeMount]] = Field(default=None, description="VolumeMounts specifies the volumes listed in \".spec.volumes\" to mount into the main container's filesystem.", alias="volumeMounts")
    __properties: ClassVar[List[str]] = ["affinity", "annotations", "configMaps", "coreLimit", "cores", "dnsConfig", "env", "envFrom", "envSecretKeyRefs", "envVars", "gpu", "hostAliases", "hostNetwork", "image", "initContainers", "labels", "memory", "memoryLimit", "memoryOverhead", "nodeSelector", "podSecurityContext", "schedulerName", "secrets", "securityContext", "serviceAccount", "shareProcessNamespace", "sidecars", "template", "terminationGracePeriodSeconds", "tolerations", "volumeMounts"]

    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 SparkV1beta2SparkPodSpec 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 affinity
        if self.affinity:
            _dict['affinity'] = self.affinity.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in config_maps (list)
        _items = []
        if self.config_maps:
            for _item_config_maps in self.config_maps:
                if _item_config_maps:
                    _items.append(_item_config_maps.to_dict())
            _dict['configMaps'] = _items
        # override the default output from pydantic by calling `to_dict()` of dns_config
        if self.dns_config:
            _dict['dnsConfig'] = self.dns_config.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in env (list)
        _items = []
        if self.env:
            for _item_env in self.env:
                if _item_env:
                    _items.append(_item_env.to_dict())
            _dict['env'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in env_from (list)
        _items = []
        if self.env_from:
            for _item_env_from in self.env_from:
                if _item_env_from:
                    _items.append(_item_env_from.to_dict())
            _dict['envFrom'] = _items
        # override the default output from pydantic by calling `to_dict()` of each value in env_secret_key_refs (dict)
        _field_dict = {}
        if self.env_secret_key_refs:
            for _key_env_secret_key_refs in self.env_secret_key_refs:
                if self.env_secret_key_refs[_key_env_secret_key_refs]:
                    _field_dict[_key_env_secret_key_refs] = self.env_secret_key_refs[_key_env_secret_key_refs].to_dict()
            _dict['envSecretKeyRefs'] = _field_dict
        # override the default output from pydantic by calling `to_dict()` of gpu
        if self.gpu:
            _dict['gpu'] = self.gpu.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in host_aliases (list)
        _items = []
        if self.host_aliases:
            for _item_host_aliases in self.host_aliases:
                if _item_host_aliases:
                    _items.append(_item_host_aliases.to_dict())
            _dict['hostAliases'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in init_containers (list)
        _items = []
        if self.init_containers:
            for _item_init_containers in self.init_containers:
                if _item_init_containers:
                    _items.append(_item_init_containers.to_dict())
            _dict['initContainers'] = _items
        # override the default output from pydantic by calling `to_dict()` of pod_security_context
        if self.pod_security_context:
            _dict['podSecurityContext'] = self.pod_security_context.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in secrets (list)
        _items = []
        if self.secrets:
            for _item_secrets in self.secrets:
                if _item_secrets:
                    _items.append(_item_secrets.to_dict())
            _dict['secrets'] = _items
        # override the default output from pydantic by calling `to_dict()` of security_context
        if self.security_context:
            _dict['securityContext'] = self.security_context.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in sidecars (list)
        _items = []
        if self.sidecars:
            for _item_sidecars in self.sidecars:
                if _item_sidecars:
                    _items.append(_item_sidecars.to_dict())
            _dict['sidecars'] = _items
        # override the default output from pydantic by calling `to_dict()` of template
        if self.template:
            _dict['template'] = self.template.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in tolerations (list)
        _items = []
        if self.tolerations:
            for _item_tolerations in self.tolerations:
                if _item_tolerations:
                    _items.append(_item_tolerations.to_dict())
            _dict['tolerations'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in volume_mounts (list)
        _items = []
        if self.volume_mounts:
            for _item_volume_mounts in self.volume_mounts:
                if _item_volume_mounts:
                    _items.append(_item_volume_mounts.to_dict())
            _dict['volumeMounts'] = _items
        return _dict

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

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

        _obj = cls.model_validate({
            "affinity": IoK8sApiCoreV1Affinity.from_dict(obj["affinity"]) if obj.get("affinity") is not None else None,
            "annotations": obj.get("annotations"),
            "configMaps": [SparkV1beta2NamePath.from_dict(_item) for _item in obj["configMaps"]] if obj.get("configMaps") is not None else None,
            "coreLimit": obj.get("coreLimit"),
            "cores": obj.get("cores"),
            "dnsConfig": IoK8sApiCoreV1PodDNSConfig.from_dict(obj["dnsConfig"]) if obj.get("dnsConfig") is not None else None,
            "env": [IoK8sApiCoreV1EnvVar.from_dict(_item) for _item in obj["env"]] if obj.get("env") is not None else None,
            "envFrom": [IoK8sApiCoreV1EnvFromSource.from_dict(_item) for _item in obj["envFrom"]] if obj.get("envFrom") is not None else None,
            "envSecretKeyRefs": dict(
                (_k, SparkV1beta2NameKey.from_dict(_v))
                for _k, _v in obj["envSecretKeyRefs"].items()
            )
            if obj.get("envSecretKeyRefs") is not None
            else None,
            "envVars": obj.get("envVars"),
            "gpu": SparkV1beta2GPUSpec.from_dict(obj["gpu"]) if obj.get("gpu") is not None else None,
            "hostAliases": [IoK8sApiCoreV1HostAlias.from_dict(_item) for _item in obj["hostAliases"]] if obj.get("hostAliases") is not None else None,
            "hostNetwork": obj.get("hostNetwork"),
            "image": obj.get("image"),
            "initContainers": [IoK8sApiCoreV1Container.from_dict(_item) for _item in obj["initContainers"]] if obj.get("initContainers") is not None else None,
            "labels": obj.get("labels"),
            "memory": obj.get("memory"),
            "memoryLimit": obj.get("memoryLimit"),
            "memoryOverhead": obj.get("memoryOverhead"),
            "nodeSelector": obj.get("nodeSelector"),
            "podSecurityContext": IoK8sApiCoreV1PodSecurityContext.from_dict(obj["podSecurityContext"]) if obj.get("podSecurityContext") is not None else None,
            "schedulerName": obj.get("schedulerName"),
            "secrets": [SparkV1beta2SecretInfo.from_dict(_item) for _item in obj["secrets"]] if obj.get("secrets") is not None else None,
            "securityContext": IoK8sApiCoreV1SecurityContext.from_dict(obj["securityContext"]) if obj.get("securityContext") is not None else None,
            "serviceAccount": obj.get("serviceAccount"),
            "shareProcessNamespace": obj.get("shareProcessNamespace"),
            "sidecars": [IoK8sApiCoreV1Container.from_dict(_item) for _item in obj["sidecars"]] if obj.get("sidecars") is not None else None,
            "template": IoK8sApiCoreV1PodTemplateSpec.from_dict(obj["template"]) if obj.get("template") is not None else None,
            "terminationGracePeriodSeconds": obj.get("terminationGracePeriodSeconds"),
            "tolerations": [IoK8sApiCoreV1Toleration.from_dict(_item) for _item in obj["tolerations"]] if obj.get("tolerations") is not None else None,
            "volumeMounts": [IoK8sApiCoreV1VolumeMount.from_dict(_item) for _item in obj["volumeMounts"]] if obj.get("volumeMounts") is not None else None
        })
        return _obj


