# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb.

# %% auto 0
__all__ = ['Watchdog_Config', 'Watchdog_Config_MaxIndexingTime', 'Watchdog_Config__Variance', 'Watchdog_Config_RowCountVariance',
           'Watchdog_Config_ExecutionVariance', 'Watchdog_Config_ErrorDetection', 'Watchdog_Config_LastDataUpdated',
           'Watchdog_Config_CustomQuery', 'Watchdog_ConfigFactory', 'DomoJob_Watchdog']

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 3
from dataclasses import dataclass, field
from abc import ABC, abstractmethod

from typing import List, Optional
from enum import Enum

import httpx

from nbdev.showdoc import patch_to

import domolibrary.client.DomoAuth as dmda
import datetime as dt

from pprint import pprint

import domolibrary.routes.application as application_routes


from domolibrary.classes.DomoApplication_Job_Base import DomoJob_Base, DomoTrigger_Schedule

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 7
@dataclass
class Watchdog_Config(ABC):
    entity_ids: List[str]
    entity_type: str  # dataflow or dataset
    watcher_parameters: dict
    report_type: str

    """base class for the different watchdog report types"""

    @classmethod
    def _from_json(cls, watcher_parameters_obj):  # executionPayload

        return cls(
            entity_ids=watcher_parameters_obj["entityIds"],
            entity_type=watcher_parameters_obj["entityType"],
            report_type=watcher_parameters_obj["type"],
            watcher_parameters=watcher_parameters_obj,
        )

    def _to_json(self):
        return {
            "entityIds": self.entity_ids,
            "entityType": self.entity_type,
            "type": self.report_type,
        }

    @abstractmethod
    def to_json(self):
        return self._to_json()

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 8
@dataclass
class Watchdog_Config_MaxIndexingTime(Watchdog_Config):
    report_type = "max_indexing_time"
    max_indexing_time_mins = 30

    def __post_init__(self):
        self.max_indexing_time_mins = self.watcher_parameters[
            "maxIndexingTimeInMinutes"
        ]

    def to_json(self, **kwargs):
        if kwargs.get("max_indexing_time_mins"):
            self.max_indexing_time_mins = kwargs["max_indexing_time_mins"]

        return {
            **self._to_json(),
            "maxIndexingTimeInMinutes": self.max_indexing_time_mins,
        }


@dataclass
class Watchdog_Config__Variance(Watchdog_Config):
    report_type: str
    variance_percent: int = 10

    def __post_init__(self):
        self.variance_percent = self.watcher_parameters["variancePercent"]

    def to_json(self, **kwargs):
        if kwargs.get("variance_percent"):
            self.variance_percent = kwargs["variance_percent"]

        return {
            **self._to_json(),
            "variancePercent": self.variance_percent,
        }


@dataclass
class Watchdog_Config_RowCountVariance(Watchdog_Config__Variance):
    report_type = "row_count_variance"


@dataclass
class Watchdog_Config_ExecutionVariance(Watchdog_Config__Variance):
    report_type = "execution_variance"


@dataclass
class Watchdog_Config_ErrorDetection(Watchdog_Config):
    report_type: str = "error_detection"

    def to_json(self, **kwargs):
        return {
            **self._to_json(),
        }


@dataclass
class Watchdog_Config_LastDataUpdated(Watchdog_Config):
    report_type: str = "last_data_updated"
    min_data_update_frequency_in_mins: int = 10

    def __post_init__(self):
        self.min_data_update_frequency_in_mins = self.watcher_parameters[
            "minDataUpdateFrequencyInMinutes"
        ]

    def to_json(self, **kwargs):
        if kwargs.get("min_data_update_frequency_in_mins"):
            self.min_data_update_frequency_in_mins = kwargs[
                "min_data_update_frequency_in_mins"
            ]

        return {
            **self._to_json(),
            "minDataUpdateFrequencyInMinutes": self.min_data_update_frequency_in_mins,
        }


