"""Fill in a module description here"""

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

# %% ../nbs/LocalAccount/00_DJ_Workspace.ipynb 2
from __future__ import annotations
from typing import List, Callable
from dataclasses import dataclass, field
import datetime as dt
import pandas as pd

import asyncio

import domolocal.core as dlcr

import domolibrary.client.DomoAuth as dmda
import domolibrary.client.DomoError as dmde
import domolibrary.classes.DomoGroup as dmdg

import domolibrary.utils.chunk_execution as dmce

import domolibrary.classes.DomoJupyter as dmdj
import domolocal.domolibrary_utils as dldm
from nbdev.showdoc import patch_to

# %% auto 0
__all__ = ['DJW_NoAccount', 'DJW_NoGroup', 'DJ_Workspace']

# %% ../nbs/LocalAccount/00_DJ_Workspace.ipynb 3
from domolocal.utils import generate_domo_password

# %% ../nbs/LocalAccount/00_DJ_Workspace.ipynb 7
class DJW_NoAccount(dlcr.ClassError):
    def __init__(self, account_name, domo_instance):
        super().__init__(
            f"unable to retrieve account - {account_name} from {domo_instance}"
        )


class DJW_NoGroup(dlcr.ClassError):
    def __init__(self, group_name, domo_instance):
        super().__init__(
            f"unable to retrieve group - {group_name} from {domo_instance}"
        )

# %% ../nbs/LocalAccount/00_DJ_Workspace.ipynb 8
@dataclass
class DJ_Workspace:
    name: str
    local_auth: dmda.DomoAuth = field(repr=False)
    domo_workspace: dmdj.DomoJupyterWorkspace = field(repr=False)

    domojupyter_fn: Callable = field(repr=False)

    generate_password_fn: Callable = field(repr=False, default=None)

    default_share_group_name: str = None
    default_share_group_owner_names: list[str] = field(
        default_factory=lambda: [
            "Role: sie_instance_admin",
            "Role: sie_dde_instance_admin",
        ]
    )

    dj_accounts: List[Any] = field(repr=False, default_factory=list)

    fix_no_account: List[str] = field(default_factory=list)
    fix_reset_password: List[str] = field(default_factory=list)
    fix_regenerate_access_token: List[str] = field(default_factory=list)

    def __eq__(self, other):
        if self.__class__.__name__ != other.__class__.__name__:
            return False

        return (
            self.name == other.name
            and self.local_auth.domo_instance == other.local_auth.domo_instance
        )

    @classmethod
    async def from_workspace_name(
        cls,
        auth: dmda.DomoAuth,
        workspace_name: str,
        domojupyter_fn: Callable,
        generate_password_fn: Callable = None,
        default_share_group_name: str = None,
        default_share_group_owner_names: list[str] = None,
    ):

        default_share_group_owner_names = default_share_group_owner_names or [
            "Role: sie_instance_admin",
            "Role: sie_dde_instance_admin",
        ]

        domo_workspace = await dmdj.search_workspace_by_name(
            auth=auth, workspace_name=workspace_name
        )

        return cls(
            name=workspace_name,
            local_auth=auth,
            domo_workspace=domo_workspace,
            domojupyter_fn=domojupyter_fn,
            generate_password_fn=generate_password_fn,
            default_share_group_name=default_share_group_name,
            default_share_group_owner_names=default_share_group_owner_names,
        )

# %% ../nbs/LocalAccount/00_DJ_Workspace.ipynb 10
@patch_to(DJ_Workspace)
async def add_account_to_jupyter_workspace(
    self, account_name, share_group_name=None, config=None
):
    try:
        domo_account = await dldm.search_domo_account_by_name(
            auth=self.local_auth, account_name=account_name
        )

        share_group_name = share_group_name or self.default_share_group_name

        share_domo_group = await dldm.search_or_upsert_domo_group(
            auth=self.local_auth, group_name=share_group_name, upsert_if_not_exist=True
        )

        await domo_account._share_v2(group_id=share_domo_group.id, auth=self.local_auth)

        await self.domo_workspace.add_account(
            domo_account=domo_account, update_config=False
        )

        return await self.domo_workspace.update_config()

    except (dmde.DomoError, DJW_NoAccount) as e:
        self.dj_workspace.fix_no_account.append(config)


@patch_to(DJ_Workspace)
def generate_config_from_domo_instace(self, domo_instance, account_name=None):

    import domolocal.DJ_WorkspaceAccount as dlwa

    try:
        account_name = account_name or f"sdk_{domo_instance}"
        return dlwa.DJ_WorkspaceAccount.from_workspace_by_account_name(
            domo_instance=domo_instance,
            local_account_name=account_name,
            dj_workspace=self,
        )

    except DJW_NoAccount as e:
        print(f"🤯 - {e} - {domo_instance}")
        self.fix_no_account.append(domo_instance)
        return None

# %% ../nbs/LocalAccount/00_DJ_Workspace.ipynb 12
@patch_to(DJ_Workspace)
def generate_configs_from_domo_instances(
    self: DJ_Workspace, domo_instance_ls: List[str]
):

    self.local_configs = [
        self.generate_config_from_domo_instace(domo_instance=domo_instance)
        for domo_instance in domo_instance_ls
    ]

    return self.local_configs

# %% ../nbs/LocalAccount/00_DJ_Workspace.ipynb 14
class DJW_NoConfigs(dlcr.ClassError):
    def __init__(self):
        super().__init__("no configs in self.local_configs.  Run generate_configs")


@patch_to(DJ_Workspace)
async def generate_fix_report(self) -> pd.DataFrame:
    if not self.local_configs:
        raise DJW_NoConfigs()

    for config in self.local_configs:
        try:
            await config.test_local_creds()
            if not config.is_valid_full_auth:
                self.fix_password.append(config.domo_instance)
            if not config.is_valid_token_auth:
                self.regenerate_access_token.append(config.domo_instance)

        except (DJW_NoAccount, Exception) as e:
            self.fix_no_account.append(config)

    df = [
        *[
            {"domo_instance": domo_instance, "task": "no_account"}
            for domo_instance in self.fix_no_account
            if domo_instance
        ],
        *[
            {"domo_instance": la.target_instance, "task": "reset_password"}
            for la in self.fix_reset_password
            if la
        ],
        *[
            {
                "domo_instance": la.target_instance,
                "task": "regenerate_access_token",
            }
            for la in self.fix_regenerate_access_token
            if la
        ],
    ]

    return {"num_errors_to_fix": len(df), "report": df}
