# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/routes/group.ipynb.

# %% auto 0
__all__ = ['SearchGroups_Error', 'search_groups_by_name', 'get_all_groups', 'get_group_by_id', 'toggle_system_group_visibility',
           'GroupType_Enum', 'generate_body_create_group', 'CreateGroup_Error', 'create_group', 'update_group',
           'get_group_owners', 'get_group_membership', 'generate_body_update_group_membership',
           'update_group_membership']

# %% ../../nbs/routes/group.ipynb 2
import httpx
from enum import Enum
from typing import Union

import domolibrary.client.get_data as gd
import domolibrary.client.ResponseGetData as rgd
import domolibrary.client.DomoAuth as dmda
import domolibrary.client.DomoError as de

# %% ../../nbs/routes/group.ipynb 4
class SearchGroups_Error(de.DomoError):
    def __init__(
        self, status, message, domo_instance, function_name="search_groups_by_name"
    ):
        super().__init__(
            function_name=function_name,
            status=status,
            message=message,
            domo_instance=domo_instance,
        )


async def search_groups_by_name(
    auth: dmda.DomoAuth,
    search_name: str,
    is_exact_match: bool = True,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
) -> rgd.ResponseGetData:
    """uses /content/v2/groups/grouplist api -- includes user details"""

    url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/grouplist?ascending=true&search={search_name}&sort=name "

    res = await gd.get_data(
        auth=auth, url=url, method="GET", debug_api=debug_api, session=session
    )
    if not is_exact_match:
        return res

    match_group = next(
        (group for group in res.response if group.get("name") == search_name), None
    )
    # print(match_group)

    if not match_group:
        raise SearchGroups_Error(
            status=res.status,
            message=f"There is no exact match for {search_name}",
            domo_instance=auth.domo_instance,
        )
    res.response = match_group

    return res

# %% ../../nbs/routes/group.ipynb 7
async def get_all_groups(
    auth: dmda.DomoAuth, 
    session: httpx.AsyncClient = None,
    debug_api: bool = False, 
    debug_loop : bool = False
) -> rgd.ResponseGetData:
    """uses /content/v2/groups/grouplist api -- includes user details"""

    url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/grouplist"


    def arr_fn(res):
        return res.response

    res = await gd.looper(
        offset_params ={ 
            'offset' : 'offset',
            'limit': 'limit'
        },

        arr_fn = arr_fn,
        loop_until_end = True,
        limit = 30,
        url=url, method="GET", 
        auth=auth, 
        session=session,
        debug_loop =debug_loop,
        debug_api = debug_api
    )

    return res

# %% ../../nbs/routes/group.ipynb 10
async def get_group_by_id(
    auth: dmda.DomoAuth,
    group_id: str,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
) -> rgd.ResponseGetData:

    """uses /content/v2/groups/ api -- does not return details"""

    url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/{group_id}"

    res = await gd.get_data(
        auth=auth, url=url, method="GET", debug_api=debug_api, session=session
    )

    if res.status == 404 and res.response == "Not Found":
        raise SearchGroups_Error(
            status=res.status,
            message=f"group {group_id} not found",
            domo_instance=auth.domo_instance,
            function_name="get_group_by_id",
        )

    return res

# %% ../../nbs/routes/group.ipynb 12
async def toggle_system_group_visibility(auth,
                                         is_hide_system_groups: bool, 
                                         debug_api: bool = False):

    print(
        f"toggling group visiblity in {auth.domo_instance} { 'hiding system groups' if is_hide_system_groups else 'show system groups'}")

    url = f'https://{auth.domo_instance}.domo.com/api/content/v2/groups/setVisibility'

    await gd.get_data(url=url,
                      method='POST', auth=auth,
                      body={"type": "system", "hidden": is_hide_system_groups})

    url = f'https://{auth.domo_instance}.domo.com/api/customer/v1/properties/groups.system.enabled'
    
    return await gd.get_data(url=url, auth=auth, method='GET')


# %% ../../nbs/routes/group.ipynb 16
class GroupType_Enum(Enum):
    OPEN = "open"
    ADHOC = "adHoc"
    CLOSED = "closed"
    DIRECTORY = "directory"
    DYNAMIC = "dynamic"
    SYSYTEM = "system"


def generate_body_create_group(
    group_name: str, group_type: str = "open", description: str = ""
) -> dict:
    """Generates the body to create group for content_v2_group API"""
    body = {"name": group_name, "type": group_type, "description": description}

    return body

# %% ../../nbs/routes/group.ipynb 19
class CreateGroup_Error(de.DomoError):
    def __init__(self, status, message, domo_instance, function_name="create_group"):
        super().__init__(
            function_name=function_name,
            status=status,
            message=message,
            domo_instance=domo_instance,
        )


