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

# %% auto 0
__all__ = ['upsert_user', 'UpsertUserConfig']

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

# %% ../nbs/00_FactoryUser.ipynb 3
from typing import List, Callable
from dataclasses import dataclass, field
import httpx

import domolibrary.client.DomoAuth as dmda

import domolibrary.classes.DomoInstanceConfig as dmic
import domolibrary.classes.DomoRole as dmdr
import domolibrary.classes.DomoUser as dmdu
import domolibrary.classes.DomoGroup as dmgr
import domolibrary.classes.DomoAccount as dmac 


# %% ../nbs/00_FactoryUser.ipynb 6
@factory_function
async def upsert_user(
    # base required
    logs: FactoryLogs,
    res : FactoryResponse,
    config : FactoryConfig,
    auth: dmda.DomoAuth, 
    
    email : str,
    display_name : str,
    domo_role : dmdr.DomoRole = None, # will use default role if no role provided
    password: str = None,
    
    # OUTPUT
    domo_user : dmdu.DomoUser = None, #will add domo user to config

    # DEBUG
    debug_api: bool = False,
    session : httpx.AsyncClient = None,
    **kwargs
    ):
    
    res.response = False    
    auth = auth
    
    # STAGE_1 = DOMO ROLE OR DEFAULT ROLE
    step = FactoryMessage( stage="retrieve domo role", is_success=False)
    res.add_message( step )
    
    if not domo_role:
        try:
            domo_role = await dmdr.DomoRoles.get_default_role(auth = auth,debug_api = debug_api, session = session)
            config.domo_role = domo_role
            
        except Exception as e:
            step.is_success = False
            step.message = str(e)

    if not domo_role:
        res.response = "no domo role"
        return res
    
    step.message = f"using role {domo_role.id} - {domo_role.name}"
    step.is_success = True
            
    # STAGE_2 = DOMO_USER
    step = FactoryMessage( stage="upsert user", is_success=False)
    res.add_message( step )
    
    try:
        domo_user  = await dmdu.DomoUsers.upsert_user(
            auth = auth,
            email_address = email,
            display_name = display_name,
            session = session,
            role_id = domo_role.id)      
                      
        config.domo_user = domo_user
        step.message = f"upsert user {domo_user.id} successful"
        step.is_success = True
    
    except Exception as e:
        step.message = e
        step.is_success = False
    
    if not domo_user:
        res.response = "no domo user"
        return res

    res.response = domo_user
    
    if not password:
        return res
    
    # STEP_3 = SET PASSWORD
    step = FactoryMessage( stage="set password", is_success=False)
    res.add_message( step )
        
    try:
        await domo_user.reset_password(new_password = password, debug_api = debug_api)
        domo_user.password = password
        step.message = f"set password {password}"
        step.is_success = True
    
    except Exception as e:
        step.message = e
        step.is_success = False
    
    return res

@dataclass
class UpsertUserConfig(FactoryConfig):
    auth: dmda.DomoAuth
    display_name : str
    email: str
    password :str = None # will not set password if not provided
    domo_role : dmdr.DomoRole = None # will use default not passed
    domo_user : dmdu.DomoUser = None # will assign after upsert

    # factory_fn_ls : List[Callable] = field(default_factory = lambda:[sync_user])

