#!/usr/bin/env bash
#
# build-nvidia.sh — build alloy-nvidia, Alloy plus the open NVIDIA module.
#
# A thin derived image over an Alloy that already exists. It does not build
# Alloy: the whole point of the derived shape (alloy `2a382a75`, option c) is
# that the module is compiled against the kernel of one specific Alloy image,
# so the input is a digest and this script's job is to resolve one and hold it.
#
# aarch64 only, and that is not a limitation to lift. The card this exists for
# is in astra; CLAUDE.md forbids cross-compiling, and an x86_64 machine with an
# NVIDIA card would want the proprietary module rather than the open one
# Blackwell requires.
#
# Rootful, for build-image.sh's reason: it shares one container store with the
# Alloy build, so the digest below resolves without a rootless->rootful copy.
#
# Usage:
#   build/build-nvidia.sh                  # derive from localhost/alloy:local
#   build/build-nvidia.sh --digest sha256:...   # derive from a named digest
#   build/build-nvidia.sh --tag alloy-nvidia:aarch64

set -euo pipefail

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

# priv / privc. See build/privilege.sh.
# shellcheck source=build/privilege.sh
. "$REPO_ROOT/build/privilege.sh"

BASE="localhost/alloy:local"
DIGEST=""
TAG="localhost/alloy-nvidia:aarch64"

while [ $# -gt 0 ]; do
  case "$1" in
    --digest) DIGEST="${2:?--digest needs a sha256:... value}"; shift 2 ;;
    --base)   BASE="${2:?--base needs an image}"; shift 2 ;;
    --tag)    TAG="${2:?--tag needs a name}"; shift 2 ;;
    -h|--help) sed -n '2,25p' "$0"; exit 0 ;;
    *) echo "error: unknown argument $1" >&2; exit 2 ;;
  esac
done

arch="$(uname -m)"
if [ "$arch" != "aarch64" ]; then
  echo "error: alloy-nvidia is aarch64 only; this is $arch." >&2
  echo "       The card it exists for is astra's. Builds are native per" >&2
  echo "       architecture (CLAUDE.md), so build it there." >&2
  exit 1
fi

# The digest is the input, so it is resolved and printed rather than assumed.
# Deriving from a tag would mean two runs a week apart produced modules for
# different kernels while claiming the same provenance, which is the drift the
# base pins in the Containerfile exist to stop.
if [ -z "$DIGEST" ]; then
  DIGEST="$(priv podman image inspect "$BASE" --format '{{.Digest}}' 2>/dev/null || true)"
  [ -n "$DIGEST" ] || {
    echo "error: no image $BASE to derive from." >&2
    echo "       Build Alloy first: build/build-image.sh --skip-bib" >&2
    exit 1
  }
fi

kernel="$(priv podman run --rm "$BASE" ls /usr/lib/modules | head -1)"
echo "deriving from $BASE"
echo "  digest: $DIGEST"
echo "  kernel: $kernel"
echo

priv podman build \
  --build-arg "ALLOY_DIGEST=$DIGEST" \
  -f "$REPO_ROOT/build/Containerfile.nvidia" \
  -t "$TAG" \
  "$REPO_ROOT"

echo
echo "built $TAG"
# Read back out of the finished image rather than trusting the build log: the
# Containerfile asserts this too, and a second reading from the outside is what
# a person checking the machine would do.
priv podman run --rm "$TAG" sh -c '
  kernel="$(ls /usr/lib/modules | head -1)"
  module="/usr/lib/modules/$kernel/extra/nvidia/nvidia.ko.xz"
  [ -f "$module" ] || module="/usr/lib/modules/$kernel/extra/nvidia/nvidia.ko"
  echo "  kernel:   $kernel"
  echo "  vermagic: $(modinfo -F vermagic "$module")"
  echo "  licence:  $(modinfo -F license "$module")"
  echo "  version:  $(modinfo -F version "$module")"
'
