# coding: utf-8

"""
    Jobs API 2.1

    The Jobs API allows you to create, edit, and delete jobs. You should never hard code secrets or store them in plain text. Use the [Secrets API](https://docs.microsoft.com/azure/databricks/dev-tools/api/latest/secrets) to manage secrets in the [Databricks CLI](https://docs.microsoft.com/azure/databricks/dev-tools/cli/index). Use the [Secrets utility](https://docs.microsoft.com/azure/databricks/dev-tools/databricks-utils#dbutils-secrets) to reference secrets in notebooks and jobs.  # noqa: E501

    The version of the OpenAPI document: 2.1
    Generated by: https://openapi-generator.tech
"""


from __future__ import annotations

import json
import pprint
import re  # noqa: F401
from inspect import getfullargspec
from typing import Optional

from pydantic import BaseModel, Field, StrictInt, StrictStr, validator


class AwsAttributes(BaseModel):
    """NOTE: This class is auto generated by OpenAPI Generator.
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """

    first_on_demand: Optional[StrictInt] = Field(
        None,
        description="The first first_on_demand nodes of the cluster are placed on on-demand instances. If this value is greater than 0, the cluster driver node is placed on an on-demand instance. If this value is greater than or equal to the current cluster size, all nodes are placed on on-demand instances. If this value is less than the current cluster size, first_on_demand nodes are placed on on-demand instances and the remainder are placed on `availability` instances. This value does not affect cluster size and cannot be mutated over the lifetime of a cluster.",
    )
    availability: Optional[StrictStr] = Field(
        None,
        description="Availability type used for all subsequent nodes past the `first_on_demand` ones. **Note:** If `first_on_demand` is zero, this availability type is used for the entire cluster.  `SPOT`: use spot instances. `ON_DEMAND`: use on-demand instances. `SPOT_WITH_FALLBACK`: preferably use spot instances, but fall back to on-demand instances if spot instances cannot be acquired (for example, if AWS spot prices are too high).",
    )
    zone_id: Optional[StrictStr] = Field(
        None,
        description="Identifier for the availability zone/datacenter in which the cluster resides. You have three options:  **Specify an availability zone as a string**, for example: “us-west-2a”. The provided availability zone must be in the same region as the Databricks deployment. For example, “us-west-2a” is not a valid zone ID if the Databricks deployment resides in the “us-east-1” region.  **Enable automatic availability zone selection (“Auto-AZ”)**, by setting the value “auto”. Databricks selects the AZ based on available IPs in the workspace subnets and retries in other availability zones if AWS returns insufficient capacity errors.  **Do not specify a value**. If not specified, a default zone is used.  The list of available zones as well as the default value can be found by using the [List zones](https://docs.databricks.com/dev-tools/api/latest/clusters.html#list-zones) API.",
    )
    instance_profile_arn: Optional[StrictStr] = Field(
        None,
        description="Nodes for this cluster are only be placed on AWS instances with this instance profile. If omitted, nodes are placed on instances without an instance profile. The instance profile must have previously been added to the Databricks environment by an account administrator.  This feature may only be available to certain customer plans.",
    )
    spot_bid_price_percent: Optional[StrictInt] = Field(
        None,
        description="The max price for AWS spot instances, as a percentage of the corresponding instance type’s on-demand price. For example, if this field is set to 50, and the cluster needs a new `i3.xlarge` spot instance, then the max price is half of the price of on-demand `i3.xlarge` instances. Similarly, if this field is set to 200, the max price is twice the price of on-demand `i3.xlarge` instances. If not specified, the default value is 100\\. When spot instances are requested for this cluster, only spot instances whose max price percentage matches this field is considered. For safety, we enforce this field to be no more than 10000.",
    )
    ebs_volume_type: Optional[StrictStr] = Field(
        None,
        description="The type of EBS volume that is launched with this cluster.  `GENERAL_PURPOSE_SSD`: provision extra storage using AWS gp2 EBS volumes. `THROUGHPUT_OPTIMIZED_HDD`: provision extra storage using AWS st1 volumes.",
    )
    ebs_volume_count: Optional[StrictInt] = Field(
        None,
        description="The number of volumes launched for each instance. You can choose up to 10 volumes. This feature is only enabled for supported node types. Legacy node types cannot specify custom EBS volumes. For node types with no instance store, at least one EBS volume needs to be specified; otherwise, cluster creation fails.  These EBS volumes are mounted at `/ebs0`, `/ebs1`, and etc. Instance store volumes are mounted at `/local_disk0`, `/local_disk1`, and etc.  If EBS volumes are attached, Databricks configures Spark to use only the EBS volumes for scratch storage because heterogeneously sized scratch devices can lead to inefficient disk utilization. If no EBS volumes are attached, Databricks configures Spark to use instance store volumes.  If EBS volumes are specified, then the Spark configuration `spark.local.dir` is overridden.",
    )
    ebs_volume_size: Optional[StrictInt] = Field(
        None,
        description="The size of each EBS volume (in GiB) launched for each instance. For general purpose SSD, this value must be within the range 100 - 4096\\. For throughput optimized HDD, this value must be within the range 500 - 4096\\. Custom EBS volumes cannot be specified for the legacy node types (_memory-optimized_ and _compute-optimized_).",
    )
    ebs_volume_iops: Optional[StrictInt] = Field(
        None,
        description="The number of IOPS per EBS gp3 volume.  This value must be between 3000 and 16000.  The value of IOPS and throughput is calculated based on AWS documentation to match the maximum performance of a gp2 volume with the same volume size.  For more information, see the [EBS volume limit calculator](https://github.com/awslabs/aws-support-tools/tree/master/EBS/VolumeLimitCalculator).",
    )
    ebs_volume_throughput: Optional[StrictInt] = Field(
        None,
        description="The throughput per EBS gp3 volume, in MiB per second.  This value must be between 125 and 1000.",
    )
    __properties = [
        "first_on_demand",
        "availability",
        "zone_id",
        "instance_profile_arn",
        "spot_bid_price_percent",
        "ebs_volume_type",
        "ebs_volume_count",
        "ebs_volume_size",
        "ebs_volume_iops",
        "ebs_volume_throughput",
    ]

    @validator("availability")
    def availability_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ("SPOT", "ON_DEMAND", "SPOT_WITH_FALLBACK"):
            raise ValueError(
                "must validate the enum values ('SPOT', 'ON_DEMAND', 'SPOT_WITH_FALLBACK')"
            )
        return v

    @validator("ebs_volume_type")
    def ebs_volume_type_validate_enum(cls, v):
        if v is None:
            return v

        if v not in ("GENERAL_PURPOSE_SSD", "THROUGHPUT_OPTIMIZED_HDD"):
            raise ValueError(
                "must validate the enum values ('GENERAL_PURPOSE_SSD', 'THROUGHPUT_OPTIMIZED_HDD')"
            )
        return v

    class Config:
        allow_population_by_field_name = True
        validate_assignment = True

    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) -> AwsAttributes:
        """Create an instance of AwsAttributes from a JSON string"""
        return cls.from_dict(json.loads(json_str))

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        _dict = self.dict(by_alias=True, exclude={}, exclude_none=True)
        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> AwsAttributes:
        """Create an instance of AwsAttributes from a dict"""
        if obj is None:
            return None

        if type(obj) is not dict:
            return AwsAttributes.parse_obj(obj)

        _obj = AwsAttributes.parse_obj(
            {
                "first_on_demand": obj.get("first_on_demand"),
                "availability": obj.get("availability"),
                "zone_id": obj.get("zone_id"),
                "instance_profile_arn": obj.get("instance_profile_arn"),
                "spot_bid_price_percent": obj.get("spot_bid_price_percent"),
                "ebs_volume_type": obj.get("ebs_volume_type"),
                "ebs_volume_count": obj.get("ebs_volume_count"),
                "ebs_volume_size": obj.get("ebs_volume_size"),
                "ebs_volume_iops": obj.get("ebs_volume_iops"),
                "ebs_volume_throughput": obj.get("ebs_volume_throughput"),
            }
        )
        return _obj
