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

# %% auto 0
__all__ = ['DomoInstanceConfig']

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 2
from domolibrary.routes.instance_config_sso import (
    SSO_AddUserDirectSignonError,
    SSO_GET_Error,
    SSO_CRUD_Error,
)
from domolibrary.routes.instance_config import (
    ToggleSocialUsers_Error,
    ToggleUserInvite_Error,
    Config_GET_Error,
    Allowlist_UnableToUpdate,
    GetDomains_NotFound,
    InstanceConfig_Error,
    GetAppDomains_NotFound,
)

from ..routes.publish import GET_Publish_Error

from domolibrary.classes.DomoInstanceConfig_ApiClient import (
    ApiClient_GET_Error,
    ApiClient_RevokeError,
    ApiClient_CRUD_Error,
    ApiClient_Search_Error,
    ApiClient_ScopeEnum,
    ApiClient,
)

from domolibrary.classes.DomoInstanceConfig_SSO import (
    SSO_CRUD_Error,
    SSO_GET_Error,
    SSOConfig_InstantiationError,
    SSOConfig_UpdateError,
    SSO_SAML_Config,
    SSO_OIDC_Config,
)


from domolibrary.classes.DomoInstanceConfig_InstanceSwitcher import (
    DomoInstanceConfig_InstanceSwitcher_Mapping,
    DomoInstanceConfig_InstanceSwitcher,
)

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 3
import httpx
import datetime as dt
from nbdev.showdoc import patch_to
from typing import List
import pandas as pd

from dataclasses import dataclass, field

import domolibrary.utils.DictDot as util_dd
import domolibrary.utils.chunk_execution as dmce
import domolibrary.utils.convert as cd


import domolibrary.client.DomoError as dmde
import domolibrary.client.DomoAuth as dmda

import domolibrary.routes.instance_config as instance_config_routes
import domolibrary.routes.sandbox as sandbox_routes
import domolibrary.routes.application as application_routes

import domolibrary.classes.DomoAccount as dmac
import domolibrary.classes.DomoAccessToken as dmat
import domolibrary.classes.DomoDataset_Connector as dmdsc
import domolibrary.classes.DomoGrant as dmgr

import domolibrary.classes.DomoInstanceConfig_UserAttribute as dicua
import domolibrary.classes.DomoInstanceConfig_SSO as dicsso
import domolibrary.classes.DomoInstanceConfig_ApiClient as dicli
import domolibrary.classes.DomoInstanceConfig_MFA as dimfa

