import hashlib
import json
import os
from pathlib import Path
import stat
import sys

root = Path(sys.argv[1])
if root.is_symlink() or not root.is_dir():
    raise ValueError("expected a real directory")
manifest = {}

def fail(error):
    raise error

for directory, directories, files in os.walk(root, followlinks=False, onerror=fail):
    for name in directories + files:
        path = Path(directory) / name
        info = path.lstat()
        if stat.S_ISDIR(info.st_mode):
            continue
        if not stat.S_ISREG(info.st_mode):
            raise ValueError("symlink or special file in recovery scope")
        digest = hashlib.sha256()
        with path.open("rb") as stream:
            for block in iter(lambda: stream.read(1024 * 1024), b""):
                digest.update(block)
        manifest[path.relative_to(root).as_posix()] = [info.st_size, digest.hexdigest()]
if not manifest:
    raise ValueError("empty recovery scope")
json.dump(manifest, sys.stdout, sort_keys=True, ensure_ascii=True, separators=(",", ":"))
sys.stdout.write("\n")
