# coding: utf-8
"""
    Snowflake Task API

    The Snowflake Task API is a REST API that you can use to access, update, and perform certain actions on task resources in a Snowflake database.  # noqa: E501

    The version of the OpenAPI document: 0.0.1
    Contact: support@snowflake.com
    Generated by: https://openapi-generator.tech

    Do not edit this file manually.
"""

from __future__ import annotations
import pprint
import re  # noqa: F401
import json

from typing import Union

from snowflake.core.task._generated.models.task_schedule import TaskSchedule

from datetime import datetime

from pydantic import BaseModel, ConfigDict, Field, StrictBool, StrictInt, StrictStr, field_validator

from typing import Any, ClassVar, Dict, List, Optional

from typing_extensions import Annotated


class Task(BaseModel):

    name: Annotated[str, Field(strict=True)]

    warehouse: Optional[Annotated[str, Field(strict=True)]] = None

    schedule: Optional[TaskSchedule] = None

    comment: Optional[StrictStr] = None

    finalize: Optional[StrictStr] = None

    task_auto_retry_attempts: Optional[Annotated[
        int, Field(le=30, strict=True, ge=0)]] = None

    config: Optional[Dict[str, Any]] = None

    session_parameters: Optional[Dict[str, Any]] = None

    definition: StrictStr

    predecessors: Optional[List[StrictStr]] = None

    task_relations: Optional[StrictStr] = None

    user_task_managed_initial_warehouse_size: Optional[StrictStr] = None

    user_task_timeout_ms: Optional[StrictInt] = None

    suspend_task_after_num_failures: Optional[StrictInt] = None

    condition: Optional[StrictStr] = None

    allow_overlapping_execution: Optional[StrictBool] = None

    error_integration: Optional[StrictStr] = None

    created_on: Optional[datetime] = None

    id: Optional[StrictStr] = None

    owner: Optional[StrictStr] = None

    owner_role_type: Optional[StrictStr] = None

    state: Optional[StrictStr] = None

    last_committed_on: Optional[datetime] = None

    last_suspended_on: Optional[datetime] = None

    database_name: Optional[StrictStr] = None

    schema_name: Optional[StrictStr] = None

    __properties = [
        "name", "warehouse", "schedule", "comment", "finalize",
        "task_auto_retry_attempts", "config", "session_parameters",
        "definition", "predecessors", "task_relations",
        "user_task_managed_initial_warehouse_size", "user_task_timeout_ms",
        "suspend_task_after_num_failures", "condition",
        "allow_overlapping_execution", "error_integration", "created_on", "id",
        "owner", "owner_role_type", "state", "last_committed_on",
        "last_suspended_on", "database_name", "schema_name"
    ]

    @field_validator('name')
    def name_validate_regular_expression(cls, v):

        if not re.match(r"""^\"([^\"]|\"\")+\"|[a-zA-Z_][a-zA-Z0-9_$]*$""", v):
            raise ValueError(
                r"""must validate the regular expression /^"([^"]|"")+"|[a-zA-Z_][a-zA-Z0-9_$]*$/"""
            )
        return v

    @field_validator('warehouse')
    def warehouse_validate_regular_expression(cls, v):

        if v is None:
            return v
        if not re.match(r"""^\"([^\"]|\"\")+\"|[a-zA-Z_][a-zA-Z0-9_$]*$""", v):
            raise ValueError(
                r"""must validate the regular expression /^"([^"]|"")+"|[a-zA-Z_][a-zA-Z0-9_$]*$/"""
            )
        return v

    @field_validator('state')
    def state_validate_enum(cls, v):

        if v is None:
            return v
        if v not in ('started', 'suspended'):
            raise ValueError("must validate the enum values ()")
        return v

    class Config:
        populate_by_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) -> Task:
        """Create an instance of Task 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 = dict(
            self._iter(to_dict=True,
                       by_alias=True,
                       exclude={
                           "task_relations",
                           "created_on",
                           "id",
                           "owner",
                           "owner_role_type",
                           "state",
                           "last_committed_on",
                           "last_suspended_on",
                           "database_name",
                           "schema_name",
                       },
                       exclude_none=True))

        # override the default output from pydantic by calling `to_dict()` of schedule
        if self.schedule:
            _dict['schedule'] = self.schedule.to_dict()

        return _dict

    @classmethod
    def from_dict(cls, obj: dict) -> Task:
        """Create an instance of Task from a dict"""

        if obj is None:
            return None

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

        _obj = Task.parse_obj({
            "name":
            obj.get("name"),
            "warehouse":
            obj.get("warehouse"),
            "schedule":
            TaskSchedule.from_dict(obj.get("schedule"))
            if obj.get("schedule") is not None else None,
            "comment":
            obj.get("comment"),
            "finalize":
            obj.get("finalize"),
            "task_auto_retry_attempts":
            obj.get("task_auto_retry_attempts"),
            "config":
            obj.get("config"),
            "session_parameters":
            obj.get("session_parameters"),
            "definition":
            obj.get("definition"),
            "predecessors":
            obj.get("predecessors"),
            "task_relations":
            obj.get("task_relations"),
            "user_task_managed_initial_warehouse_size":
            obj.get("user_task_managed_initial_warehouse_size"),
            "user_task_timeout_ms":
            obj.get("user_task_timeout_ms"),
            "suspend_task_after_num_failures":
            obj.get("suspend_task_after_num_failures"),
            "condition":
            obj.get("condition"),
            "allow_overlapping_execution":
            obj.get("allow_overlapping_execution"),
            "error_integration":
            obj.get("error_integration"),
            "created_on":
            obj.get("created_on"),
            "id":
            obj.get("id"),
            "owner":
            obj.get("owner"),
            "owner_role_type":
            obj.get("owner_role_type"),
            "state":
            obj.get("state"),
            "last_committed_on":
            obj.get("last_committed_on"),
            "last_suspended_on":
            obj.get("last_suspended_on"),
            "database_name":
            obj.get("database_name"),
            "schema_name":
            obj.get("schema_name"),
        })

        return _obj


from typing import Optional, List, Dict

from snowflake.core.task._generated.models.task_schedule import TaskSchedule


class TaskModel():

    def __init__(
        self,
        name: str,
        definition: str,
        # optional properties
        warehouse: Optional[str] = None,
        schedule: Optional[TaskSchedule] = None,
        comment: Optional[str] = None,
        finalize: Optional[str] = None,
        task_auto_retry_attempts: Optional[int] = None,
        config: Optional[object] = None,
        session_parameters: Optional[object] = None,
        predecessors: Optional[List[str]] = None,
        task_relations: Optional[str] = None,
        user_task_managed_initial_warehouse_size: Optional[str] = None,
        user_task_timeout_ms: Optional[int] = None,
        suspend_task_after_num_failures: Optional[int] = None,
        condition: Optional[str] = None,
        allow_overlapping_execution: Optional[bool] = None,
        error_integration: Optional[str] = None,
        created_on: Optional[datetime] = None,
        id: Optional[str] = None,
        owner: Optional[str] = None,
        owner_role_type: Optional[str] = None,
        state: Optional[str] = None,
        last_committed_on: Optional[datetime] = None,
        last_suspended_on: Optional[datetime] = None,
        database_name: Optional[str] = None,
        schema_name: Optional[str] = None,
    ):

        self.name = name
        self.warehouse = warehouse
        self.schedule = schedule
        self.comment = comment
        self.finalize = finalize
        self.task_auto_retry_attempts = task_auto_retry_attempts
        self.config = config
        self.session_parameters = session_parameters
        self.definition = definition
        self.predecessors = predecessors
        self.task_relations = task_relations
        self.user_task_managed_initial_warehouse_size = user_task_managed_initial_warehouse_size
        self.user_task_timeout_ms = user_task_timeout_ms
        self.suspend_task_after_num_failures = suspend_task_after_num_failures
        self.condition = condition
        self.allow_overlapping_execution = allow_overlapping_execution
        self.error_integration = error_integration
        self.created_on = created_on
        self.id = id
        self.owner = owner
        self.owner_role_type = owner_role_type
        self.state = state
        self.last_committed_on = last_committed_on
        self.last_suspended_on = last_suspended_on
        self.database_name = database_name
        self.schema_name = schema_name

    __properties = [
        "name", "warehouse", "schedule", "comment", "finalize",
        "task_auto_retry_attempts", "config", "session_parameters",
        "definition", "predecessors", "task_relations",
        "user_task_managed_initial_warehouse_size", "user_task_timeout_ms",
        "suspend_task_after_num_failures", "condition",
        "allow_overlapping_execution", "error_integration", "created_on", "id",
        "owner", "owner_role_type", "state", "last_committed_on",
        "last_suspended_on", "database_name", "schema_name"
    ]

    def _to_model(self):
        return Task(
            name=self.name,
            warehouse=self.warehouse,
            schedule=self.schedule._to_model()
            if self.schedule is not None else None,
            comment=self.comment,
            finalize=self.finalize,
            task_auto_retry_attempts=self.task_auto_retry_attempts,
            config=self.config,
            session_parameters=self.session_parameters,
            definition=self.definition,
            predecessors=self.predecessors,
            task_relations=self.task_relations,
            user_task_managed_initial_warehouse_size=self.
            user_task_managed_initial_warehouse_size,
            user_task_timeout_ms=self.user_task_timeout_ms,
            suspend_task_after_num_failures=self.
            suspend_task_after_num_failures,
            condition=self.condition,
            allow_overlapping_execution=self.allow_overlapping_execution,
            error_integration=self.error_integration,
            created_on=self.created_on,
            id=self.id,
            owner=self.owner,
            owner_role_type=self.owner_role_type,
            state=self.state,
            last_committed_on=self.last_committed_on,
            last_suspended_on=self.last_suspended_on,
            database_name=self.database_name,
            schema_name=self.schema_name,
        )

    @classmethod
    def _from_model(cls, model) -> TaskModel:
        return TaskModel(
            name=model.name,
            warehouse=model.warehouse,
            schedule=TaskScheduleModel._from_model(model.schedule)
            if model.schedule is not None else None,
            comment=model.comment,
            finalize=model.finalize,
            task_auto_retry_attempts=model.task_auto_retry_attempts,
            config=model.config,
            session_parameters=model.session_parameters,
            definition=model.definition,
            predecessors=model.predecessors,
            task_relations=model.task_relations,
            user_task_managed_initial_warehouse_size=model.
            user_task_managed_initial_warehouse_size,
            user_task_timeout_ms=model.user_task_timeout_ms,
            suspend_task_after_num_failures=model.
            suspend_task_after_num_failures,
            condition=model.condition,
            allow_overlapping_execution=model.allow_overlapping_execution,
            error_integration=model.error_integration,
            created_on=model.created_on,
            id=model.id,
            owner=model.owner,
            owner_role_type=model.owner_role_type,
            state=model.state,
            last_committed_on=model.last_committed_on,
            last_suspended_on=model.last_suspended_on,
            database_name=model.database_name,
            schema_name=model.schema_name,
        )

    def to_dict(self):
        """Returns the dictionary representation of the model using alias"""
        return self._to_model().to_dict()

    @classmethod
    def from_dict(cls, obj: dict) -> TaskModel:
        """Create an instance of Task from a dict"""
        return cls._from_model(Task.from_dict(obj))


Task._model_class = TaskModel
