# coding: utf-8

"""
Earnix Elevate Data API

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

The version of the OpenAPI document: 0.0.1
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

from __future__ import annotations

import json
import pprint
from datetime import datetime
from typing import Optional

from pydantic.v1 import Field, StrictBool, StrictInt, StrictStr, constr, validator

from earnix_elevate.clients.data.models.data_set_node_response import (
    DataSetNodeResponse,
)
from earnix_elevate.clients.data.models.user_response import UserResponse


class DataSetRecipeNodeResponse(DataSetNodeResponse):
    """
    `DataSetRecipeNodeResponse`
    """

    recipe_id: Optional[StrictInt] = Field(
        default=None,
        alias="recipeId",
        description="Unique identifier of the recipe definition associated with this node",
    )
    recipe_type: Optional[StrictStr] = Field(
        default=None,
        alias="recipeType",
        description="Recipe type (TRANSFORMATION for data processing, STRUCTURE for schema modifications)",
    )
    code: Optional[constr(strict=True, max_length=10000, min_length=3)] = Field(
        default=None, description="SQL code that defines the data transformation logic"
    )
    language: Optional[StrictStr] = Field(
        default=None,
        description="Programming language of the recipe (currently only SQL is supported)",
    )
    recipe_execution_status: Optional[StrictInt] = Field(
        default=None,
        alias="recipeExecutionStatus",
        description="Numeric status code indicating the current state of recipe execution (e.g., 0=PENDING, 1=IN_PROGRESS, 2=COMPLETED, 3=FAILED)",
    )
    error_code: Optional[StrictStr] = Field(
        default=None,
        alias="errorCode",
        description="Specific error code if the recipe execution failed, null if successful",
    )
    error_message: Optional[StrictStr] = Field(
        default=None,
        alias="errorMessage",
        description="Human-readable error message if the recipe execution failed, null if successful",
    )
    error_cause: Optional[StrictStr] = Field(
        default=None,
        alias="errorCause",
        description="Root cause of the error if the recipe execution failed, null if successful",
    )
    start_time: Optional[datetime] = Field(
        default=None,
        alias="startTime",
        description="Date and time when the recipe execution started, null if not yet started",
    )
    end_time: Optional[datetime] = Field(
        default=None,
        alias="endTime",
        description="Date and time when the recipe execution completed, null if still running or not started",
    )
    use_sample: Optional[StrictBool] = Field(
        default=None,
        alias="useSample",
        description="Whether the recipe was executed on a sample of the data instead of the complete dataset",
    )
    progress: Optional[StrictInt] = Field(
        default=None, description="Progress of the recipe execution in percentage"
    )
    last_run: Optional[datetime] = Field(
        default=None,
        alias="lastRun",
        description="Date and time when this entity was created",
    )
    run_by: Optional[UserResponse] = Field(default=None, alias="runBy")
    created_by: Optional[UserResponse] = Field(default=None, alias="createdBy")
    created_date: Optional[datetime] = Field(
        default=None,
        alias="createdDate",
        description="Date and time when this entity was created",
    )
    last_modified_by: Optional[UserResponse] = Field(
        default=None, alias="lastModifiedBy"
    )
    last_modified_date: Optional[datetime] = Field(
        default=None,
        alias="lastModifiedDate",
        description="Date and time when this entity was last modified",
    )
    __properties = [
        "nodeType",
        "name",
        "description",
        "tags",
        "id",
        "lockVersion",
        "recipeType",
        "code",
        "language",
        "recipeExecutionStatus",
        "errorCode",
        "errorMessage",
        "errorCause",
        "startTime",
        "endTime",
        "useSample",
        "progress",
        "lastRun",
        "runBy",
        "createdBy",
        "createdDate",
        "lastModifiedBy",
        "lastModifiedDate",
    ]

    @validator("recipe_type")
    def recipe_type_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in (
            "TRANSFORMATION",
            "STRUCTURE",
        ):
            raise ValueError(
                "must be one of enum values ('TRANSFORMATION', 'STRUCTURE')"
            )
        return value

    @validator("language")
    def language_validate_enum(cls, value):
        """Validates the enum"""
        if value is None:
            return value

        if value not in ("SQL",):
            raise ValueError("must be one of enum values ('SQL')")
        return value

    class Config:
        """Pydantic configuration"""

        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) -> DataSetRecipeNodeResponse:
        """Create an instance of DataSetRecipeNodeResponse 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 run_by
        if self.run_by:
            _dict["runBy"] = self.run_by.to_dict()
        # override the default output from pydantic by calling `to_dict()` of created_by
        if self.created_by:
            _dict["createdBy"] = self.created_by.to_dict()
        # override the default output from pydantic by calling `to_dict()` of last_modified_by
        if self.last_modified_by:
            _dict["lastModifiedBy"] = self.last_modified_by.to_dict()
        # set to None if description (nullable) is None
        # and __fields_set__ contains the field
        if self.description is None and "description" in self.__fields_set__:
            _dict["description"] = None

        # set to None if error_code (nullable) is None
        # and __fields_set__ contains the field
        if self.error_code is None and "error_code" in self.__fields_set__:
            _dict["errorCode"] = None

        # set to None if error_message (nullable) is None
        # and __fields_set__ contains the field
        if self.error_message is None and "error_message" in self.__fields_set__:
            _dict["errorMessage"] = None

        # set to None if error_cause (nullable) is None
        # and __fields_set__ contains the field
        if self.error_cause is None and "error_cause" in self.__fields_set__:
            _dict["errorCause"] = None

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

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

        return _dict

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

        if not isinstance(obj, dict):
            return DataSetRecipeNodeResponse.parse_obj(obj)

        _obj = DataSetRecipeNodeResponse.parse_obj(
            {
                "node_type": obj.get("nodeType"),
                "name": obj.get("name"),
                "description": obj.get("description"),
                "tags": obj.get("tags"),
                "id": obj.get("id"),
                "lock_version": obj.get("lockVersion"),
                "recipe_type": obj.get("recipeType"),
                "code": obj.get("code"),
                "language": obj.get("language"),
                "recipe_execution_status": obj.get("recipeExecutionStatus"),
                "error_code": obj.get("errorCode"),
                "error_message": obj.get("errorMessage"),
                "error_cause": obj.get("errorCause"),
                "start_time": obj.get("startTime"),
                "end_time": obj.get("endTime"),
                "use_sample": obj.get("useSample"),
                "progress": obj.get("progress"),
                "last_run": obj.get("lastRun"),
                "run_by": UserResponse.from_dict(obj.get("runBy"))
                if obj.get("runBy") is not None
                else None,
                "created_by": UserResponse.from_dict(obj.get("createdBy"))
                if obj.get("createdBy") is not None
                else None,
                "created_date": obj.get("createdDate"),
                "last_modified_by": UserResponse.from_dict(obj.get("lastModifiedBy"))
                if obj.get("lastModifiedBy") is not None
                else None,
                "last_modified_date": obj.get("lastModifiedDate"),
            }
        )
        return _obj
