# coding: utf-8

"""
    InductivaWebAPI

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

    The version of the OpenAPI document: 0.1.0
    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 datetime import datetime
from pydantic import BaseModel, ConfigDict, StrictBool, StrictFloat, StrictInt, StrictStr
from typing import Any, ClassVar, Dict, List, Optional, Union
from inductiva.client.models.compression_method import CompressionMethod
from inductiva.client.models.executer import Executer
from inductiva.client.models.task_machine_operation import TaskMachineOperation
from inductiva.client.models.task_metrics import TaskMetrics
from inductiva.client.models.task_status_code import TaskStatusCode
from inductiva.client.models.task_status_info import TaskStatusInfo
from inductiva.client.models.task_step import TaskStep
from typing import Optional, Set
from typing_extensions import Self


class TaskWithStatusHistory(BaseModel):
    """
    TaskWithStatusHistory
    """

  # noqa: E501
    task_id: StrictStr
    status: TaskStatusCode
    status_alias: StrictStr
    simulator: StrictStr
    storage_path: Optional[StrictStr] = None
    storage_input_path: Optional[StrictStr] = None
    storage_output_path: Optional[StrictStr] = None
    container_image: Optional[StrictStr] = None
    project: StrictStr
    is_terminated: StrictBool
    create_time: Optional[datetime] = None
    input_submit_time: Optional[datetime] = None
    start_time: Optional[datetime] = None
    computation_start_time: Optional[datetime] = None
    computation_end_time: Optional[datetime] = None
    end_time: Optional[datetime] = None
    estimated_computation_cost: Optional[Union[StrictFloat, StrictInt]] = None
    metrics: Optional[TaskMetrics] = None
    executer: Optional[Executer] = None
    machine_group_name: Optional[StrictStr] = None
    machine_group_id: Optional[StrictStr] = None
    error_detail: Optional[StrictStr] = None
    input_resources: Optional[List[StrictStr]] = None
    stream_zip: Optional[StrictBool] = True
    num_retries: StrictInt
    compress_with: Optional[CompressionMethod] = None
    task_metadata: Optional[Dict[str, StrictStr]] = None
    extra_params: Optional[Dict[str, Any]] = None
    resubmit_on_preemption: Optional[StrictBool] = False
    duration_seconds: Optional[Union[StrictFloat, StrictInt]]
    status_history: List[TaskStatusInfo]
    machine_operations: List[TaskMachineOperation]
    steps: Optional[List[TaskStep]] = None
    __properties: ClassVar[List[str]] = [
        "task_id", "status", "status_alias", "simulator", "storage_path",
        "storage_input_path", "storage_output_path", "container_image",
        "project", "is_terminated", "create_time", "input_submit_time",
        "start_time", "computation_start_time", "computation_end_time",
        "end_time", "estimated_computation_cost", "metrics", "executer",
        "machine_group_name", "machine_group_id", "error_detail",
        "input_resources", "stream_zip", "num_retries", "compress_with",
        "task_metadata", "extra_params", "resubmit_on_preemption",
        "duration_seconds", "status_history", "machine_operations", "steps"
    ]

    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 TaskWithStatusHistory 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 metrics
        if self.metrics:
            _dict['metrics'] = self.metrics.to_dict()
        # override the default output from pydantic by calling `to_dict()` of executer
        if self.executer:
            _dict['executer'] = self.executer.to_dict()
        # override the default output from pydantic by calling `to_dict()` of each item in status_history (list)
        _items = []
        if self.status_history:
            for _item_status_history in self.status_history:
                if _item_status_history:
                    _items.append(_item_status_history.to_dict())
            _dict['status_history'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in machine_operations (list)
        _items = []
        if self.machine_operations:
            for _item_machine_operations in self.machine_operations:
                if _item_machine_operations:
                    _items.append(_item_machine_operations.to_dict())
            _dict['machine_operations'] = _items
        # override the default output from pydantic by calling `to_dict()` of each item in steps (list)
        _items = []
        if self.steps:
            for _item_steps in self.steps:
                if _item_steps:
                    _items.append(_item_steps.to_dict())
            _dict['steps'] = _items
        # set to None if storage_path (nullable) is None
        # and model_fields_set contains the field
        if self.storage_path is None and "storage_path" in self.model_fields_set:
            _dict['storage_path'] = None

        # set to None if storage_input_path (nullable) is None
        # and model_fields_set contains the field
        if self.storage_input_path is None and "storage_input_path" in self.model_fields_set:
            _dict['storage_input_path'] = None

        # set to None if storage_output_path (nullable) is None
        # and model_fields_set contains the field
        if self.storage_output_path is None and "storage_output_path" in self.model_fields_set:
            _dict['storage_output_path'] = None

        # set to None if container_image (nullable) is None
        # and model_fields_set contains the field
        if self.container_image is None and "container_image" in self.model_fields_set:
            _dict['container_image'] = None

        # set to None if create_time (nullable) is None
        # and model_fields_set contains the field
        if self.create_time is None and "create_time" in self.model_fields_set:
            _dict['create_time'] = None

        # set to None if input_submit_time (nullable) is None
        # and model_fields_set contains the field
        if self.input_submit_time is None and "input_submit_time" in self.model_fields_set:
            _dict['input_submit_time'] = None

        # set to None if start_time (nullable) is None
        # and model_fields_set contains the field
        if self.start_time is None and "start_time" in self.model_fields_set:
            _dict['start_time'] = None

        # set to None if computation_start_time (nullable) is None
        # and model_fields_set contains the field
        if self.computation_start_time is None and "computation_start_time" in self.model_fields_set:
            _dict['computation_start_time'] = None

        # set to None if computation_end_time (nullable) is None
        # and model_fields_set contains the field
        if self.computation_end_time is None and "computation_end_time" in self.model_fields_set:
            _dict['computation_end_time'] = None

        # set to None if end_time (nullable) is None
        # and model_fields_set contains the field
        if self.end_time is None and "end_time" in self.model_fields_set:
            _dict['end_time'] = None

        # set to None if estimated_computation_cost (nullable) is None
        # and model_fields_set contains the field
        if self.estimated_computation_cost is None and "estimated_computation_cost" in self.model_fields_set:
            _dict['estimated_computation_cost'] = None

        # set to None if metrics (nullable) is None
        # and model_fields_set contains the field
        if self.metrics is None and "metrics" in self.model_fields_set:
            _dict['metrics'] = None

        # set to None if executer (nullable) is None
        # and model_fields_set contains the field
        if self.executer is None and "executer" in self.model_fields_set:
            _dict['executer'] = None

        # set to None if machine_group_name (nullable) is None
        # and model_fields_set contains the field
        if self.machine_group_name is None and "machine_group_name" in self.model_fields_set:
            _dict['machine_group_name'] = None

        # set to None if machine_group_id (nullable) is None
        # and model_fields_set contains the field
        if self.machine_group_id is None and "machine_group_id" in self.model_fields_set:
            _dict['machine_group_id'] = None

        # set to None if error_detail (nullable) is None
        # and model_fields_set contains the field
        if self.error_detail is None and "error_detail" in self.model_fields_set:
            _dict['error_detail'] = None

        # set to None if task_metadata (nullable) is None
        # and model_fields_set contains the field
        if self.task_metadata is None and "task_metadata" in self.model_fields_set:
            _dict['task_metadata'] = None

        # set to None if extra_params (nullable) is None
        # and model_fields_set contains the field
        if self.extra_params is None and "extra_params" in self.model_fields_set:
            _dict['extra_params'] = None

        # set to None if duration_seconds (nullable) is None
        # and model_fields_set contains the field
        if self.duration_seconds is None and "duration_seconds" in self.model_fields_set:
            _dict['duration_seconds'] = None

        return _dict

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

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

        _obj = cls.model_validate({
            "task_id":
                obj.get("task_id"),
            "status":
                obj.get("status"),
            "status_alias":
                obj.get("status_alias"),
            "simulator":
                obj.get("simulator"),
            "storage_path":
                obj.get("storage_path"),
            "storage_input_path":
                obj.get("storage_input_path"),
            "storage_output_path":
                obj.get("storage_output_path"),
            "container_image":
                obj.get("container_image"),
            "project":
                obj.get("project"),
            "is_terminated":
                obj.get("is_terminated"),
            "create_time":
                obj.get("create_time"),
            "input_submit_time":
                obj.get("input_submit_time"),
            "start_time":
                obj.get("start_time"),
            "computation_start_time":
                obj.get("computation_start_time"),
            "computation_end_time":
                obj.get("computation_end_time"),
            "end_time":
                obj.get("end_time"),
            "estimated_computation_cost":
                obj.get("estimated_computation_cost"),
            "metrics":
                TaskMetrics.from_dict(obj["metrics"])
                if obj.get("metrics") is not None else None,
            "executer":
                Executer.from_dict(obj["executer"])
                if obj.get("executer") is not None else None,
            "machine_group_name":
                obj.get("machine_group_name"),
            "machine_group_id":
                obj.get("machine_group_id"),
            "error_detail":
                obj.get("error_detail"),
            "input_resources":
                obj.get("input_resources"),
            "stream_zip":
                obj.get("stream_zip")
                if obj.get("stream_zip") is not None else True,
            "num_retries":
                obj.get("num_retries"),
            "compress_with":
                obj.get("compress_with"),
            "task_metadata":
                obj.get("task_metadata"),
            "extra_params":
                obj.get("extra_params"),
            "resubmit_on_preemption":
                obj.get("resubmit_on_preemption")
                if obj.get("resubmit_on_preemption") is not None else False,
            "duration_seconds":
                obj.get("duration_seconds"),
            "status_history": [
                TaskStatusInfo.from_dict(_item)
                for _item in obj["status_history"]
            ] if obj.get("status_history") is not None else None,
            "machine_operations": [
                TaskMachineOperation.from_dict(_item)
                for _item in obj["machine_operations"]
            ] if obj.get("machine_operations") is not None else None,
            "steps": [TaskStep.from_dict(_item) for _item in obj["steps"]]
                     if obj.get("steps") is not None else None
        })
        return _obj
