# 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, StrictStr
from typing import Any, ClassVar, Dict, List, Optional
from airflow_client.client.models.dag_run_state import DagRunState
from airflow_client.client.models.dag_run_triggered_by_type import DagRunTriggeredByType
from airflow_client.client.models.dag_run_type import DagRunType
from airflow_client.client.models.dag_version_response import DagVersionResponse
from typing import Optional, Set
from typing_extensions import Self

class DAGRunResponse(BaseModel):
    """
    DAG Run serializer for responses.
    """ # noqa: E501
    bundle_version: Optional[StrictStr] = None
    conf: Dict[str, Any]
    dag_id: StrictStr
    dag_run_id: StrictStr
    dag_versions: List[DagVersionResponse]
    data_interval_end: Optional[datetime] = None
    data_interval_start: Optional[datetime] = None
    end_date: Optional[datetime] = None
    last_scheduling_decision: Optional[datetime] = None
    logical_date: Optional[datetime] = None
    note: Optional[StrictStr] = None
    queued_at: Optional[datetime] = None
    run_after: datetime
    run_type: DagRunType
    start_date: Optional[datetime] = None
    state: DagRunState
    triggered_by: Optional[DagRunTriggeredByType] = None
    __properties: ClassVar[List[str]] = ["bundle_version", "conf", "dag_id", "dag_run_id", "dag_versions", "data_interval_end", "data_interval_start", "end_date", "last_scheduling_decision", "logical_date", "note", "queued_at", "run_after", "run_type", "start_date", "state", "triggered_by"]

    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 DAGRunResponse 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 dag_versions (list)
        _items = []
        if self.dag_versions:
            for _item_dag_versions in self.dag_versions:
                if _item_dag_versions:
                    _items.append(_item_dag_versions.to_dict())
            _dict['dag_versions'] = _items
        return _dict

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

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

        _obj = cls.model_validate({
            "bundle_version": obj.get("bundle_version"),
            "conf": obj.get("conf"),
            "dag_id": obj.get("dag_id"),
            "dag_run_id": obj.get("dag_run_id"),
            "dag_versions": [DagVersionResponse.from_dict(_item) for _item in obj["dag_versions"]] if obj.get("dag_versions") is not None else None,
            "data_interval_end": obj.get("data_interval_end"),
            "data_interval_start": obj.get("data_interval_start"),
            "end_date": obj.get("end_date"),
            "last_scheduling_decision": obj.get("last_scheduling_decision"),
            "logical_date": obj.get("logical_date"),
            "note": obj.get("note"),
            "queued_at": obj.get("queued_at"),
            "run_after": obj.get("run_after"),
            "run_type": obj.get("run_type"),
            "start_date": obj.get("start_date"),
            "state": obj.get("state"),
            "triggered_by": obj.get("triggered_by")
        })
        return _obj


