"""
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 json
import pprint
import re

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

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

from snowflake.core.task._generated.models.minutes_schedule import MinutesSchedule, MinutesScheduleModel
from snowflake.core.task._generated.models.task_schedule import TaskSchedule, TaskScheduleModel


class Task(BaseModel):
    """A model object representing the Task resource.

    Constructs an object of type Task with the provided properties.

    Parameters
    __________
    name : str
        A Snowflake object identifier. If the identifier contains spaces or special characters, the entire string must be enclosed in double quotes. Identifiers enclosed in double quotes are also case-sensitive.
    definition : str
        The SQL definition for the task. Any one of single SQL statement, call to stored procedure, or procedural logic using Snowflake scripting.
    warehouse : str, optional
        A Snowflake object identifier. If the identifier contains spaces or special characters, the entire string must be enclosed in double quotes. Identifiers enclosed in double quotes are also case-sensitive.
    schedule : TaskSchedule, optional

    comment : str, optional
        Specifies a comment for the task.
    finalize : str, optional
        Specifies the name of the root task that the finalizer task is associated with.
    task_auto_retry_attempts : int, optional
        Root task settable only. Specifies the number of automatic task graph retry attempts. Valid range is 0 to 30. When not specified, no retry would happen.
    config : object, optional
        Task Config
    session_parameters : object, optional
        Session Parameters for the task at runtime.
    predecessors : list[str], optional
        Specifies one or more predecessor tasks for the current task
    task_relations : str, optional
        Displays the relationship between the root task and its corresponding finalizer tasks — **Read-only:** *any user-provided value will be ignored.*
    user_task_managed_initial_warehouse_size : str, optional
        Specifies the size of the compute resources to provision for the first run of the task. This parameter only applies to serverless tasks.
    target_completion_interval : MinutesSchedule, optional

    serverless_task_min_statement_size : str, optional
        Specifies the minimum allowed warehouse size for the serverless task. Minimum XSMALL, Maximum XXLARGE. This parameter only applies to serverless tasks.
    serverless_task_max_statement_size : str, optional
        Specifies the maximum allowed warehouse size for the serverless task. Minimum XSMALL, Maximum XXLARGE. This parameter only applies to serverless tasks.
    user_task_timeout_ms : int, optional
        Specifies the time limit on a single run of the task before it times out (in milliseconds).
    suspend_task_after_num_failures : int, optional
        Specifies the number of consecutive failed task runs after which the current task is suspended automatically.
    condition : str, optional
        Specifies a Boolean SQL expression condition; multiple conditions joined with AND/OR are supported
    allow_overlapping_execution : bool, optional
        Specifies whether to allow multiple instances of the DAG to run concurrently.
    error_integration : str, optional
        Specifies the name of the notification integration used to communicate with Amazon SNS, MS Azure Event Grid, or Google Pub/Sub.
    created_on : datetime, optional
        The time the task was created on — **Read-only:** *any user-provided value will be ignored.*
    id : str, optional
        An ID for the current task — **Read-only:** *any user-provided value will be ignored.*
    owner : str, optional
        The role that owns the task — **Read-only:** *any user-provided value will be ignored.*
    owner_role_type : str, optional
        The role type of the task owner — **Read-only:** *any user-provided value will be ignored.*
    state : str, optional
        The state of the task. Must be one of started or suspended — **Read-only:** *any user-provided value will be ignored.*
    last_committed_on : datetime, optional
        The time the task was last committed on — **Read-only:** *any user-provided value will be ignored.*
    last_suspended_on : datetime, optional
        The time the task was last suspended on — **Read-only:** *any user-provided value will be ignored.*
    database_name : str, optional
        The name of the parent database for the task — **Read-only:** *any user-provided value will be ignored.*
    schema_name : str, optional
        The name of the parent schema for the task — **Read-only:** *any user-provided value will be ignored.*
    """

    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

    target_completion_interval: Optional[MinutesSchedule] = None

    serverless_task_min_statement_size: Optional[StrictStr] = None

    serverless_task_max_statement_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",
        "target_completion_interval",
        "serverless_task_min_statement_size",
        "serverless_task_max_statement_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 ('started','suspended')")
        return v

    model_config = ConfigDict(
        validate_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,
        hide_readonly_properties: bool = False,
    ) -> dict[str, Any]:
        """Returns the dictionary representation of the model using alias."""
        exclude_properties = set()

        if hide_readonly_properties:
            exclude_properties.update(
                {
                    "task_relations",
                    "created_on",
                    "id",
                    "owner",
                    "owner_role_type",
                    "state",
                    "last_committed_on",
                    "last_suspended_on",
                    "database_name",
                    "schema_name",
                }
            )

        _dict = self.model_dump(serialize_as_any=True, by_alias=True, exclude=exclude_properties, exclude_none=True)

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

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

        return _dict

    def to_dict_without_readonly_properties(self) -> dict[str, Any]:
        """Return the dictionary representation of the model without readonly properties."""
        return self.to_dict(hide_readonly_properties=True)

    @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.model_validate(obj)

        _obj = Task.model_validate(
            {
                "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"),
                "target_completion_interval": MinutesSchedule.from_dict(obj.get("target_completion_interval"))
                if obj.get("target_completion_interval") is not None
                else None,
                "serverless_task_min_statement_size": obj.get("serverless_task_min_statement_size"),
                "serverless_task_max_statement_size": obj.get("serverless_task_max_statement_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


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,
        target_completion_interval: Optional[MinutesSchedule] = None,
        serverless_task_min_statement_size: Optional[str] = None,
        serverless_task_max_statement_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,
    ):
        """A model object representing the Task resource.

        Constructs an object of type Task with the provided properties.

        Parameters
        __________
        name : str
            A Snowflake object identifier. If the identifier contains spaces or special characters, the entire string must be enclosed in double quotes. Identifiers enclosed in double quotes are also case-sensitive.
        definition : str
            The SQL definition for the task. Any one of single SQL statement, call to stored procedure, or procedural logic using Snowflake scripting.
        warehouse : str, optional
            A Snowflake object identifier. If the identifier contains spaces or special characters, the entire string must be enclosed in double quotes. Identifiers enclosed in double quotes are also case-sensitive.
        schedule : TaskSchedule, optional

        comment : str, optional
            Specifies a comment for the task.
        finalize : str, optional
            Specifies the name of the root task that the finalizer task is associated with.
        task_auto_retry_attempts : int, optional
            Root task settable only. Specifies the number of automatic task graph retry attempts. Valid range is 0 to 30. When not specified, no retry would happen.
        config : object, optional
            Task Config
        session_parameters : object, optional
            Session Parameters for the task at runtime.
        predecessors : list[str], optional
            Specifies one or more predecessor tasks for the current task
        task_relations : str, optional
            Displays the relationship between the root task and its corresponding finalizer tasks.
        user_task_managed_initial_warehouse_size : str, optional
            Specifies the size of the compute resources to provision for the first run of the task. This parameter only applies to serverless tasks.
        target_completion_interval : MinutesSchedule, optional

        serverless_task_min_statement_size : str, optional
            Specifies the minimum allowed warehouse size for the serverless task. Minimum XSMALL, Maximum XXLARGE. This parameter only applies to serverless tasks.
        serverless_task_max_statement_size : str, optional
            Specifies the maximum allowed warehouse size for the serverless task. Minimum XSMALL, Maximum XXLARGE. This parameter only applies to serverless tasks.
        user_task_timeout_ms : int, optional
            Specifies the time limit on a single run of the task before it times out (in milliseconds).
        suspend_task_after_num_failures : int, optional
            Specifies the number of consecutive failed task runs after which the current task is suspended automatically.
        condition : str, optional
            Specifies a Boolean SQL expression condition; multiple conditions joined with AND/OR are supported
        allow_overlapping_execution : bool, optional
            Specifies whether to allow multiple instances of the DAG to run concurrently.
        error_integration : str, optional
            Specifies the name of the notification integration used to communicate with Amazon SNS, MS Azure Event Grid, or Google Pub/Sub.
        created_on : datetime, optional
            The time the task was created on.
        id : str, optional
            An ID for the current task.
        owner : str, optional
            The role that owns the task.
        owner_role_type : str, optional
            The role type of the task owner.
        state : str, optional
            The state of the task. Must be one of started or suspended.
        last_committed_on : datetime, optional
            The time the task was last committed on.
        last_suspended_on : datetime, optional
            The time the task was last suspended on.
        database_name : str, optional
            The name of the parent database for the task.
        schema_name : str, optional
            The name of the parent schema for the task.
        """
        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.target_completion_interval = target_completion_interval
        self.serverless_task_min_statement_size = serverless_task_min_statement_size
        self.serverless_task_max_statement_size = serverless_task_max_statement_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",
        "target_completion_interval",
        "serverless_task_min_statement_size",
        "serverless_task_max_statement_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 __repr__(self) -> str:
        return repr(self._to_model())

    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,
            target_completion_interval=self.target_completion_interval._to_model()
            if self.target_completion_interval is not None
            else None,
            serverless_task_min_statement_size=self.serverless_task_min_statement_size,
            serverless_task_max_statement_size=self.serverless_task_max_statement_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 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,
            target_completion_interval=MinutesScheduleModel._from_model(model.target_completion_interval)
            if model.target_completion_interval
            else None,
            serverless_task_min_statement_size=model.serverless_task_min_statement_size,
            serverless_task_max_statement_size=model.serverless_task_max_statement_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):
        """Create a dictionary of the properties from a Task.

        This method constructs a dictionary with the key-value entries corresponding to the properties of the Task object.

        Returns
        _______
        dict
            A dictionary object created using the input model.
        """
        return self._to_model().to_dict()

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

        This method constructs a Task object from a dictionary with the key-value pairs of its properties.

        Parameters
        ----------
        obj : dict
            A dictionary whose keys and values correspond to the properties of the resource object.

        Returns
        _______
        Task
            A Task object created using the input dictionary; this will fail if the required properties are missing.
        """
        return cls._from_model(Task.from_dict(obj))


Task._model_class = TaskModel
