# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/02_leaf.ipynb.

# %% auto 0
__all__ = ['LeafXath', 'LeafPath', 'LeafFile', 'LeafDir']

# %% ../nbs/02_leaf.ipynb 6
import pathlib

# %% ../nbs/02_leaf.ipynb 8
#| export


# %% ../nbs/02_leaf.ipynb 10
from atyp import StrQ

from nchr import DOT
from nlit import (BASE, LEAF, PATH, PathKind, )

from pstr.util import toprivate

# %% ../nbs/02_leaf.ipynb 12
from psrc.util import aspath
from psrc.leaf import trimleaf, joinleaf, normleaf

# %% ../nbs/02_leaf.ipynb 14
from .base import Xath, Path, File, Dir
from .mxns.kind import FileKindMixin, DirKindMixin

# %% ../nbs/02_leaf.ipynb 16
_BASE, _LEAF, _PATH = tuple(map(toprivate, (BASE, LEAF, PATH)))

# %% ../nbs/02_leaf.ipynb 17
class LeafXath(Xath):
    aspec: tuple = ( LEAF, BASE, )
    
    @property
    def leaf(self) -> pathlib.Path: return getattr(self, _LEAF, pathlib.Path(DOT))
    @leaf.setter
    def leaf(self, leaf: pathlib.Path):
        self._leaf = aspath(leaf)
        self.base = trimleaf(self.path, self.leaf) # Update base to respect new leaf
        self.path = joinleaf(self.path, self.leaf) # Recompute path = base / leaf

    @property
    def base(self) -> pathlib.Path: return getattr(self, _BASE, pathlib.Path(DOT))
    @base.setter
    def base(self, path: pathlib.Path):
        self._base = trimleaf(path, self.leaf)      # Ensure base doesn't include leaf
        self._path = joinleaf(self.base, self.leaf) # Recompute path = base / leaf

    @property
    def path(self) -> pathlib.Path: return getattr(self, _PATH, pathlib.Path(DOT))
    @path.setter
    def path(self, path: str):
        path, leaf = normleaf(path, self.leaf)
        self._base = trimleaf(path, self.leaf)
        self._path = joinleaf(self.base, self.leaf)

    def canbechild(self, other: str) -> bool: 
        return False if self.kind == str(PathKind.FILE) else True
    
    def canbeparent(self, other: str) -> bool:
        otype = other.kind if isinstance(other, type(self)) else str(PathKind.PATH)
        return False if otype == str(PathKind.FILE) else True
    
    def __truediv__(self, other):
        if self.canbeparent(other): return super().__truediv__(other)
        raise ValueError(f'{self.name} cannot be parent of {other}')

    def __rtruediv__(self, other):
        if self.canbechild(other): return super().__rtruediv__(other)
        raise ValueError(f'{self.name} cannot be child of {other}')
    
    def __init__(self, path: StrQ = None, leaf: StrQ = None, *args, **kwargs):
        base, leaf = normleaf(path, leaf or self.leaf)
        self.leaf = leaf
        self.base = trimleaf(base, leaf)
        self.path = joinleaf(self.base, self.leaf)
        
        kwargs.update(leaf=leaf, base=base)
        super().__init__(self.path, *args, **kwargs)

# %% ../nbs/02_leaf.ipynb 19
class LeafPath(LeafXath): 
    ...

# %% ../nbs/02_leaf.ipynb 21
class LeafFile(FileKindMixin, LeafPath): 
    file: str = File('')

# %% ../nbs/02_leaf.ipynb 23
class LeafDir(DirKindMixin, LeafPath):
    dir: str = Dir('')
