# coding: utf-8

"""
    Airflow API

    Airflow API. All endpoints located under ``/api/v2`` can be used safely, are stable and backward compatible. Endpoints located under ``/ui`` are dedicated to the UI and are subject to breaking change depending on the need of the frontend. Users should not rely on those but use the public ones instead.

    The version of the OpenAPI document: 2
    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, Field, StrictBool, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from airflow_client.client.models.clear_task_instances_body_task_ids_inner import ClearTaskInstancesBodyTaskIdsInner
from typing import Optional, Set
from typing_extensions import Self

class ClearTaskInstancesBody(BaseModel):
    """
    Request body for Clear Task Instances endpoint.
    """ # noqa: E501
    dag_run_id: Optional[StrictStr] = None
    dry_run: Optional[StrictBool] = True
    end_date: Optional[datetime] = None
    include_downstream: Optional[StrictBool] = False
    include_future: Optional[StrictBool] = False
    include_past: Optional[StrictBool] = False
    include_upstream: Optional[StrictBool] = False
    only_failed: Optional[StrictBool] = True
    only_running: Optional[StrictBool] = False
    reset_dag_runs: Optional[StrictBool] = True
    run_on_latest_version: Optional[StrictBool] = Field(default=False, description="(Experimental) Run on the latest bundle version of the dag after clearing the task instances.")
    start_date: Optional[datetime] = None
    task_ids: Optional[List[ClearTaskInstancesBodyTaskIdsInner]] = None
    __properties: ClassVar[List[str]] = ["dag_run_id", "dry_run", "end_date", "include_downstream", "include_future", "include_past", "include_upstream", "only_failed", "only_running", "reset_dag_runs", "run_on_latest_version", "start_date", "task_ids"]

    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 ClearTaskInstancesBody 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 each item in task_ids (list)
        _items = []
        if self.task_ids:
            for _item_task_ids in self.task_ids:
                if _item_task_ids:
                    _items.append(_item_task_ids.to_dict())
            _dict['task_ids'] = _items
        return _dict

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

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

        _obj = cls.model_validate({
            "dag_run_id": obj.get("dag_run_id"),
            "dry_run": obj.get("dry_run") if obj.get("dry_run") is not None else True,
            "end_date": obj.get("end_date"),
            "include_downstream": obj.get("include_downstream") if obj.get("include_downstream") is not None else False,
            "include_future": obj.get("include_future") if obj.get("include_future") is not None else False,
            "include_past": obj.get("include_past") if obj.get("include_past") is not None else False,
            "include_upstream": obj.get("include_upstream") if obj.get("include_upstream") is not None else False,
            "only_failed": obj.get("only_failed") if obj.get("only_failed") is not None else True,
            "only_running": obj.get("only_running") if obj.get("only_running") is not None else False,
            "reset_dag_runs": obj.get("reset_dag_runs") if obj.get("reset_dag_runs") is not None else True,
            "run_on_latest_version": obj.get("run_on_latest_version") if obj.get("run_on_latest_version") is not None else False,
            "start_date": obj.get("start_date"),
            "task_ids": [ClearTaskInstancesBodyTaskIdsInner.from_dict(_item) for _item in obj["task_ids"]] if obj.get("task_ids") is not None else None
        })
        return _obj


