#!/usr/bin/env bash
# Run on the Proxmox host (as root) when rpiboot fails with "No 'bootcode' files found" / "rpiboot gadget empty".
# Cause: mass-storage-gadget64 has no real boot files (broken symlinks or Git LFS not pulled).
# This script removes broken symlinks and extracts bootcode4.bin from the installed rpiboot binary.
#
# Does NOT fix: "libusb_bulk_transfer returned -7" / "Failed to write correct length" — that is a USB
# transfer/timing issue (try USB 2.0 port, or rpiboot -m 2000). See PROXMOX-LXC-DEPLOYMENT.md.
#
# On host: bash fix-gadget-bootcode-on-host.sh
# From your machine: ssh root@HOST 'bash -s' < emmc-provisioning/scripts/fix-gadget-bootcode-on-host.sh

set -e
GADGET="${1:-/opt/usbboot/mass-storage-gadget64}"
RPIBOOT="${2:-/opt/usbboot/rpiboot}"

[[ -d "$GADGET" ]] || { echo "Error: $GADGET not found"; exit 1; }
[[ -x "$RPIBOOT" ]] || { echo "Error: $RPIBOOT not found (install usbboot first: install-usbboot-on-host.sh)"; exit 1; }

# Ensure readelf and objdump are available (binutils)
for cmd in readelf objdump; do
  if ! command -v "$cmd" &>/dev/null; then
    echo "Installing binutils (required for $cmd)..."
    apt-get update -qq && apt-get install -y -qq binutils 2>/dev/null || {
      echo "Error: $cmd not found. Install binutils: apt-get install -y binutils"
      exit 1
    }
    break
  fi
done

# Remove broken symlinks in gadget dir so we can replace with real boot file
for f in bootfiles.bin bootcode.bin bootcode4.bin bootcode5.bin; do
  if [[ -L "$GADGET/$f" ]] && ! [[ -f "$GADGET/$f" ]]; then
    rm -f "$GADGET/$f"
    echo "Removed broken symlink $GADGET/$f"
  fi
done

# If we already have a valid boot file, done
if [[ -f "$GADGET/bootcode4.bin" ]] || [[ -f "$GADGET/bootfiles.bin" ]]; then
  echo "Already has bootcode4.bin or valid bootfiles.bin. OK."
  exit 0
fi

# Get .data section file offset and address from ELF
readelf -S "$RPIBOOT" | grep -q "\.data" || { echo "No .data section"; exit 1; }
DATA_OFF=$(readelf -S "$RPIBOOT" | awk '/\.data\s/ { print "0x"$5; exit }')
DATA_ADDR=$(readelf -S "$RPIBOOT" | awk '/\.data\s/ { print "0x"$4; exit }')
LEN_SYM=$(objdump -t "$RPIBOOT" | awk '/msd_bootcode4_bin_len/ { print $1; exit }')
BIN_SYM=$(objdump -t "$RPIBOOT" | awk '/msd_bootcode4_bin\s/ { print $1; exit }')
[[ -n "$LEN_SYM" && -n "$BIN_SYM" ]] || { echo "msd_bootcode4_bin symbols not found in rpiboot"; exit 1; }

LEN_ADDR=$((0x$LEN_SYM))
BIN_ADDR=$((0x$BIN_SYM))
LEN_OFF=$((DATA_OFF + LEN_ADDR - DATA_ADDR))
BIN_OFF=$((DATA_OFF + BIN_ADDR - DATA_ADDR))
LEN=$(dd if="$RPIBOOT" bs=1 skip=$LEN_OFF count=4 2>/dev/null | od -An -t u4 | tr -d ' ')
dd if="$RPIBOOT" of="$GADGET/bootcode4.bin" bs=1 skip=$BIN_OFF count=$LEN 2>/dev/null
echo "Wrote $GADGET/bootcode4.bin ($LEN bytes). Verify: $RPIBOOT -d $GADGET -V"