# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/integrations/DomoJupyter.ipynb.

# %% auto 0
__all__ = ['NoConfigCompanyError', 'GetInstanceConfig', 'GetDomains_Query_Exception_PW_Col_Error',
           'GetDomains_Query_AuthMatch_Error']

# %% ../../nbs/integrations/DomoJupyter.ipynb 2
from dataclasses import dataclass, field
from typing import Optional
from enum import Enum


import re
import pandas as pd
import importlib
import datetime as dt
import time

import json

# import domojupyter as dj

import domolibrary.client.DomoAuth as dmda
import domolibrary.client.Logger as lc
import domolibrary.classes.DomoDataset as dmds

from fastcore.basics import patch_to


# %% ../../nbs/integrations/DomoJupyter.ipynb 3
class NoConfigCompanyError(Exception):
    def __init__(self, sql, domo_instance):
        message = f'SQL "{sql}" returned no results in {domo_instance}'
        self.message = message
        super().__init__(self.message)


class GetInstanceConfig:
    config: pd.DataFrame = None
    logger: lc.Logger = None

    def __init__(self, logger: Optional[lc.Logger] = None):

        self.logger = logger or lc.Logger(app_name='GetInstanceConfig')

    async def _retrieve_company_ds(self,
                                   config_auth: dmda.DomoAuth,
                                   dataset_id: str,
                                   sql: str,
                                   debug_prn: bool = False,
                                   debug_api: bool = False,
                                   debug_log: bool = False,
                                   ) -> pd.DataFrame:

        ds = await dmds.DomoDataset.get_from_id(auth=config_auth,
                                                dataset_id=dataset_id, debug_api=debug_api)

        message = f"⚙️ START - Retrieving company list \n{ds.display_url()} using \n{sql}"

        if debug_prn:
            print(message)

        logger.log_info(message, debug_log=debug_log)

        df = await ds.query_dataset_private(auth=config_auth,
                                            dataset_id=dataset_id,
                                            sql=sql,
                                            debug_api=debug_api)
        if len(df.index) == 0:
            raise NoConfigCompanyError(
                sql, domo_instance=config_auth.domo_instance)

        self.config = df

        message = f"\n⚙️ SUCCESS 🎉 Retrieved company list \nThere are {len(df.index)} companies to update"

        if debug_prn:
            print(message)
        logger.log_info(message, debug_log=debug_log)

        return df


# %% ../../nbs/integrations/DomoJupyter.ipynb 6
class GetDomains_Query_Exception_PW_Col_Error(Exception):
    """raise if SQL query fails to return column named 'config_exception_pw'"""

    def __init__(self, sql :str = None, domo_instance : str = None, message : str = None):
        message = message or f"Query failed to return a column 'config_exception_pw' sql = {sql} in {domo_instance}"
        super().__init__(self, message)


@patch_to(GetInstanceConfig, cls_method=True)
async def get_domains_with_global_config_auth(cls: GetInstanceConfig,

                                              config_dataset_id: str,
                                              config_auth: dmda.DomoAuth, # which instance to retrieve configuration data from
                                              
                                              global_auth: dmda.DomoAuth, # global authentication credentials
                                              global_exception_auth: dmda.DomoAuth, # exception credentials (ex 24 char password)
                                              # must return a column named domo_instance, if there is an exception_auth, must return a column 'config_exception_pw'
                                              
                                              config_sql: str = "select domain as domo_instance, config_exception_pw from table",
                                              
                                              debug_api: bool = False,
                                              debug_log: bool = False,
                                              debug_prn: bool = False,
                                              
                                              logger: lc.Logger = None) -> pd.DataFrame:
    if not logger:
        logger = lc.Logger(app_name='get_domains_with_global_config_auth')

    gic = cls(logger = logger)

    df = await gic._retrieve_company_ds(config_auth=config_auth,
                                        dataset_id=config_dataset_id,
                                        sql=config_sql,
                                       debug_prn=debug_prn,
                                       debug_log=debug_log,
                                       debug_api=debug_api)
    
    if 'config_exception_pw' not in df.columns:
        message = f"Query failed to return a column 'config_exception_pw' sql = {config_sql} in {config_auth.domo_instance}"
        gic.logger.log_error(message)
        raise GetDomains_Query_Exception_PW_Col_Error(message= message)

    for index, instance in df.iterrows():
        creds = global_auth

        if instance['config_exception_pw'] == 1:
            creds = global_exception_auth

        creds.domo_instance=instance['domo_instance']

        try:
            await creds.get_auth_token()
            df.at[index, 'is_valid'] = 1

        except dmda.InvalidCredentialsError as e:
            if debug_prn:
                print(e)
            
            logger.log_error(str(e))
            df.at[index, 'is_valid'] = 0
        
        finally:
            df.at[index, 'instance_auth'] = creds

    return df


# %% ../../nbs/integrations/DomoJupyter.ipynb 10
class GetDomains_Query_AuthMatch_Error(Exception):
    """raise if SQL query fails to return column named 'auth_match_col'"""
    def __init__(self, sql : str = None, domo_instance : str = None ,message : str = None):
        message = message or f"Query failed to return a column 'auth_match_col' sql = {sql} in {domo_instance}"
        super().__init__(self, self.message)

@patch_to(GetInstanceConfig, cls_method=True)
async def get_domains_with_instance_auth(cls: GetInstanceConfig,
                                         config_dataset_id: str,
                                         
                                         config_auth: dmda.DomoAuth,  # which instance to retrieve configuration data from
                                         default_auth : dmda.DomoAuth,
                                         auth_enum : Enum,
                                         
                                         config_sql: str = "select domain as domo_instance,concat(config_useprod, '-', project) as auth_match_col from table",
                                         
                                        
                                         debug_api: bool = False,
                                         debug_log: bool = False,
                                         debug_prn: bool = False,
                                         logger: Optional[lc.Logger] = None) -> pd.DataFrame: # returns a dataframe with domo_instance, instance_auth, and binary column is_valid 
    if not logger:
        logger = lc.Logger(app_name='get_domains_with_instance_auth')

    gic = cls(logger=logger)

    df = await gic._retrieve_company_ds(config_auth=config_auth,
                                        dataset_id=config_dataset_id,
                                        sql=config_sql,
                                        debug_prn=debug_prn,
                                        debug_log=debug_log,
                                        debug_api=debug_api)

    if 'auth_match_col' not in df.columns:
        message = f"Query failed to return a column 'auth_match_col' sql = {config_sql} in {config_auth.domo_instance}"
        raise GetDomains_Query_AuthMatch_Error(message)

    for index, instance in df.iterrows():
        
        creds = default_auth

        match_auth = next(
            (member.value for member in auth_enum if member.name == instance['auth_match_col']))

        if match_auth:
            creds = match_auth

        creds.domo_instance=instance['domo_instance']

        try:
            await creds.get_auth_token(debug_api = debug_api)
            df.at[index, 'is_valid'] = 1

        except dmda.InvalidCredentialsError as e:
            if debug_prn:
                print(e)
            
            logger.log_error(str(e))
            df.at[index, 'is_valid'] = 0
        
        finally:
            df.at[index, 'instance_auth'] = creds

    return df

