#!/bin/bash
#
# build_initramfs.sh — Pack the hiperiso host initramfs
# ---------------------------------------------------------------------------
# Takes the staging directory (build/staging) and assembles a cpio.gz from:
#   - host/initramfs/*  (init scripts — written by the initramfs task)
#   - busybox            (static binary, built/downloaded separately)
#   - qemu-system-x86_64 (from the QEMU build, already in staging)
#   - hiperiso-log       (from logging/hiperiso-log, already in staging)
#   - OVMF.fd            (from the EDK2 build, already in staging)
#
# Usage:  build_initramfs.sh <staging_dir>
#
set -euo pipefail

STAGING="${1:?usage: build_initramfs.sh <staging_dir>}"
STAGING="$(cd "$STAGING" && pwd)"
[ -d "$STAGING" ] || { echo "ERROR: staging dir '$STAGING' not found" >&2; exit 1; }

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ROOT="$STAGING/initramfs"

echo "=== Building initramfs in $ROOT ==="

# ── Directory tree ──────────────────────────────────────────────────────────
mkdir -p "$ROOT"/{bin,sbin,etc,proc,sys,dev,tmp,run,mnt/usb,mnt/efi,usr/bin,usr/sbin,EFI/hiperiso/trace}

# ── Init scripts (from host/initramfs/) — copied to root of initramfs ───────
if [ -d "$REPO_ROOT/host/initramfs" ]; then
    cp -a "$REPO_ROOT/host/initramfs/." "$ROOT/"
    chmod +x "$ROOT"/init "$ROOT"/*.sh 2>/dev/null || true
    echo "  [ok] copied init scripts"
else
    echo "  [warn] host/initramfs/ missing — init scripts not packed yet"
fi

# ── busybox (static binary) ─────────────────────────────────────────────────
BUSYBOX="${BUSYBOX:-$STAGING/busybox}"
if [ -x "$BUSYBOX" ]; then
    install -m0755 "$BUSYBOX" "$ROOT/bin/busybox"
    # Create common applet symlinks
    for app in sh ash mount umount ls cat echo printf mkdir mkfifo poweroff reboot halt sync sleep ln cp mv rm switch_root date grep cut sed awk head tail tr wc basename dirname find mktemp dd mknod losetup blkid lsblk dmesg ps kill chmod chown env uname stat tar test true false which readlink free pidof renice insmod modprobe lsmod ifconfig ip route uptime fdisk zcat gunzip gzip xz unxz du df id; do
        ln -sf busybox "$ROOT/bin/$app"
    done
    echo "  [ok] busybox installed"
else
    echo "  [warn] busybox not found at $BUSYBOX (set BUSYBOX=path)"
fi

# ── qemu-system-x86_64 (stripped, from QEMU build) ──────────────────────────
if [ -x "$STAGING/qemu-system-x86_64" ]; then
    install -m0755 "$STAGING/qemu-system-x86_64" "$ROOT/usr/bin/qemu-system-x86_64"
    echo "  [ok] qemu-system-x86_64 installed"
else
    echo "  [warn] qemu-system-x86_64 missing in staging"
fi

# ── hiperiso-log (log analysis tool) ────────────────────────────────────────
if [ -x "$STAGING/hiperiso-log" ]; then
    install -m0755 "$STAGING/hiperiso-log" "$ROOT/usr/bin/hiperiso-log"
    echo "  [ok] hiperiso-log installed"
else
    echo "  [warn] hiperiso-log missing in staging"
fi

# ── OVMF firmware (for QEMU -bios) ──────────────────────────────────────────
if [ -f "$STAGING/OVMF.fd" ]; then
    install -m0644 "$STAGING/OVMF.fd" "$ROOT/EFI/hiperiso/OVMF.fd"
    echo "  [ok] OVMF.fd installed"
else
    echo "  [warn] OVMF.fd missing in staging"
fi

# ── Trace event files ───────────────────────────────────────────────────────
if ls "$REPO_ROOT"/logging/trace-*.events >/dev/null 2>&1; then
    cp "$REPO_ROOT"/logging/trace-*.events "$ROOT/EFI/hiperiso/trace/"
    echo "  [ok] trace event files installed"
fi

# ── /dev nodes ─────────────────────────────────────────────────────────────
# devtmpfs will populate /dev at runtime; just ensure the mountpoint exists.
# (Creating device nodes here would require root; devtmpfs handles it.)

# ── Pack into cpio.gz ───────────────────────────────────────────────────────
echo "=== Packing initramfs.cpio.gz ==="
(
    cd "$ROOT"
    find . -print0 | cpio --null -H newc -o --owner=root:root 2>/dev/null \
        | gzip -9 > "$STAGING/initramfs.cpio.gz"
)
echo "=== initramfs.cpio.gz ready ($(du -h "$STAGING/initramfs.cpio.gz" | cut -f1)) ==="
