#!/usr/bin/env bash
# Purpose: re-check every model file in the library against the .sha256 that fetch-model.sh
#          wrote beside it at download time, print one line per file and a summary, exit
#          non-zero if anything failed, and optionally record the audit in the lab notebook
# Platform: all (Linux, macOS and WSL2; uses sha256sum where present and shasum otherwise)
# Minimum memory: 8 GB
# Assumes: the library at $MODELS_DIR (default ~/models) was filled by fetch-model.sh, so
#          every weights file has a <file>.sha256 beside it; python3 is on PATH for the
#          notebook line
#
# Usage: bash verify-library.sh [labbook.md]
#
# Environment:
#   MODELS_DIR   where the library lives   (default: $HOME/models)
#
# Reading every file takes about as long as copying it, so a 60 GB library takes minutes,
# not seconds. Nothing is downloaded and nothing is changed.

set -euo pipefail

MODELS_DIR="${MODELS_DIR:-$HOME/models}"
LABBOOK="${1:-}"

die() { echo "verify-library: $*" >&2; exit 1; }

[ -d "$MODELS_DIR" ] || die "$MODELS_DIR does not exist; run fetch-model.sh first"

# sha256sum --check reads "<hash>  <file>" lines, which is exactly what fetch-model.sh
# writes; shasum on macOS reads the same format.
if command -v sha256sum >/dev/null; then
  check_sums() { sha256sum --check "$1"; }
elif command -v shasum >/dev/null; then
  check_sums() { shasum -a 256 --check "$1"; }
else
  die "no sha256 tool found (install coreutils for sha256sum, or use macOS shasum)"
fi

ok=0
failed=0
missing=0
bytes=0

echo "==> Verifying every *.sha256 under $MODELS_DIR"
while IFS= read -r -d '' sums; do
  dir="$(dirname "$sums")"
  file="$(basename "${sums%.sha256}")"
  if [ ! -f "$dir/$file" ]; then
    echo "MISSING  $dir/$file (checksum file present, weights file gone)"
    missing=$((missing + 1))
    continue
  fi
  if (cd "$dir" && check_sums "$file.sha256" >/dev/null 2>&1); then
    echo "OK       $dir/$file"
    ok=$((ok + 1))
    size="$(wc -c < "$dir/$file" | tr -d ' ')"
    bytes=$((bytes + size))
  else
    echo "FAILED   $dir/$file (contents do not match the recorded SHA-256)"
    failed=$((failed + 1))
  fi
done < <(find "$MODELS_DIR" -type f -name '*.sha256' -print0)

total=$((ok + failed + missing))
[ "$total" -gt 0 ] || die "no *.sha256 files under $MODELS_DIR; nothing to verify"

echo "==> $ok ok, $failed failed, $missing missing, of $total recorded file(s); $bytes bytes verified"

if [ -n "$LABBOOK" ] && command -v python3 >/dev/null; then
  python3 -c '
import json, sys
from datetime import date
print(json.dumps({
    "lab": "part-04/verify-library",
    "date": date.today().isoformat(),
    "models_dir": sys.argv[1],
    "ok": int(sys.argv[2]),
    "failed": int(sys.argv[3]),
    "missing": int(sys.argv[4]),
    "bytes_verified": int(sys.argv[5]),
}))' "$MODELS_DIR" "$ok" "$failed" "$missing" "$bytes" >> "$LABBOOK"
  echo "    recorded in $LABBOOK"
fi

[ "$failed" -eq 0 ] || exit 1
