#!/bin/bash
# Script: /tools/lsmod-diff
# Purpose: Run a command, then show which kernel modules were newly loaded after it completes.
# This is to help onboard new Hardware Models.
#
# Usage:
#   lsmod-diff <command> [args...]
#   lsmod-diff -- <command> [args...]
#
# Examples:
#   ./lsmod-diff modprobe xhci_pci
#   ./lsmod-diff bash -c 'for d in /sys/bus/pci/devices/*; do ...; done'
#

set -euo pipefail

if [[ $# -lt 1 ]]; then
  echo "Usage: $0 <command> [args...]" >&2
  exit 2
fi

# Allow optional "--" separator
if [[ "${1:-}" == "--" ]]; then
  shift
fi

[ ! -d /tmp ] && mkdir -p /tmp

tmp_before="$(mktemp -t lsmod.before.XXXXXX)"
tmp_after="$(mktemp -t lsmod.after.XXXXXX)"
tmp_new="$(mktemp -t lsmod.new.XXXXXX)"

cleanup() {
  rm -f "$tmp_before" "$tmp_after" "$tmp_new"
}
trap cleanup EXIT

snapshot_lsmod() {
  # Store only the module names, one per line, sorted.
  # Skip header row.
  lsmod | awk 'NR>1 {print $1}' | sort -u
}

# Snapshot before
snapshot_lsmod > "$tmp_before"

# Run the user command
set +e
"$@"
cmd_rc=$?
set -e

# Snapshot after
snapshot_lsmod > "$tmp_after"

# Compute new modules: present in after, not in before
comm -13 "$tmp_before" "$tmp_after" > "$tmp_new"

echo
echo "=== Command ==="
printf '%q ' "$@"
echo
echo "Exit status: $cmd_rc"
echo

if [[ -s "$tmp_new" ]]; then
  echo "=== Newly loaded modules ==="
  cat "$tmp_new"
else
  echo "=== Newly loaded modules ==="
  echo "(none)"
fi

exit "$cmd_rc"
