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

# %% auto 0
__all__ = ['MFAConfig_InstantiationError', 'MFA_Config']

# %% ../../nbs/classes/50_DomoInstanceConfig_MFA.ipynb 2
import httpx
from nbdev.showdoc import patch_to
from typing import List

from dataclasses import dataclass, field
import domolibrary.client.DomoAuth as dmda
import domolibrary.client.DomoError as dmde

import domolibrary.routes.instance_config_mfa as mfa_routes

# %% ../../nbs/classes/50_DomoInstanceConfig_MFA.ipynb 6
class MFAConfig_InstantiationError(dmde.ClassError):

    def __init__(self, message, auth: dmda.DomoAuth, cls):

        super().__init__(domo_instance=auth.domo_instance, message=message, cls=cls)


@dataclass
class MFA_Config:
    auth: dmda.DomoAuth = field(repr=False)
    is_multifactor_required: bool = None
    max_code_attempts: int = None
    num_days_valid: int = None

    @classmethod
    def _from_json(cls, auth: dmda.DomoAuth, obj: List[dict]):

        return cls(
            auth=auth,
            is_multifactor_required=obj.get("is_multifactor_required"),
            num_days_valid=obj.get("num_days_valid"),
            max_code_attempts=obj.get("max_code_attempts"),
        )

    @classmethod
    async def get_instance_config(
        cls,
        auth: dmda.DomoAuth,
        incl_is_multifactor_required: bool = True,
        incl_num_days_valid: bool = True,
        incl_max_code_attempts: bool = True,
        session: httpx.AsyncClient = None,
        debug_api: bool = False,
        debug_num_stacks_to_drop: int = 2,
        return_raw: bool = False,
    ):
        res = await mfa_routes.get_mfa_config(
            auth=auth,
            incl_is_multifactor_required=incl_is_multifactor_required,
            incl_num_days_valid=incl_num_days_valid,
            incl_max_code_attempts=incl_max_code_attempts,
            session=session,
            debug_api=debug_api,
            parent_class=cls.__name__,
            debug_num_stacks_to_drop=debug_num_stacks_to_drop,
            return_raw=return_raw,
        )

        if return_raw:
            return res

        if res.is_success and not (isinstance(res.response, dict)):
            raise MFAConfig_InstantiationError(
                auth=auth,
                message=f"must enable MFA to get MFA config from {auth.domo_instance}",
            )

        return cls._from_json(auth=auth, obj=res.response)

    async def get(
        self,
        session: httpx.AsyncClient = None,
        debug_api: bool = False,
        debug_num_stacks_to_drop=2,
        return_raw: bool = False
    ):
        res = await mfa_routes.get_mfa_config(
            auth=self.auth,
            incl_is_multifactor_required=True,
            incl_num_days_valid=True,
            incl_max_code_attempts=True,
            session=session,
            debug_api=debug_api,
            parent_class=self.__class__.__name__,
            debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        )

        if return_raw:
            return res

        self.num_days_valid = res.response.get("num_days_valid")
        self.max_code_attempts = res.response.get("max_code_attempts")
        self.is_multifactor_required = res.response.get("is_multifactor_required")

        return self

# %% ../../nbs/classes/50_DomoInstanceConfig_MFA.ipynb 8
@patch_to(MFA_Config)
def _test_need_update_config(self, attr_name, new_value, is_ignore_test: bool = False, debug_prn: bool = False):
    current_value = getattr(self, attr_name)

    if new_value is None:
        return False

    if new_value == current_value and not is_ignore_test:
        if debug_prn:
            print(f"No change necessary -- {current_value} is the same as {new_value}")
        return False

    return True


@patch_to(MFA_Config)
async def toggle_mfa(
    self,
    is_enable_MFA: bool,
    is_ignore_test: bool = False,
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
    suppress_update_self: bool = False,
    debug_prn: bool = False
):
    need_update_config = self._test_need_update_config(
        attr_name="is_multifactor_required",
        new_value=is_enable_MFA,
        is_ignore_test=is_ignore_test,
        debug_prn = debug_prn
    )

    if not need_update_config:
        return self

    await mfa_routes.toggle_enable_mfa(
        auth=self.auth,
        is_enable_MFA=is_enable_MFA,
        session=session,
        debug_api=debug_api,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
    )

    if suppress_update_self:
        return self

    return await self.get()


@patch_to(MFA_Config)
async def enable(
    self,
    is_ignore_test: bool = False,
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
):
    """will have enable_value=True and will enable mfa in the instance"""
    return await self.toggle_mfa(
        is_ignore_test=is_ignore_test,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop,
        is_enable_MFA=True,
    )


@patch_to(MFA_Config)
async def disable(
    self,
    is_ignore_test: bool = False,
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
):
    """will have enable_value=False and will disable mfa in the instance"""
    return await self.toggle_mfa(
        is_ignore_test=is_ignore_test,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
        is_enable_MFA=False,
    )


@patch_to(MFA_Config)
async def set_max_code_attempts(
    self,
    max_code_attempts: int,
    is_ignore_test: bool = False,
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
    suppress_update_self: bool = False,
    debug_prn: bool = False
):
    need_update_config = self._test_need_update_config(
        attr_name="max_code_attempts",
        new_value=max_code_attempts,
        is_ignore_test=is_ignore_test,
        debug_prn=debug_prn
    )

    if not need_update_config:
        return self

    await mfa_routes.set_mfa_max_code_attempts(
        auth=self.auth,
        max_code_attempts=max_code_attempts,
        session=session,
        debug_api=debug_api,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
    )

    if suppress_update_self:
        return self

    return await self.get()


@patch_to(MFA_Config)
async def set_num_days_valid(
    self,
    num_days_valid: int,
    is_ignore_test: bool = False,
    session: httpx.AsyncClient = None,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
    suppress_update_self: bool = False,
    debug_prn: bool = False
):
    need_update_config = self._test_need_update_config(
        attr_name="num_days_valid",
        new_value=num_days_valid,
        is_ignore_test=is_ignore_test,
        debug_prn=debug_prn
    )

    if not need_update_config:
        return self

    await mfa_routes.set_mfa_num_days_valid(
        auth=self.auth,
        num_days_valid=num_days_valid,
        session=session,
        debug_api=debug_api,
        parent_class=self.__class__.__name__,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
    )
    if not suppress_update_self:
        return self

    return await self.get()

# %% ../../nbs/classes/50_DomoInstanceConfig_MFA.ipynb 10
@patch_to(MFA_Config)
async def update(
    self,
    is_enable_MFA: bool = None,
    max_code_attempts: int = None,
    num_days_valid: int = None,
    session: httpx.AsyncClient = None,
    return_raw: bool = False,
    debug_api: bool = False,
    debug_num_stacks_to_drop: int = 2,
    debug_prn: bool = False,
):

    await self.toggle_mfa(
        is_enable_MFA=is_enable_MFA,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
        suppress_update_self=True,
        debug_prn=debug_prn,
        
    )

    await self.set_max_code_attempts(
        max_code_attempts=max_code_attempts,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
        suppress_update_self=True,
        debug_prn=debug_prn,
    )

    await self.set_num_days_valid(
        num_days_valid=num_days_valid,
        session=session,
        debug_api=debug_api,
        debug_num_stacks_to_drop=debug_num_stacks_to_drop + 1,
        suppress_update_self=True,
        debug_prn=debug_prn,
    )

    return await self.get(debug_api = debug_api, return_raw = return_raw)

