"""Read-only sibling filename collision preflight. Python 3.9+."""
import argparse
import json
import os
from pathlib import Path
import sys
import unicodedata


def name_key(name):
    return unicodedata.normalize(
        "NFC", unicodedata.normalize("NFC", name).casefold()
    )


def audit(root):
    if not root.is_dir():
        raise ValueError("root must be an existing directory")
    groups = []
    pending = [root]
    while pending:
        directory = pending.pop()
        by_key = {}
        with os.scandir(directory) as entries:
            for entry in entries:
                by_key.setdefault(name_key(entry.name), []).append(entry.name)
                if entry.is_dir(follow_symlinks=False):
                    pending.append(Path(entry.path))
        for names in by_key.values():
            if len(names) > 1:
                groups.append({
                    "directory": directory.relative_to(root).as_posix(),
                    "names": sorted(names),
                })
    groups.sort(key=lambda item: (item["directory"], item["names"]))
    return {"collision_groups": len(groups), "groups": groups}


def main():
    cli = argparse.ArgumentParser(description=__doc__, allow_abbrev=False)
    cli.add_argument("root", type=Path, help="quiet local directory to scan")
    args = cli.parse_args()
    try:
        report = audit(args.root)
    except (OSError, ValueError) as exc:
        print(f"ERROR: {exc}", file=sys.stderr)
        return 2
    print(json.dumps(report, ensure_ascii=True, sort_keys=True))
    return 1 if report["collision_groups"] else 0


if __name__ == "__main__":
    raise SystemExit(main())
