#!/usr/bin/env python3
"""Write a newc-format cpio archive of a directory tree to stdout.

Used by scripts/build-linux-bootstrap.sh to pack the Nucleic Linux bootstrap initramfs without a
`cpio` binary (which macOS lacks by default). Emits the SVR4/newc format the Linux kernel's initramfs
loader expects; handles regular files, directories, and symlinks. Byte-identical on Linux and macOS.
"""
import os
import stat
import sys


def field(n: int) -> bytes:
    return b"%08X" % (n & 0xFFFFFFFF)


def emit(out, name: bytes, st, data: bytes):
    # newc header: magic + 13 eight-hex fields, then name (NUL-terminated, 4-byte padded), then data
    # (4-byte padded).
    hdr = b"070701"
    hdr += field(st.st_ino if st else 0)
    hdr += field(st.st_mode if st else 0)
    hdr += field(0)  # uid — normalize to root so the initramfs is reproducible
    hdr += field(0)  # gid
    hdr += field(st.st_nlink if st else 1)
    hdr += field(0)  # mtime — normalize for reproducibility
    hdr += field(len(data))
    hdr += field(0) * 4  # devmajor/minor, rdevmajor/minor
    namebytes = name + b"\x00"
    hdr += field(len(namebytes))
    hdr += field(0)  # check (unused for newc)
    out.write(hdr)
    out.write(namebytes)
    pad = (-(len(hdr) + len(namebytes))) % 4
    out.write(b"\x00" * pad)
    out.write(data)
    out.write(b"\x00" * ((-len(data)) % 4))


def main():
    rootdir = sys.argv[1]
    out = sys.stdout.buffer
    entries = []
    for dirpath, dirnames, filenames in os.walk(rootdir):
        for d in sorted(dirnames):
            entries.append(os.path.join(dirpath, d))
        for f in sorted(filenames):
            entries.append(os.path.join(dirpath, f))
    for path in entries:
        rel = os.path.relpath(path, rootdir).encode()
        st = os.lstat(path)
        if stat.S_ISLNK(st.st_mode):
            data = os.readlink(path).encode()
        elif stat.S_ISDIR(st.st_mode):
            data = b""
        else:
            with open(path, "rb") as fh:
                data = fh.read()
        emit(out, rel, st, data)
    # Trailer.
    class Z:
        st_ino = 0
        st_mode = 0
        st_nlink = 1
    emit(out, b"TRAILER!!!", Z(), b"")


if __name__ == "__main__":
    main()
