from collections.abc import Iterable
from typing import Any, MutableMapping, Optional, Tuple, Union

from typing_extensions import TypeAlias

from dirlay.nested_dict import NestedDict
from dirlay.optional import rich
from dirlay.types import DictTree, DictNode, Path as Path, PathType

if rich is not None:
    from rich.tree import Tree as RichTree
else:
    RichTree = None  # type: ignore[misc]  # assign to type

class Node(object):
    key: str
    path: Path
    is_dir: bool
    data: 'DictNode'
    _base: DictTree
    def __init__(self, key: str, path: PathType, base: DictTree) -> None: ...
    def __eq__(self, other: Any) -> bool: ...
    def __repr__(self) -> str: ...

MutableDictTree: TypeAlias = MutableMapping[str, 'MutableDictNode']
MutableDictNode: TypeAlias = Union[MutableDictTree, str]

class Dir:
    _tree: NestedDict[MutableDictTree]
    _basedir: Optional[Path]
    _basedir_remove: bool
    _original_cwd: Optional[Path]
    def __init__(self, entries: Optional[DictTree] = ...) -> None: ...
    @property
    def data(self) -> DictTree: ...
    def __contains__(self, path: PathType) -> bool: ...
    def __eq__(self, other: Any) -> bool: ...
    def __getitem__(self, path: PathType) -> Node: ...
    def __iter__(self) -> Iterable[str]: ...
    def items(self) -> Iterable[Tuple[str, Node]]: ...
    def keys(self) -> Tuple[str]: ...
    def values(self) -> Tuple[Node]: ...
    def root(self) -> Node: ...
    def leaves(self) -> Tuple[Node]: ...
    def __or__(self, entries: Union[Dir, DictTree]) -> 'Dir': ...
    def __ior__(self, entries: Union[Dir, DictTree]) -> 'Dir': ...
    def __enter__(self) -> 'Dir': ...
    def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> 'Dir': ...
    def copy(self) -> 'Dir': ...
    def update(self, entries: Union[Dir, DictTree], exist_ok: bool = ...) -> None: ...
    def _assert_tree_created(self) -> None: ...
    @property
    def basedir(self) -> Optional[Path]: ...
    def chdir(self, path: Optional[PathType] = ...) -> None: ...
    def mktree(
        self,
        basedir: Optional[PathType] = ...,
        chdir: Union[PathType | bool | None] = ...,
    ) -> 'Dir': ...
    def rmtree(self) -> None: ...
    def as_rich(
        self,
        real_basedir: bool = ...,
        show_data: bool = ...,
        **kwargs: Any,
    ) -> RichTree: ...
    def print_rich(
        self,
        real_basedir: bool = ...,
        show_data: bool = ...,
        **kwargs: Any,
    ) -> None: ...

def getcwd() -> Path: ...
