#!/usr/bin/env python3
"""manifest.py DIR -> stdout: one sorted line per entry under DIR.

Line: <type> <relpath> <mode> <size> <sha256 of data> <sha256 of sorted xattrs>
Used to prove the surviving snapshot S2 is byte-identical before/after a test.
"""
import hashlib
import os
import stat
import sys


def xattr_hash(p):
    h = hashlib.sha256()
    for name in sorted(os.listxattr(p, follow_symlinks=False)):
        h.update(name.encode() + b"\0")
        h.update(os.getxattr(p, name, follow_symlinks=False) + b"\0")
    return h.hexdigest()


def data_hash(p):
    h = hashlib.sha256()
    with open(p, "rb") as f:
        for chunk in iter(lambda: f.read(1 << 20), b""):
            h.update(chunk)
    return h.hexdigest()


def main():
    top = sys.argv[1]
    out = []
    for dirpath, dirnames, filenames in os.walk(top):
        for name in dirnames + filenames:
            p = os.path.join(dirpath, name)
            rel = os.path.relpath(p, top)
            st = os.lstat(p)
            if stat.S_ISREG(st.st_mode):
                t, dh = "f", data_hash(p)
            elif stat.S_ISDIR(st.st_mode):
                t, dh = "d", "-"
            else:
                t, dh = "o", "-"
            out.append(f"{t} {rel} {st.st_mode:o} {st.st_size} {dh} {xattr_hash(p)}")
    out.sort()
    sys.stdout.write("\n".join(out) + "\n")


if __name__ == "__main__":
    main()
