#!/usr/bin/env python3
"""tree [DIR] [-L DEPTH] [-a]  -  compact directory listing without build/VCS noise."""

import argparse
import os
import sys

NOISE = {
    ".git", "node_modules", "__pycache__", ".venv", "venv", "dist", "build",
    ".mypy_cache", ".pytest_cache", ".ruff_cache", ".next", "target", ".cache",
}


def walk(root: str, depth: int, limit: int, show_hidden: bool, out: list[str], prefix: str = ""):
    try:
        entries = sorted(os.scandir(root), key=lambda e: (not e.is_dir(follow_symlinks=False), e.name))
    except PermissionError:
        return
    entries = [
        e for e in entries
        if e.name not in NOISE and (show_hidden or not e.name.startswith("."))
    ]
    for index, entry in enumerate(entries):
        last = index == len(entries) - 1
        branch = "`-- " if last else "|-- "
        if entry.is_dir(follow_symlinks=False):
            out.append(f"{prefix}{branch}{entry.name}/")
            if depth < limit:
                walk(entry.path, depth + 1, limit, show_hidden, out, prefix + ("    " if last else "|   "))
        elif entry.is_symlink():
            out.append(f"{prefix}{branch}{entry.name} -> {os.readlink(entry.path)}")
        else:
            out.append(f"{prefix}{branch}{entry.name}")


def main() -> int:
    parser = argparse.ArgumentParser(description=__doc__)
    parser.add_argument("dir", nargs="?", default=".")
    parser.add_argument("-L", "--depth", type=int, default=3)
    parser.add_argument("-a", "--all", action="store_true", help="include dotfiles")
    args = parser.parse_args()
    if not os.path.isdir(args.dir):
        print(f"tree: not a directory: {args.dir}", file=sys.stderr)
        return 1
    lines = [args.dir.rstrip("/") + "/"]
    walk(args.dir, 1, args.depth, args.all, lines)
    print("\n".join(lines[:2000]))
    if len(lines) > 2000:
        print(f"... {len(lines) - 2000} more entries (use -L for a shallower view)")
    return 0


if __name__ == "__main__":
    sys.exit(main())
