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

# %% auto 0
__all__ = ['getannkeys', 'get_kws_at_lvl', 'getattrs_at_lvl', 'get_kws_cur', 'get_kws_all', 'get_kws_inh', 'getattrs_cur',
           'getattrs_all', 'getattrs_inh']

# %% ../nbs/00_utils.ipynb 4
from typing import (Type, Tuple, Union)

# %% ../nbs/00_utils.ipynb 6
from ispec.types import AttrLvl, isint
from ispec.utils import getattrs
from ispec.ann import getannargs
from ispec.agg import aggattrs

# %% ../nbs/00_utils.ipynb 8
def getannkeys(obj) -> list:
    return list(getannargs(obj).keys())

def get_kws_at_lvl(obj, lvl: AttrLvl, agg: bool = True, return_cls: bool = False, verbose: bool = False) -> Union[dict, Tuple[dict, Type]]:
    return aggattrs(
        obj=obj, lvl=lvl, agg=agg,
        return_cls=return_cls, return_arr=True,
        verbose=verbose, getkwsfunc=getannkeys
    )

# %% ../nbs/00_utils.ipynb 10
def getattrs_at_lvl(obj, lvl: AttrLvl, agg: bool = True, use_lvl_vals: bool = False, verbose: bool = False) -> dict:
    kws, lvlcls = get_kws_at_lvl(obj, lvl, agg, return_cls=True, verbose=verbose)
    lvlcls = (lvlcls if isint(lvl) else lvl)
    
    lvlkws = getattrs(lvlcls, kws)
    curkws = getattrs(obj, kws)
    params = lvlkws.copy()
    if not agg:
        return params

    if use_lvl_vals: 
        params.update({k: v for k, v in curkws.items() if lvlkws.get(k, None) is None})    
    else:
        params.update(curkws)
    return params

# %% ../nbs/00_utils.ipynb 12
def get_kws_cur(obj, verbose: bool = False) -> list:
    kws = get_kws_at_lvl(obj, 0, agg=True, return_cls=False, verbose=verbose)
    return kws

def get_kws_all(obj, verbose: bool = False) -> list:
    kws = get_kws_at_lvl(obj, float('inf'), agg=True, return_cls=False, verbose=verbose)
    return kws

def get_kws_inh(obj, verbose: bool = False) -> list:
    curkws = get_kws_cur(obj, verbose=verbose)
    allkws = get_kws_all(obj, verbose=verbose)
    inhkws = sorted(list(set(allkws) - set(curkws)))
    return inhkws

def getattrs_cur(obj, use_lvl_vals: bool = False, verbose: bool = False) -> dict:
    attrs = getattrs_at_lvl(obj, 0, agg=True, use_lvl_vals=use_lvl_vals, verbose=verbose)
    return attrs

def getattrs_all(obj, use_lvl_vals: bool = False, verbose: bool = False) -> dict:
    attrs = getattrs_at_lvl(obj, float('inf'), agg=True, use_lvl_vals=use_lvl_vals, verbose=verbose)
    return attrs

def getattrs_inh(obj, use_lvl_vals: bool = False, verbose: bool = False) -> dict:
    curattrs = getattrs_cur(obj, use_lvl_vals, verbose)
    allattrs = getattrs_all(obj, use_lvl_vals, verbose)
    inhattrs = {k: v for k, v in allattrs.items() if k not in curattrs}
    return inhattrs