@dataclass
class Watchdog_Config_CustomQuery(Watchdog_Config):
    report_type: str = "custom_query"
    sql_query: str = ""

    def __post_init__(self):
        self.sql_query = self.watcher_parameters["sqlQuery"]

    def to_json(self, **kwargs):
        if kwargs.get("sql_query"):
            self.sql_query = kwargs["sql_query"]

        return {
            **self._to_json(),
            "sqlQuery": self.sql_query,
        }

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 9
class Watchdog_ConfigFactory(Enum):
    MAX_INDEXING_TIME = Watchdog_Config_MaxIndexingTime
    ROW_COUNT_VARIANCE = Watchdog_Config_RowCountVariance
    EXECUTION_VARIANCE = Watchdog_Config_ExecutionVariance
    ERROR_DETECTION = Watchdog_Config_ErrorDetection
    LAST_DATA_UPDATED = Watchdog_Config_LastDataUpdated
    CUSTOM_QUERY = Watchdog_Config_CustomQuery

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 11
@dataclass
class DomoJob_Watchdog(DomoJob_Base):
    custom_message: str = None
    remote_instance: str = None

    notify_emails: List[str] = field(default_factory=lambda: [])
    notify_group_ids: List[str] = field(default_factory=lambda: [])
    notify_user_ids: List[str] = field(default_factory=lambda: [])

    Config: Watchdog_Config = None
    webhooks: List[str] = None

    @classmethod
    def _from_json(cls, obj, auth):

        remote_instance = cls._format_remote_instance(
            obj["executionPayload"].get("domain")
        )

        watchdog_parameters_obj = obj["executionPayload"]["watcherParameters"]

        config = Watchdog_ConfigFactory[
            watchdog_parameters_obj["type"].upper()
        ].value._from_json(watchdog_parameters_obj)

        return cls(
            **cls._convert_API_res_to_DomoJob_base_obj(obj),
            remote_instance=remote_instance,
            custom_message=obj["executionPayload"]["customMessage"],
            Config=config,
            notify_emails=obj["executionPayload"]["notifyEmailAddresses"],
            notify_group_ids=obj["executionPayload"]["notifyGroupIds"],
            notify_user_ids=obj["executionPayload"]["notifyUserIds"],
            webhooks=obj["executionPayload"]["webhooks"],
            auth=auth
        )

    @classmethod
    async def get_by_id(
        cls,
        application_id,
        job_id,
        auth: dmda.DomoAuth,
        debug_api: bool = False,
        session: Optional[httpx.AsyncClient] = None,
        debug_num_stacks_to_drop=2,
        return_raw: bool = False,
    ):

        return await cls._get_by_id(
            application_id=application_id,
            job_id=job_id,
            auth=auth,
            debug_api=debug_api,
            session=session,
            debug_num_stacks_to_drop=debug_num_stacks_to_drop,
            return_raw=return_raw,
            new_cls=cls,
            parent_class=cls.__name__,
        )

    def to_json(self):
        s = self._generate_to_json()

        s["executionPayload"].update(
            {
                "customMessage": self.custom_message,
                "domain": self.remote_instance,
                "notifyEmailAddresses": self.notify_emails,
                "notifyGroupIds": self.notify_group_ids,
                "notifyUserIds": self.notify_user_ids,
                "watcherParameters": self.Config.to_json(),
                "webhooks": self.webhooks,
            }
        )
        return s

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 14
@patch_to(DomoJob_Base)
async def update(
    self: DomoJob_Base,
    debug_api: bool = False,
    session: Optional[httpx.AsyncClient] = None,
    debug_num_stacks_to_drop=2,
):

    res = await application_routes.update_application_job(
        auth=self.auth,
        body=self.to_json(),
        application_id=self.application_id,
        job_id=self.id,
        debug_api=debug_api,
        session=session,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    return res

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 17
@patch_to(DomoJob_Base)
async def execute(
    self,
    debug_api: bool = False,
    session: Optional[httpx.AsyncClient] = None,
    debug_num_stacks_to_drop=2,
):

    res = await application_routes.execute_application_job(
        auth=self.auth,
        application_id=self.application_id,
        job_id=self.id,
        debug_api=debug_api,
        session=session,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    return res

# %% ../../nbs/classes/50_DomoApplication_Job_Watchdog.ipynb 20
@patch_to(DomoJob_Watchdog, cls_method=True)
async def create(
    cls,
    auth: dmda.DomoAuth,
    name: str,
    application_id: str,
    config: Watchdog_Config,
    logs_dataset_id: str,
    notify_user_ids: list = None,
    notify_group_ids: list = None,
    notify_emails: list = None,
    triggers: List[DomoTrigger_Schedule] = None,
    description: str = f"created via domolibrary - {dt.date.today()}",
    execution_timeout=1440,
    accounts: list[int] = None,
    remote_instance=None,
    custom_message: str = None,
    webhooks: List[str] = None,
    debug_api: bool = False,
    session: Optional[httpx.AsyncClient] = None,
    return_raw: bool = False,
):

    domo_job = cls(
        auth=auth,
        name=name,
        description=description,
        application_id=application_id,
        execution_timeout=execution_timeout,
        notify_user_ids=notify_user_ids or [],
        notify_group_ids=notify_group_ids or [],
        notify_emails=notify_emails or [],
        triggers=triggers or [],
        accounts=accounts or [],
        logs_dataset_id=logs_dataset_id,
        remote_instance=remote_instance,
        Config=config,
        custom_message=custom_message,
        webhooks=webhooks,
    )

    body = domo_job.to_json()

    res = await application_routes.create_application_job(
        auth=auth,
        application_id=application_id,
        body=body,
        debug_api=debug_api,
        session=session,
    )

    if return_raw:
        return res

    return cls._from_json(res.response, auth=auth)