async def create_group(
    auth: dmda.DomoAuth,
    group_name: str,
    group_type: str = "open",
    description: str = "",
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
) -> rgd.ResponseGetData:
    # body : {"name": "GROUP_NAME", "type": "open", "description": ""}

    body = generate_body_create_group(
        group_name=group_name, group_type=group_type, description=description
    )

    url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/"

    res = await gd.get_data(
        auth=auth,
        url=url,
        method="POST",
        body=body,
        debug_api=debug_api,
        session=session,
    )

    if not res.is_success:
        group_exists = await search_groups_by_name(
            auth=auth, search_name=group_name, is_exact_match=True
        )
        if group_exists.is_success:
            raise CreateGroup_Error(
                status=res.status,
                message=f"{group_name} already exists. Choose a different group_name",
                domo_instance=auth.domo_instance,
                function_name="create_group",
            )

    if not res.is_success:
        raise CreateGroup_Error(
            status=res.status,
            message=res.response,
            domo_instance=auth.domo_instance,
            function_name="create_group",
        )

    return res

# %% ../../nbs/routes/group.ipynb 22
async def update_group(
    auth: dmda.DomoAuth,
    group_id: int,
    group_name: str = None,
    group_type: str = None,
    description: str = None,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
) -> rgd.ResponseGetData:

    body = [
        {
            "groupId": int(group_id),
            "name": group_name,
            "type": group_type,
            "description": description,
        }
    ]

    url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/"

    res = await gd.get_data(
        auth=auth,
        url=url,
        method="PUT",
        body=body,
        debug_api=debug_api,
        session=session,
    )

    return res

# %% ../../nbs/routes/group.ipynb 26
async def get_group_owners(
    auth: dmda.DomoAuth,
    group_id: str,
    return_raw: bool = False,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
) -> rgd.ResponseGetData:

    # url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/access"
    # url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/users?group={group_id}"
    url = f'https://{auth.domo_instance}.domo.com/api/content/v2/groups/permissions?checkOwnership=true&includeUsers=false'

    res = await gd.get_data(
        auth=auth,
        url=url,
        body = [str(group_id)],
        method="POST",
        debug_api=debug_api,
        session=session,
    )

    if return_raw:
        return res

    res.response = res.response[0].get('permissions').get('owners')
    return res



# %% ../../nbs/routes/group.ipynb 29
async def get_group_membership(
    auth: dmda.DomoAuth,
    group_id: str,
    return_raw: bool = False,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
) -> rgd.ResponseGetData:

    # url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/access"
    url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/users?group={group_id}"

    res = await gd.get_data(
        auth=auth,
        url=url,
        method="GET",
        debug_api=debug_api,
        session=session,
    )

    if return_raw:
        return res

    res.response = res.response.get('groupUserList')
    return res

# %% ../../nbs/routes/group.ipynb 33
def generate_body_update_group_membership_entity(user_id: Union[str, int],
                                                 user_type: str  # USER or GROUP
                                                 ):
    if user_type == 'USER':
        return {"type": "USER", "id": str(user_id)}
    elif user_type == 'GROUP':
        return {"type": "GROUP", "id": int(user_id)}


# %% ../../nbs/routes/group.ipynb 34
def generate_body_update_group_membership(group_id: str,
                                          add_member_arr: list[str] = None,
                                          remove_member_arr: list[str] = None,

                                          add_owner_arr: list[str] = None,
                                          remove_owner_arr: list[str] = None) -> list[dict]:
    """
    each member or owner obj should be an object of shape {"type", "id"}
    """

    body = {"groupId": int(group_id)}

    if add_owner_arr and len(add_owner_arr) > 0 :
        body.update({"addOwners": [generate_body_update_group_membership_entity(
            user_id=obj.get('id'), user_type=obj.get('type')) for obj in add_owner_arr]})

    if remove_owner_arr and len(remove_owner_arr) > 0:
        body.update({"removeOwners": [generate_body_update_group_membership_entity(
            user_id=obj.get('id'), user_type=obj.get('type')) for obj in remove_owner_arr]})

    if remove_member_arr and len(remove_member_arr) > 0:
        body.update({"removeMembers": [
                    generate_body_update_group_membership_entity(user_id=obj.get('id'), user_type=obj.get('type')) for obj in remove_member_arr]})
    if add_member_arr and len(add_member_arr) > 0:
        body.update(
            {"addMembers": [generate_body_update_group_membership_entity(user_id=obj.get('id'), user_type=obj.get('type')) for obj in add_member_arr]})

    return [body]


# %% ../../nbs/routes/group.ipynb 35
async def update_group_membership(
    auth: dmda.DomoAuth,
    group_id: str,
    add_member_arr: list[dict] = None,
    remove_member_arr: list[dict] = None,
    add_owner_arr: list[dict] = None,
    remove_owner_arr: list[dict] = None,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
) -> rgd.ResponseGetData:

    """
    each member or owner obj should be an object of shape {"type", "id"}
    """

    body = generate_body_update_group_membership(group_id = group_id,
                                                 add_member_arr = add_member_arr,
                                                 remove_member_arr= remove_member_arr,
                                                 add_owner_arr = add_owner_arr,
                                                 remove_owner_arr = remove_owner_arr)

    # body = [{
    #     "groupId":"GROUP_ID",
    #     "removeMembers": [{"type":"USER","id":"USER_ID"}],
    #     "addMembers"   : [{"type":"USER","id":"USER_ID"}]
    # }]
    url = f"https://{auth.domo_instance}.domo.com/api/content/v2/groups/access"

    if debug_api:
        print(url, body)

    res = await gd.get_data(
        auth=auth,
        url=url,
        method="PUT",
        body=body,
        debug_api=debug_api,
        session=session,
    )

    return res

