# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_FactoryRole.ipynb.

# %% auto 0
__all__ = ['get_role', 'GetRole', 'upsert_role', 'UpsertRoleConfig']

# %% ../nbs/00_FactoryRole.ipynb 2
from .utils.factory import (
    factory_function,
    FactoryLogs, 
    FactoryResponse, FactoryConfig, FactoryMessage)

# %% ../nbs/00_FactoryRole.ipynb 3
from typing import List
from dataclasses import dataclass
import httpx

import domolibrary.client.DomoAuth as dmda

import domolibrary.classes.DomoInstanceConfig as dmic
import domolibrary.classes.DomoRole as dmdr

# %% ../nbs/00_FactoryRole.ipynb 6
@factory_function
async def get_role(
    logs: FactoryLogs,
    res: FactoryResponse,
    config: FactoryConfig,
    auth: dmda.DomoAuth,

    get_default_role: bool = False,  # if set to True will retrieve default role
    role_name: str = None, # will retrieve role searched by name
    
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    debug_factory: bool = False,
    
    **kwargs,
):

    res.response = False

    domo_role = None

    if debug_factory:
        from pprint import pprint
        pprint(logs.logs)

    # if not role_name and not get_default_role:
    #     raise FactoryFunction_Error(
    #         factory = res,
    #         location=config.location,
    #         message="must pass `role_name` or get_default_role = True",
    #     )

    step = FactoryMessage(stage="retrieve role", is_success=False)
    res.add_message(step)

    if get_default_role:
        try:
            domo_role = await dmdr.DomoRoles.get_default_role(
                auth=auth, debug_api=debug_api, session=session
            )
            step.is_success = True
            step.message = "default role retrieved"

        except Exception as e:
            step.is_success = False
            step.message = f"unable to retrieve default role - {str(e)}"


    if not domo_role:
        try:
            domo_role = await dmdr.DomoRoles.search_role(auth=auth, role_name=role_name)
            step.is_success = True
            step.message = f"search role {role_name} retrieved {domo_role.name}"

        except Exception as e:
            step.is_success = False
            step.message = f"unable to retrieve search role {role_name} - {str(e)}"

    if not domo_role:
        res.response = "no domo role"
        return res

    config.domo_role = domo_role
    res.response = domo_role

    if debug_factory:
        pprint(logs.logs)

    return res


@dataclass
class GetRole(FactoryConfig):
    auth: dmda.DomoAuth
    role_name: str = None
    get_default_role : bool = False
    domo_role : dmdr. DomoRole = None # will update during execution


# %% ../nbs/00_FactoryRole.ipynb 10
@factory_function
async def upsert_role(
    logs: FactoryLogs,
    res : FactoryResponse,
    config : FactoryConfig,
    auth: dmda.DomoAuth,
    
    grant_ls : List[str] = None,
    is_all_grants: bool = False, # use when generating super_admin account

    role_name : str = None,
    role_description : str = None,
    set_default_role: bool = False,

    # output
    domo_role : dmdr.DomoRole = None, # gets assigned during function execution

    debug_api: bool = False,
    session : httpx.AsyncClient = None,
    **kwargs
    ):
    
    res.response = False
    
    # STAGE_1 = GET GRANTS
    step = FactoryMessage( stage="retrieve grants", is_success=False, stage_num=1)
    res.add_message( step )
    
    if grant_ls:
        step.message = "using grants from config"
    
    # STAGE_2 = USE ALL GRANTS
    if is_all_grants:
        try:
            step_all_grants = FactoryMessage( stage="get super_admin grants", is_success=False, stage_num=2)
            res.add_message( step_all_grants )

            domo_instance = dmic.DomoInstanceConfig(auth = auth)
            grant_ls = await domo_instance.get_grants(session = session, debug_api = debug_api)     
            
            config.grant_ls = grant_ls
            step_all_grants.message = "using all grants"
            step_all_grants.is_success=True
            
        except Exception as e:
            step.is_success = False
            step.message = str(e)

    if not grant_ls:
        res.response = "no grant list"
        return res
    

    step.is_success = True
            
    # STAGE_3 = upsert DOMO_ROLE
    step = FactoryMessage( stage="upsert role", is_success=False, stage_num=3)
    res.add_message( step )

    domo_role = None
    # try:
    domo_role =  await dmdr.DomoRoles.upsert_role(auth=config.auth,
                                                name=role_name,
                                                description=role_description,
                                                grant_ls=grant_ls, 
                                                session = session,
                                                debug_api = debug_api)
    
    config.domo_role = domo_role
    step.is_success = True
    step.message = f"{domo_role.name} upserted"
    
    # except Exception as e:
        # step.is_success = False
        # step.message = str(e)
    
    if not domo_role:
        res.response = "no domo role"
        return res
    
    
    # STAGE_4 = config DEFAUL_ROLE
    if set_default_role:
        step = FactoryMessage( stage="set default role", is_success=False, stage_num=4)
        res.add_message( step )
        
        try:
            await domo_role.set_as_default_role(session = session, debug_api = debug_api)
            step.is_success = True
            step.message = f"{domo_role.name} set to default role in {auth.domo_instance}"
        
        except Exception as e:
            step.is_success = False
            step.message = str(e)
        
    res.response = domo_role
    return res

@dataclass
class UpsertRoleConfig(FactoryConfig):
    auth: dmda.DomoAuth
    role_name: str
    role_description:str
    grant_ls: List[str]
    
    is_all_grants : bool = False
    set_default_role: bool = False
    
    domo_role : dmdr.DomoRole = None
    
    # factory_fn_ls : List[Callable] = field(default_factory = lambda:[sync_role])