import domolibrary.classes.DomoPublish as dmpb
import domolibrary.classes.DomoRole as dmrl

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 7
@dataclass
class DomoInstanceConfig:
    """utility class that absorbs many of the domo instance configuration methods"""

    auth: dmda.DomoAuth = field(repr=False)

    allowlist: list[str] = field(default_factory=list)

    is_sandbox_self_instance_promotion_enabled: bool = field(default=None)
    is_user_invite_notification_enabled: bool = field(default=None)
    is_invite_social_users_enabled: bool = field(default=None)

    Accounts: dmac.DomoAccounts = field(default = None)
    AccessTokens: dmat.DomoAccessTokens = field(default=None)
    ApiClients: dicli.ApiClients = field(default=None)

    Connectors: dmdsc.DomoConnectors = field(default=None)
    InstanceSwitcher: DomoInstanceConfig_InstanceSwitcher = field(default=None)

    Grants: dmgr.DomoGrants = field(default=None)

    MFA: dimfa.MFA_Config = field(default=None)
    Roles: dmrl.DomoRoles = field(default=None)

    SSO: dicsso.SSO_Config = field(default=None)
    Publish: dmpb.DomoPublications = field(default=None)
    UserAttributes: dicua.UserAttributes = field(default=None)

    def __post_init__(self):
        self.Accounts = dmac.DomoAccounts(auth = self.auth)
        self.AccessTokens = dmat.DomoAccessTokens(auth=self.auth)
        self.ApiClients = dicli.ApiClients(auth=self.auth)
        self.Connectors = dmdsc.DomoConnectors(auth=self.auth)
        self.Grants = dmgr.DomoGrants(auth=self.auth)
        self.InstanceSwitcher = DomoInstanceConfig_InstanceSwitcher(auth=self.auth)
        self.MFA = dimfa.MFA_Config(auth=self.auth)
        self.Publish = dmpb.DomoPublications(auth=self.auth)
        self.UserAttributes = dicua.UserAttributes(auth=self.auth)
        self.Roles = dmrl.DomoRoles(auth=self.auth)
        self.SSO = dicsso.SSO(auth=self.auth)

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 15
@patch_to(DomoInstanceConfig)
async def get_allowlist(
    self: DomoInstanceConfig,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
    debug_api: bool = False,
    debug_num_stacks_to_drop=2,
) -> list[str]:
    """
    retrieves the allowlist for an instance
    requires FullAuth
    """

    res = await instance_config_routes.get_allowlist(
        auth=self.auth,
        debug_api=debug_api,
        session=session,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    if return_raw:
        return res

    self.allowlist = res.response.get("addresses")

    return self.allowlist


@patch_to(DomoInstanceConfig)
async def set_allowlist(
    self: DomoInstanceConfig,
    ip_address_ls: list[str],
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
):
    """modifying the allowlist requires ull auth"""

    await instance_config_routes.set_allowlist(
        ip_address_ls=ip_address_ls,
        auth=self.auth,
        debug_api=debug_api,
        session=session,
    )

    return await self.get_allowlist(debug_api=debug_api, session=session)


@patch_to(DomoInstanceConfig)
async def upsert_allowlist(
    self: DomoInstanceConfig,
    ip_address_ls: List[str],  # list of ip_v4 ip addresses to upsert to allowlist
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
):
    """
    will only UPDATE or INSERT ip addresses
    note: the API will SET the allowlist, so must GET and then merge ips before setting
    """
    exist_ip_address_ls = await self.get_allowlist(debug_api=debug_api, session=session)
    ip_address_ls += exist_ip_address_ls

    return await self.set_allowlist(
        ip_address_ls=list(set(ip_address_ls)),
        debug_api=debug_api,
        session=session,
    )


# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 20
@patch_to(DomoInstanceConfig)
async def get_applications(
    self,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
    debug_num_stacks_to_drop=2,
):
    import domolibrary.classes.DomoApplication as dmapp

    res = await application_routes.get_applications(
        auth=self.auth,
        debug_api=debug_api,
        session=session,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    if return_raw:
        return res

    return [
        dmapp.DomoApplication._from_json(job, auth=self.auth) for job in res.response
    ]

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 23
@patch_to(DomoInstanceConfig)
async def generate_applications_report(
    self,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
    debug_num_stacks_to_drop=2,
):
    import domolibrary.classes.DomoApplication as dmapp

    domo_apps = await self.get_applications(
        debug_api=debug_api,
        session=session,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        return_raw=return_raw,
    )

    if return_raw:
        return domo_apps

    df = pd.DataFrame([app.__dict__ for app in domo_apps])
    df["domo_instance"] = self.auth.domo_instance

    df.drop(columns=["auth"], inplace=True)
    df.rename(
        columns={
            "id": "application_id",
            "name": "application_name",
            "description": "application_description",
            "version": "application_version",
        },
        inplace=True,
    )

    return df.sort_index(axis=1)

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 31
@patch_to(DomoInstanceConfig)
async def get_authorized_domains(
    self: DomoInstanceConfig,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
) -> List[str]:
    """returns a list of authorized domains (str) does not update instance_config"""

    res = await instance_config_routes.get_authorized_domains(
        auth=self.auth, debug_api=debug_api, session=session, return_raw=return_raw
    )

    if return_raw:
        return res

    return res.response


@patch_to(DomoInstanceConfig)
async def set_authorized_domains(
    self: DomoInstanceConfig,
    authorized_domains: List[str],
    debug_api: bool = False,
    debug_num_stacks_to_drop=1,
    session: httpx.AsyncClient = None,
):

    res = await instance_config_routes.set_authorized_domains(
        auth=self.auth,
        authorized_domain_ls=authorized_domains,
        debug_api=debug_api,
        session=session,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    return res


@patch_to(DomoInstanceConfig)
async def upsert_authorized_domains(
    self: DomoInstanceConfig,
    authorized_domains: List[str],
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    debug_num_stacks_to_drop=2,
):

    existing_domains = await self.get_authorized_domains(
        debug_api=debug_api,
        session=session,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
    )

    authorized_domains += existing_domains

    return await self.set_authorized_domains(
        authorized_domains=authorized_domains,
        debug_api=debug_api,
        session=session,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
    )

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 35
@patch_to(DomoInstanceConfig)
async def get_authorized_custom_app_domains(
    self: DomoInstanceConfig,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
    debug_num_stacks_to_drop=2,
) -> List[str]:

    res = await instance_config_routes.get_authorized_custom_app_domains(
        auth=self.auth,
        debug_api=debug_api,
        session=session,
        return_raw=return_raw,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    if return_raw:
        return res

    return res.response


# | exporti
@patch_to(DomoInstanceConfig)
async def set_authorized_custom_app_domains(
    self: DomoInstanceConfig,
    authorized_domains: List[str],
    debug_api: bool = False,
    debug_num_stacks_to_drop=2,
    session: httpx.AsyncClient = None,
):
    res = await instance_config_routes.set_authorized_custom_app_domains(
        auth=self.auth,
        authorized_custom_app_domain_ls=authorized_domains,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        session=session,
        parent_class=self.__class__.__name__,
    )

    return res


@patch_to(DomoInstanceConfig)
async def upsert_authorized_custom_app_domains(
    self: DomoInstanceConfig,
    authorized_domains: List[str],
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
    session: httpx.AsyncClient = None,
):
    existing_domains = await self.get_authorized_custom_app_domains(
        debug_api=debug_api,
        session=session,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
    )

    authorized_domains += existing_domains

    return await self.set_authorized_custom_app_domains(
        authorized_custom_app_domain_ls=authorized_domains,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
        session=session,
    )

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 47
@patch_to(DomoInstanceConfig)
async def get_sandbox_is_same_instance_promotion_enabled(
    self: DomoInstanceConfig,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
    debug_num_stacks_to_drop=2,
):

    res = await sandbox_routes.get_is_allow_same_instance_promotion_enabled(
        auth=self.auth,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        parent_class=self.__class__.__name__,
    )

    self.is_sandbox_self_instance_promotion_enabled = res.response["is_enabled"]

    if return_raw:
        return res

    return res.response

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 50
@patch_to(DomoInstanceConfig)
async def toggle_sandbox_allow_same_instance_promotion(
    self: DomoInstanceConfig,
    is_enabled: bool,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
    debug_num_stacks_to_drop=2,
):
    """will enable or disable same instance promotion for sandbox"""

    res = await sandbox_routes.toggle_allow_same_instance_promotion(
        auth=self.auth,
        session=session,
        is_enabled=is_enabled,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        parent_class=self.__class__.__name__,
    )

    res_is_enabled = await self.get_sandbox_is_same_instance_promotion_enabled()

    if return_raw:
        return res

    return res_is_enabled

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 53
@patch_to(DomoInstanceConfig)
async def get_is_user_invite_notification_enabled(
    self: DomoInstanceConfig,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    debug_num_stacks_to_drop: int = 2,
    return_raw: bool = False,
):
    """
    Admin > Company Settings > Admin Notifications
    Toggles whether user recieves 'You've been Domo'ed email
    """

    res = await instance_config_routes.get_is_user_invite_notifications_enabled(
        auth=self.auth,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        parent_class=self.__class__.__name__,
    )

    self.is_user_invite_notification_enabled = res.response["is_enabled"]

    if return_raw:
        return res

    return res.response


@patch_to(DomoInstanceConfig)
async def toggle_is_user_invite_notification_enabled(
    self: DomoInstanceConfig,
    is_enabled: bool,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    debug_num_stacks_to_drop: int = 2,
    return_raw: bool = False,
):
    res_is_enabled = await self.get_is_user_invite_notification_enabled()

    if is_enabled == self.is_user_invite_notification_enabled:

        return res_is_enabled

    res = await instance_config_routes.toggle_is_user_invite_enabled(
        auth=self.auth,
        is_enabled=is_enabled,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        parent_class=self.__class__.__name__,
    )

    res_is_enabled = await self.get_is_user_invite_notification_enabled()

    if return_raw:
        return res

    return res_is_enabled

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 57
class InstanceConfig_ClassError(dmde.ClassError):
    def __init__(self, cls_instance, message):
        super().__init__(
            cls_instance=cls_instance,
            message=message,
            entity_id=cls_instance.auth.domo_instance,
        )


@patch_to(DomoInstanceConfig)
async def get_is_invite_social_users_enabled(
    self: DomoInstanceConfig,
    customer_id: str = None,
    debug_api: bool = False,
    debug_num_stacks_to_drop=2,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
):
    """checks if users can be invited as social users to the instaance"""

    if not customer_id:
        import domolibrary.classes.DomoBootstrap as dmbp

        try:
            bs = dmbp.DomoBootstrap(auth=self.auth)
            customer_id = await bs.get_customer_id()

        except dmda.InvalidAuthTypeError as e:
            raise InstanceConfig_ClassError(
                self,
                message=f"{e.__class__.__name__} -- bootstrap API requires FullAuth OR pass customer_id",
            ) from e

    res = await instance_config_routes.get_is_invite_social_users_enabled(
        auth=self.auth,
        customer_id=customer_id,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        parent_class=self.__class__.__name__,
    )

    self.is_invite_social_users_enabled = res.response["is_enabled"]

    if return_raw:
        return res

    return res.response


@patch_to(DomoInstanceConfig)
async def toggle_is_invite_social_users_enabled(
    self: DomoInstanceConfig,
    is_enabled: bool,
    debug_api: bool = False,
    session: httpx.AsyncClient = None,
    debug_num_stacks_to_drop=2,
    return_raw: bool = False,
):
    """enables or disables the ability to invite users to instance as social users"""

    res_is_enabled = await self.get_is_invite_social_users_enabled()

    if is_enabled == self.is_invite_social_users_enabled:
        return res_is_enabled

    res = await instance_config_routes.toggle_is_social_users_enabled(
        auth=self.auth,
        is_enabled=is_enabled,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        parent_class=self.__class__.__name__,
    )

    res_is_enabled = await self.get_is_invite_social_users_enabled()

    if return_raw:
        return res

    return res_is_enabled

# %% ../../nbs/classes/50_DomoInstanceConfig.ipynb 67
@patch_to(DomoInstanceConfig)
async def get_is_weekly_digest_enabled(
    self: DomoInstanceConfig,
    return_raw: bool = False,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
    session: httpx.AsyncClient = None,
):
    """the weekly digest is a weekly email from Domo of changes to the instance"""

    res = await instance_config_routes.get_is_weekly_digest_enabled(
        auth=self.auth,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        parent_class=self.__class__.__name__,
    )

    if return_raw:
        return res

    self.is_weekly_digest_enabled = res.response["is_enabled"]

    return res.response


@patch_to(DomoInstanceConfig)
async def toggle_is_weekly_digest_enabled(
    self: DomoInstanceConfig,
    is_enabled: bool,
    return_raw: bool = False,
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    debug_prn: bool = False,
    debug_num_stacks_to_drop=2,
):
    """toggles if weekly digest is enabled or disabled"""

    res_is_enabled = await self.get_is_weekly_digest_enabled()

    if is_enabled == self.is_weekly_digest_enabled:
        if debug_prn:
            print(
                f"weekly digest is already {'enabled' if is_enabled else 'disabled'} in {self.auth.domo_instance}"
            )
        return res_is_enabled

    if debug_prn:
        print(
            f"{'enabling' if is_enabled else 'disabling'} weekly digest {self.auth.domo_instance}"
        )

    res = await instance_config_routes.toggle_is_weekly_digest_enabled(
        auth=self.auth,
        is_enabled=is_enabled,
        session=session,
        debug_api=debug_api,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
    )

    res_is_enabled = await self.get_is_weekly_digest_enabled()

    if return_raw:
        return res

    return res_is_enabled
