# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/40_ldir.ipynb.

# %% auto 0
__all__ = ['LISTVARS', 'RICHVARS', 'RichConsQ', 'RichTreeQ', 'ListDir']

# %% ../nbs/40_ldir.ipynb 5
import os, pathlib, inspect
from typing import List, Self, Optional, TypeAlias

# %% ../nbs/40_ldir.ipynb 7
# from atyp import (RichCons, RichTree, PathFormatFunc)
from quac import richcons, richtree, callq
from nlit import TREE, CONS, RICH, HIDDEN, FMTFUNC
# from pfmt import fmtpath
from chck import isdict
from aspec import aspec
# from ispec import funkws

# %% ../nbs/40_ldir.ipynb 9
from .util import fullpath
from .walk import walktree
from .pfmt import fmtpath, PathFormatFunc

# %% ../nbs/40_ldir.ipynb 11
LISTVARS = (HIDDEN, FMTFUNC, )
RICHVARS = (TREE, CONS, RICH, )

RichConsQ: TypeAlias = Optional[richcons]
RichTreeQ: TypeAlias = Optional[richtree]

# %% ../nbs/40_ldir.ipynb 12
def funkws(fnc: callq = None, **kwargs) -> dict:
    '''Filter keyword arguments to function signature'''
    if not fnc: return kwargs
    params = fnc if isdict(fnc) else inspect.signature(fnc).parameters
    return {k: v for k, v in kwargs.items() if k in params}

# %% ../nbs/40_ldir.ipynb 13
class ListDir(aspec):
    hidden: bool = False
    fmtfunc: PathFormatFunc = fmtpath    
    richvars: tuple = RICHVARS
    viewvars: tuple = LISTVARS
    
    aspec: tuple = LISTVARS + RICHVARS

    def __init__(self, path: pathlib.Path, **kwargs):
        self.path = fullpath(path or os.getcwd())
        self.prepview(**kwargs)

    @classmethod
    def hasrich(cls) -> bool:
        try: import rich
        except ImportError: return False
        return True
    
    @classmethod
    def newtree(cls, path: Optional[pathlib.Path] = None, **kwargs) -> RichTreeQ:
        label = f'[link file://{path}]{path}' if path else f'{cls.__name__}'
        if cls.hasrich():
            from rich.tree import Tree
            kwargs.setdefault('guide_style', 'bold bright_blue')
            return Tree(label, **funkws(Tree, **kwargs))
        return None
    
    @classmethod
    def newcons(cls, **kwargs) -> RichConsQ:
        if cls.hasrich():
            from rich import get_console
            from rich.console import Console
            return Console(**funkws(Console, **kwargs)) or get_console()
        return None
                
    def delrichvars(self) -> Self:
        for attr in self.richvars:
            if hasattr(self, attr): delattr(self, attr)
        return self
    
    def delviewvars(self) -> Self:
        for attr in self.viewvars:
            if hasattr(self, attr): delattr(self, attr)
        return self
    
    def newviewvars(self, **kwargs) -> Self:
        for attr in self.viewvars:
            kwargs.setdefault(attr, getattr(type(self), attr))
            setattr(self, attr, kwargs[attr])
        return self
    
    def newrichvars(self, **kwargs) -> Self:
        self.tree = self.newtree(self.path, **kwargs)
        self.cons = self.newcons(**kwargs)
        self.rich = self.hasrich()
        return self
        
    def prepview(self, **kwargs) -> Self:
        return self.delrichvars().newrichvars(**kwargs).newviewvars(**kwargs)
        
    
    def viewels(self) -> List[str]:
        return list(walktree(self.path, tree=self.tree, hidden=self.hidden, fmtfunc=self.fmtfunc))
    def viewlns(self) -> List[str]: return list(map(str, self.viewels()))
    def viewstr(self) -> str: return '\n'.join(self.viewlns())
    
    def view(self, **kwargs):
        self.prepview(**kwargs)
        self.viewlns()
        if self.cons and self.tree: self.cons.print(self.tree)
        else: print(self.viewstr())

    def makecopy(self, *args, **kwargs) -> 'ListDir':
        new = type(self)(self, *args, **self.getattrs(**kwargs))
        return new
    
    def __deepcopy__(self, memo = None, *args, **kwargs):
        self.delrichvars()
        copied = super().__deepcopy__(memo, *args, **kwargs)
        copied.prepview()
        return copied
