# 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, conlist

from databricks_jobs.models.cluster_instance import ClusterInstance
from databricks_jobs.models.cluster_spec import ClusterSpec
from databricks_jobs.models.cron_schedule import CronSchedule
from databricks_jobs.models.git_source import GitSource
from databricks_jobs.models.job_cluster import JobCluster
from databricks_jobs.models.run_parameters import RunParameters
from databricks_jobs.models.run_state import RunState
from databricks_jobs.models.run_task import RunTask
from databricks_jobs.models.run_type import RunType
from databricks_jobs.models.trigger_type import TriggerType


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

    Do not edit the class manually.
    """

    job_id: Optional[StrictInt] = Field(
        None, description="The canonical identifier of the job that contains this run."
    )
    run_id: Optional[StrictInt] = Field(
        None,
        description="The canonical identifier of the run. This ID is unique across all runs of all jobs.",
    )
    number_in_job: Optional[StrictInt] = Field(
        None,
        description="A unique identifier for this job run. This is set to the same value as `run_id`.",
    )
    creator_user_name: Optional[StrictStr] = Field(
        None,
        description="The creator user name. This field won’t be included in the response if the user has already been deleted.",
    )
    original_attempt_run_id: Optional[StrictInt] = Field(
        None,
        description="If this run is a retry of a prior run attempt, this field contains the run_id of the original attempt; otherwise, it is the same as the run_id.",
    )
    state: Optional[RunState] = None
    schedule: Optional[CronSchedule] = None
    tasks: Optional[conlist(RunTask, max_items=100)] = Field(
        None,
        description="The list of tasks performed by the run. Each task has its own `run_id` which you can use to call `JobsGetOutput` to retrieve the run resutls.",
    )
    job_clusters: Optional[conlist(JobCluster, max_items=100)] = Field(
        None,
        description="A list of job cluster specifications that can be shared and reused by tasks of this job. Libraries cannot be declared in a shared job cluster. You must declare dependent libraries in task settings.",
    )
    cluster_spec: Optional[ClusterSpec] = None
    cluster_instance: Optional[ClusterInstance] = None
    git_source: Optional[GitSource] = None
    overriding_parameters: Optional[RunParameters] = None
    start_time: Optional[StrictInt] = Field(
        None,
        description="The time at which this run was started in epoch milliseconds (milliseconds since 1/1/1970 UTC). This may not be the time when the job task starts executing, for example, if the job is scheduled to run on a new cluster, this is the time the cluster creation call is issued.",
    )
    setup_duration: Optional[StrictInt] = Field(
        None,
        description="The time in milliseconds it took to set up the cluster. For runs that run on new clusters this is the cluster creation time, for runs that run on existing clusters this time should be very short. The duration of a task run is the sum of the `setup_duration`, `execution_duration`, and the `cleanup_duration`. The `setup_duration` field is set to 0 for multitask job runs. The total duration of a multitask job run is the value of the `run_duration` field.",
    )
    execution_duration: Optional[StrictInt] = Field(
        None,
        description="The time in milliseconds it took to execute the commands in the JAR or notebook until they  completed, failed, timed out, were cancelled, or encountered an unexpected error. The duration of a task run is the sum of the `setup_duration`, `execution_duration`, and the  `cleanup_duration`. The `execution_duration` field is set to 0 for multitask job runs. The total  duration of a multitask job run is the value of the `run_duration` field.",
    )
    cleanup_duration: Optional[StrictInt] = Field(
        None,
        description="The time in milliseconds it took to terminate the cluster and clean up any associated artifacts. The duration of a task run is the sum of the `setup_duration`, `execution_duration`, and the `cleanup_duration`. The `cleanup_duration` field is set to 0 for multitask job runs. The total duration of a multitask job run is the value of the `run_duration` field.",
    )
    end_time: Optional[StrictInt] = Field(
        None,
        description="The time at which this run ended in epoch milliseconds (milliseconds since 1/1/1970 UTC). This field is set to 0 if the job is still running.",
    )
    run_duration: Optional[StrictInt] = Field(
        None,
        description="The time in milliseconds it took the job run and all of its repairs to finish. This field is only set for multitask job runs and not task runs. The duration of a task run is the sum of the `setup_duration`, `execution_duration`, and the `cleanup_duration`.",
    )
    trigger: Optional[TriggerType] = None
    run_name: Optional[StrictStr] = Field(
        "Untitled",
        description="An optional name for the run. The maximum allowed length is 4096 bytes in UTF-8 encoding.",
    )
    run_page_url: Optional[StrictStr] = Field(
        None, description="The URL to the detail page of the run."
    )
    run_type: Optional[RunType] = None
    attempt_number: Optional[StrictInt] = Field(
        None,
        description="The sequence number of this run attempt for a triggered job run. The initial attempt of a run has an attempt_number of 0\\. If the initial run attempt fails, and the job has a retry policy (`max_retries` \\> 0), subsequent runs are created with an `original_attempt_run_id` of the original attempt’s ID and an incrementing `attempt_number`. Runs are retried only until they succeed, and the maximum `attempt_number` is the same as the `max_retries` value for the job.",
    )
    __properties = [
        "job_id",
        "run_id",
        "number_in_job",
        "creator_user_name",
        "original_attempt_run_id",
        "state",
        "schedule",
        "tasks",
        "job_clusters",
        "cluster_spec",
        "cluster_instance",
        "git_source",
        "overriding_parameters",
        "start_time",
        "setup_duration",
        "execution_duration",
        "cleanup_duration",
        "end_time",
        "run_duration",
        "trigger",
        "run_name",
        "run_page_url",
        "run_type",
        "attempt_number",
    ]

    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) -> Run:
        """Create an instance of Run 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)
        # override the default output from pydantic by calling `to_dict()` of state
        if self.state:
            _dict["state"] = self.state.to_dict()
        # override the default output from pydantic by calling `to_dict()` of schedule
        if self.schedule:
            _dict["schedule"] = self.schedule.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in tasks (list)
        _items = []
        if self.tasks:
            for _item in self.tasks:
                if _item:
                    _items.append(_item.to_dict())
            _dict["tasks"] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in job_clusters (list)
        _items = []
        if self.job_clusters:
            for _item in self.job_clusters:
                if _item:
                    _items.append(_item.to_dict())
            _dict["job_clusters"] = _items
        # override the default output from pydantic by calling `to_dict()` of cluster_spec
        if self.cluster_spec:
            _dict["cluster_spec"] = self.cluster_spec.to_dict()
        # override the default output from pydantic by calling `to_dict()` of cluster_instance
        if self.cluster_instance:
            _dict["cluster_instance"] = self.cluster_instance.to_dict()
        # override the default output from pydantic by calling `to_dict()` of git_source
        if self.git_source:
            _dict["git_source"] = self.git_source.to_dict()
        # override the default output from pydantic by calling `to_dict()` of overriding_parameters
        if self.overriding_parameters:
            _dict["overriding_parameters"] = self.overriding_parameters.to_dict()
        return _dict

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

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

        _obj = Run.parse_obj(
            {
                "job_id": obj.get("job_id"),
                "run_id": obj.get("run_id"),
                "number_in_job": obj.get("number_in_job"),
                "creator_user_name": obj.get("creator_user_name"),
                "original_attempt_run_id": obj.get("original_attempt_run_id"),
                "state": RunState.from_dict(obj.get("state"))
                if obj.get("state") is not None
                else None,
                "schedule": CronSchedule.from_dict(obj.get("schedule"))
                if obj.get("schedule") is not None
                else None,
                "tasks": [RunTask.from_dict(_item) for _item in obj.get("tasks")]
                if obj.get("tasks") is not None
                else None,
                "job_clusters": [
                    JobCluster.from_dict(_item) for _item in obj.get("job_clusters")
                ]
                if obj.get("job_clusters") is not None
                else None,
                "cluster_spec": ClusterSpec.from_dict(obj.get("cluster_spec"))
                if obj.get("cluster_spec") is not None
                else None,
                "cluster_instance": ClusterInstance.from_dict(
                    obj.get("cluster_instance")
                )
                if obj.get("cluster_instance") is not None
                else None,
                "git_source": GitSource.from_dict(obj.get("git_source"))
                if obj.get("git_source") is not None
                else None,
                "overriding_parameters": RunParameters.from_dict(
                    obj.get("overriding_parameters")
                )
                if obj.get("overriding_parameters") is not None
                else None,
                "start_time": obj.get("start_time"),
                "setup_duration": obj.get("setup_duration"),
                "execution_duration": obj.get("execution_duration"),
                "cleanup_duration": obj.get("cleanup_duration"),
                "end_time": obj.get("end_time"),
                "run_duration": obj.get("run_duration"),
                "trigger": obj.get("trigger"),
                "run_name": obj.get("run_name")
                if obj.get("run_name") is not None
                else "Untitled",
                "run_page_url": obj.get("run_page_url"),
                "run_type": obj.get("run_type"),
                "attempt_number": obj.get("attempt_number"),
            }
        )
        return _obj
