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

# %% auto 0
__all__ = ['DomoAppStudio', 'DomoAppStudios']

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 2
from ..routes.appstudio import AppStudioRetrieval_byId_Error

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 3
from nbdev.showdoc import patch_to
from dataclasses import dataclass, field
from typing import List

import httpx

import domolibrary.client.Logger as lg
import domolibrary.client.DomoError as de
import domolibrary.client.DomoAuth as dmda
import domolibrary.classes.DomoPage_Content as dmpg_c
import domolibrary.routes.appstudio as appstudio_routes

import domolibrary.utils.DictDot as util_dd
import domolibrary.utils.chunk_execution as ce

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 6
@dataclass
class DomoAppStudio:
    id: int
    title: str = None
    auth: dmda.DomoAuth = field(default=None, repr=False)
    is_locked: bool = None

    owners: list = field(default_factory=list)

    custom_attributes: dict = field(default_factory=dict)

    @classmethod
    async def _from_content_stacks_v3(cls, page_obj, auth: dmda.DomoAuth = None):

        dd = page_obj
        if isinstance(page_obj, dict):
            dd = util_dd.DictDot(page_obj)

        aps = cls(
            id=int(dd.dataAppId),
            title=dd.title or dd.Title,
            is_locked=dd.locked,
            auth=auth,
        )

        if dd.owners and len(dd.owners) > 0:
            aps.owners = await aps._get_domo_owners_from_dd(dd.owners)

        return aps

    @classmethod
    async def get_by_id(
        cls,
        appstudio_id: str,
        auth: dmda.DomoAuth,
        return_raw: bool = False,
        debug_api: bool = False,
        session: httpx.AsyncClient = None,
        debug_num_stacks_to_drop: int = 2,
    ):

        res = await appstudio_routes.get_apstudio_by_id(
            auth=auth,
            appstudio_id=appstudio_id,
            debug_api=debug_api,
            session=session,
            debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        )

        if return_raw:
            return res

        return await cls._from_content_stacks_v3(page_obj=res.response, auth=auth)

    @classmethod
    async def _get_by_id(
        cls,
        id: str,
        auth: dmda.DomoAuth,
        return_raw: bool = False,
        debug_api: bool = False,
        session: httpx.AsyncClient = None,
        debug_num_stacks_to_drop: int = 2,
    ):

        return await cls.get_by_id(
            auth=auth,
            appstudio_id=id,
            debug_api=debug_api,
            session=session,
            debug_num_stacks_to_drop=debug_num_stacks_to_drop,
            return_raw = return_raw,
        )

    def display_url(self):
        return f"https://{self.auth.domo_instance}.domo.com/app-studio/{self.id}"

    async def _get_domo_owners_from_dd(self, owners: util_dd.DictDot):
        if not owners or len(owners) == 0:
            return []

        import domolibrary.classes.DomoUser as dmu
        import domolibrary.classes.DomoGroup as dmg

        domo_groups = []
        domo_users = []

        owner_group_ls = [
            owner.id for owner in owners if owner.type == "GROUP" and owner.id
        ]

        if len(owner_group_ls) > 0:
            domo_groups = await ce.gather_with_concurrency(
                n=60,
                *[
                    dmg.DomoGroup.get_by_id(group_id=group_id, auth=self.auth)
                    for group_id in owner_group_ls
                ],
            )

        owner_user_ls = [
            owner.id for owner in owners if owner.type == "USER" and owner.id
        ]

        if len(owner_user_ls) > 0:
            domo_users = await dmu.DomoUsers.by_id(
                user_ids=owner_user_ls, only_allow_one=False, auth=self.auth
            )

        owner_ce = (domo_groups or []) + (domo_users or [])

        res = []
        for owner in owner_ce:
            if isinstance(owner, list):
                [res.append(member) for member in owner]
            else:
                res.append(owner)

        return res

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 7
@patch_to(DomoAppStudio, cls_method=True)
async def _from_adminsummary(cls, appstudio_obj, auth: dmda.DomoAuth):

    dd = appstudio_obj

    if isinstance(appstudio_obj, dict):
        dd = util_dd.DictDot(appstudio_obj)

    aps = cls(
        id=int(dd.id or dd.dataAppId),
        title=dd.title or dd.Title,
        is_locked=dd.locked,
        auth=auth,
    )

    if dd.owners and len(dd.owners) > 0:
        aps.owners = await aps._get_domo_owners_from_dd(dd.owners)
        

    return aps

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 11
@dataclass
class DomoAppStudios:

    @classmethod
    async def get_appstudios(
        cls,
        auth=dmda.DomoAuth,
        return_raw: bool = False,
        debug_api: bool = False,
        debug_loop: bool = False,
        session: httpx.AsyncClient = None,
    ):
        """use admin_summary to retrieve all appstudios in an instance -- regardless of user access
        NOTE: some appstudios APIs will not return results if appstudio access isn't explicitly shared
        """
        is_close_session = False if session else True

        session = session or httpx.AsyncClient()

        try:
            res = await appstudio_routes.get_appstudios_adminsummary(
                auth=auth, debug_loop=debug_loop, debug_api=debug_api, session=session
            )

            if return_raw:
                return res

            if not res.is_success:
                raise Exception("unable to retrieve appstudios")

            return await ce.gather_with_concurrency(
                n=60,
                *[
                    DomoAppStudio._from_adminsummary(page_obj, auth=auth)
                    for page_obj in res.response
                ],
            )

        finally:
            if is_close_session:
                await session.aclose()

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 14
@patch_to(DomoAppStudio)
async def get_accesslist(
    self,
    auth: dmda.DomoAuth = None,
    return_raw: bool = False,
    debug_api: bool = False,
):
    auth = auth or self.auth

    res = await appstudio_routes.get_appstudio_access(
        auth=auth,
        appstudio_id=self.id,
        debug_api=debug_api,
        debug_num_stacks_to_drop=2,
        parent_class=self.__class__.__name__,
    )

    if return_raw:
        return res

    if not res.is_success:
        raise Exception("error getting access list")

    import domolibrary.classes.DomoUser as dmu
    import domolibrary.classes.DomoGroup as dmg

    s = {
        #"explicit_shared_user_count": res.response.get("explicitSharedUserCount"),
        "total_user_count": res.response.get("totalUserCount"),
    }

    user_ls = res.response.get("users", None)
    domo_users = []
    if user_ls and isinstance(user_ls, list) and len(user_ls) > 0:
        domo_users = await dmu.DomoUsers.by_id(
            user_ids=[user.get("id") for user in user_ls],
            only_allow_one=False,
            auth=auth,
        )

    group_ls = res.response.get("groups", None)
    domo_groups = []
    if group_ls and isinstance(group_ls, list) and len(group_ls) > 0:
        domo_groups = await ce.gather_with_concurrency(
            n=60,
            *[
                dmg.DomoGroup.get_by_id(group_id=group.get("id"), auth=auth)
                for group in group_ls
            ],
        )


    return {
        **s,
        "domo_users": domo_users,
        "domo_groups": domo_groups,
    }

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 17
@patch_to(DomoAppStudio)
async def share(
    self: DomoAppStudio,
    auth: dmda.DomoAuth = None,
    domo_users: list = None,  # DomoUsers to share page with,
    domo_groups: list = None,  # DomoGroups to share page with
    message: str = None,  # message for automated email
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
):


    if domo_groups:
        domo_groups = domo_groups if isinstance(domo_groups, list) else [domo_groups]
    if domo_users:
        domo_users = domo_users if isinstance(domo_users, list) else [domo_users]

    
    res = await appstudio_routes.share(
    auth=auth or self.auth,
    resource_ids=[self.id],
    group_ids=[group.id for group in domo_groups] if domo_groups else None,
    user_ids=[user.id for user in domo_users] if domo_users else None,
    message=message,
    debug_api=debug_api,
    session=session)

    return res

# %% ../../nbs/classes/50_DomoAppStudio.ipynb 20
@patch_to(DomoAppStudio, cls_method=True)
async def add_appstudio_owner(
    cls,
    auth: dmda.DomoAuth,
    appstudio_id_ls: List[int],  # AppStudio IDs to be updated by owner,
    group_id_ls: List[int],  # DomoGroup IDs to share page with
    user_id_ls: List[int],  # DomoUser IDs to share page with
    note: str = None,  # message for automated email
    send_email: bool = False,  # send or not email to the new owners
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
):
    res = await appstudio_routes.add_page_owner(
        auth=auth,
        appstudio_id_ls=appstudio_id_ls,
        group_id_ls=group_id_ls,
        user_id_ls=user_id_ls,
        note=note,
        send_email=send_email,
        debug_api=debug_api,
        session=session,
    )

    return res
