#!/bin/sh
# Shadowgate port pre-commit check. Refuses anything that could contain
# game data. Modelled on the policy in z2rs (.githooks/pre-commit).
# Install once per clone:  git config core.hooksPath .githooks

# SHA-1 of the supported ROM: whole file, and body with the 16-byte header removed.
ROM_SHA1_FULL="1af2c83b4724efbfac7fca00fab7f7a8e100caca"
ROM_SHA1_BODY="e7869c683bd93275cde4536cd2ddf37f230dd8d0"
MAX_BYTES=524288   # 512 KiB: no source file of ours should be this big

fail=0
refuse() { echo "pre-commit: REFUSED $1 -- $2" >&2; fail=1; }

# -z keeps file names with spaces intact; only added/copied/modified/renamed files.
files=$(git diff --cached --name-only --diff-filter=ACMR)

IFS='
'
for f in $files; do
  lower=$(printf '%s' "$f" | tr 'A-Z' 'a-z')

  case "$lower" in
    *.nes|*.unf|*.unif|*.fds|*.qd|*.zip|*.7z|*.rar)
      refuse "$f" "ROMs and archives are never committed"; continue ;;
    *.sav|*.state|*.cycstate|*.dmp|*.bin|*.trace|*.mss|*.mst)
      refuse "$f" "saves, states, dumps and traces can contain game data"; continue ;;
    *.png|*.bmp|*.gif|*.jpg|*.jpeg)
      refuse "$f" "pictures of the game are its graphics; original art needs a deliberate exception"; continue ;;
    build/*|build-*/*|build_*/*|generated/*|out/*|saves/*|*/build/*|*/generated/*)
      refuse "$f" "build output contains code generated from the ROM"; continue ;;
  esac

  size=$(git cat-file -s ":$f" 2>/dev/null || echo 0)
  if [ "$size" -gt "$MAX_BYTES" ]; then
    refuse "$f" "larger than $MAX_BYTES bytes"; continue
  fi

  magic=$(git show ":$f" 2>/dev/null | head -c 4 | od -An -tx1 | tr -d ' \n')
  if [ "$magic" = "4e45531a" ]; then
    refuse "$f" "starts with an iNES ROM header"; continue
  fi

  full=$(git show ":$f" 2>/dev/null | sha1sum | cut -c1-40)
  body=$(git show ":$f" 2>/dev/null | tail -c +17 | sha1sum | cut -c1-40)
  if [ "$full" = "$ROM_SHA1_FULL" ] || [ "$body" = "$ROM_SHA1_BODY" ] || [ "$full" = "$ROM_SHA1_BODY" ]; then
    refuse "$f" "its contents match the Shadowgate ROM"; continue
  fi
done

if [ "$fail" -ne 0 ]; then
  echo "pre-commit: nothing was committed. Unstage the files above (git restore --staged <file>). See LEGAL.md." >&2
  exit 1
fi
exit 0
