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

# %% auto 0
__all__ = ['DomoTrigger_Schedule', 'DomoTrigger', 'DomoJob_Base']

# %% ../../nbs/classes/50_DomoApplication_Job_Base.ipynb 3
from dataclasses import dataclass, field

from typing import List, Optional

import httpx

from nbdev.showdoc import patch_to

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

import domolibrary.routes.application as application_routes

import domolibrary.utils.convert as cc

# %% ../../nbs/classes/50_DomoApplication_Job_Base.ipynb 6
@dataclass
class DomoTrigger_Schedule:
    schedule_text: str = None
    schedule_type: str = "scheduleTriggered"

    minute: int = None
    hour: int = None
    minute_str: str = None
    hour_str: str = None

    @classmethod
    def _from_str(cls, s_text, s_type):
        sched = cls(schedule_type=s_type, schedule_text=s_text)

        try:
            parsed_hour = s_text.split(" ")[2]
            parsed_minute = s_text.split(" ")[1]

            if "*" in parsed_hour or "/" in parsed_hour:
                sched.hour_str = parsed_hour
            else:
                sched.hour = int(float(parsed_hour))
            if "*" in parsed_minute:
                sched.minute_str = parsed_minute
            else:
                sched.minute = int(float(parsed_minute))

            return sched

        except Exception as e:
            print(f"unable to parse schedule {s_text}")
            print(e)

    def to_obj(self):
        return {"hour": int(self.hour), "minute": int(self.minute)}

    def to_json(self):
        minute = self.minute_str if self.minute_str is not None else str(self.minute)
        hour = self.hour_str if self.hour_str is not None else str(self.hour)
        return {
            "eventEntity": f"0 {minute} {hour} ? * *",
            # old value on Jan 13
            # "eventEntity": f'0 {minute} {hour} 1/1 * ? *',
            "eventType": self.schedule_type,
        }


@dataclass
class DomoTrigger:
    id: str
    job_id: str
    schedule: List[DomoTrigger_Schedule] = None

    @classmethod
    def _from_json(cls, obj):
        return cls(
            id=obj["triggerId"],
            job_id=obj["jobId"],
            schedule=DomoTrigger_Schedule._from_str(
                s_text=obj.get("eventEntity"), s_type=obj.get("eventType")
            ),
        )

# %% ../../nbs/classes/50_DomoApplication_Job_Base.ipynb 8
@dataclass
class DomoJob_Base:
    """
    the base class only captures attributes applicable to all jobs (i.e. does not destructure execution_payload onto the class)
    build Application / Job extensions by creating children of the DomoJob_Base class
    """

    auth: dmda.DomoAuth = field(repr=False)

    name: str
    application_id: str

    logs_dataset_id: str = None
    id: str = None
    user_id: str = None
    execution_timeout: int = 1440

    is_enabled: bool = False  # based on triggers
    customer_id: str = None
    created_dt: dt.datetime = None
    updated_dt: dt.datetime = None

    description: str = None

    execution_payload: dict = field(default_factory=lambda: {})
    share_state: dict = field(default_factory=lambda: {})
    accounts: List[str] = field(default_factory=[])
    triggers: List[DomoTrigger] = field(default_factory=[])

    @staticmethod
    def _format_remote_instance(remote_instance):
        if not remote_instance:
            return remote_instance

        return remote_instance.replace(".domo.com", "")

    @staticmethod
    def _convert_API_res_to_DomoJob_base_obj(obj) -> dict:
        """base class for converting an API response into a dictionary with parameters that DomoJob_Base expects"""

        triggers_ls = obj.get("triggers")
        domo_triggers = (
            [DomoTrigger._from_json(tg) for tg in triggers_ls] if triggers_ls else []
        )

        return {
            "id": obj["jobId"],
            "name": obj["jobName"],
            "user_id": obj["userId"],
            "application_id": obj["applicationId"],
            "customer_id": obj["customerId"],
            "execution_timeout": obj["executionTimeout"],
            "execution_payload": obj["executionPayload"],
            "logs_dataset_id": obj["executionPayload"]["metricsDatasetId"],
            "share_state": obj.get("shareState", {}),
            "created_dt": cc.convert_epoch_millisecond_to_datetime(obj["created"]),
            "updated_dt": cc.convert_epoch_millisecond_to_datetime(obj["updated"]),
            "is_enabled": True if triggers_ls else False,
            "description": obj.get("jobDescription"),
            "accounts": obj.get("accounts"),
            "triggers": domo_triggers,
        }

# %% ../../nbs/classes/50_DomoApplication_Job_Base.ipynb 9
@patch_to(DomoJob_Base, cls_method=True)
def _from_json(
    cls,
    obj,
    auth,
):
    """_from_json is a required abstract method.  Each DomoJob_Base implementation must have an instance of _from_json"""

    base_obj = cls._convert_API_res_to_DomoJob_base_obj(obj=obj)

    return cls(
        auth=auth,
        **base_obj,
    )


@patch_to(DomoJob_Base, cls_method=True)
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,
    new_cls: DomoJob_Base = None,  # pass in a child class which has the mandatory "from_json" function
    return_raw: bool = False,
    parent_class=None,
):
    """
    this function will receive the parent_class as an input_parameter (instead of relying on the actual class DomoJob_Base)
    to call the `new_class._from_json()`

    this process will handle converting the JSON obj into 'the correct' class
    """

    res = await application_routes.get_application_job_by_id(
        auth=auth,
        application_id=application_id,
        job_id=job_id,
        session=session,
        debug_api=debug_api,
        parent_class=parent_class,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    if return_raw:
        return res

    cls = new_cls or cls

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


@patch_to(DomoJob_Base, cls_method=True)
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,
):
    """
    stub abstract function that each `DomoJob_Base` will have.
    note we pass the calling functions class into classmethod _get_by_id()
    so that we can call cls._from_json() during code execution
    """

    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,
    )

# %% ../../nbs/classes/50_DomoApplication_Job_Base.ipynb 10
@patch_to(DomoJob_Base)
def _generate_to_json(self) -> dict:
    """returns a base dictionary representation of the DomoJob_Base class"""

    trigger_ls = [self.triggers[0].schedule.to_json()] if len(self.triggers) > 0 else []

    execution_payload = self.execution_payload or {}
    execution_payload.update({"metricsDatasetId": self.logs_dataset_id})

    return {
        "jobId": self.id,
        "jobName": self.name,
        "userId": self.user_id,
        "applicationId": self.application_id,
        "customerId": self.customer_id,
        "executionTimeout": self.execution_timeout,
        "executionPayload": execution_payload,
        "shareState": self.share_state,
        # created / excluded because generated metadata
        # updated / excluded because generated metadata
        "triggers": trigger_ls,
        "jobDescription": self.description,
        "executionTimeout": self.execution_timeout,
        "accounts": self.accounts,
    }


@patch_to(DomoJob_Base)
def to_json(self):
    """this is an abstract method, each DomoJob_Base implementation must define a to_json() function"""
    return self._generate_to_json()
