"""List the largest regular files without reading their contents. Python 3.9+."""
import argparse
import heapq
import json
import os
from pathlib import Path
import stat
import sys


def main(argv=None):
    parser = argparse.ArgumentParser(description=__doc__, allow_abbrev=False)
    parser.add_argument("directory", type=Path)
    parser.add_argument("--top", type=int, default=10, help="results to keep, 1-1000")
    parser.add_argument("--min-mib", type=int, default=0, help="minimum size in whole MiB")
    args = parser.parse_args(argv)
    if not 1 <= args.top <= 1000 or args.min_mib < 0:
        parser.error("top must be 1-1000 and min-mib must be nonnegative")
    try:
        root = args.directory.resolve(strict=True)
        if not stat.S_ISDIR(root.stat().st_mode):
            parser.error("directory must refer to a directory")
    except (OSError, RuntimeError) as exc:
        parser.error(str(exc))

    errors = scanned = matched = 0
    largest = []
    minimum = args.min_mib * 1024 * 1024

    def report_error(exc):
        nonlocal errors
        errors += 1
        print(f"ERROR: {ascii(str(exc))}", file=sys.stderr)

    for folder, _dirs, names in os.walk(root, onerror=report_error, followlinks=False):
        for name in names:
            path = Path(folder) / name
            try:
                info = path.lstat()
            except OSError as exc:
                report_error(exc)
                continue
            if not stat.S_ISREG(info.st_mode):
                continue
            scanned += 1
            if info.st_size < minimum:
                continue
            matched += 1
            item = (info.st_size, str(path.relative_to(root)))
            if len(largest) < args.top:
                heapq.heappush(largest, item)
            elif item > largest[0]:
                heapq.heapreplace(largest, item)

    print("MiB\tbytes\tpath_json")
    for size, relative in sorted(largest, reverse=True):
        print(f"{size / (1024 * 1024):.2f}\t{size}\t{json.dumps(relative)}")
    print(
        f"scanned={scanned} matched={matched} shown={len(largest)} errors={errors}",
        file=sys.stderr,
    )
    return 1 if errors else 0


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