#!/usr/bin/env bash
# Fail if any versioned migration Vxxx already present on the base branch is modified
# in the current HEAD (Flyway checksum mismatch risk). See CLAUDE.md (never rewrite applied V__).
#
# Usage: ci_check_migration_immutability.sh [BASE]
#   BASE — ref or full SHA (default: origin/main). For PRs pass base commit SHA.
set -euo pipefail

ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
if [[ -z "$ROOT" ]]; then
  echo "ERROR: not inside a git repository"
  exit 1
fi
cd "$ROOT"

BASE="${1:-origin/main}"

if [[ "$BASE" =~ ^[0-9a-f]{7,40}$ ]]; then
  if ! git cat-file -e "${BASE}^{commit}" 2>/dev/null; then
    git fetch --no-tags --depth=256 origin "$BASE"
  fi
fi

if ! git rev-parse --verify -q "${BASE}^{commit}" >/dev/null; then
  echo "ERROR: cannot resolve base revision: $BASE (fetch origin main?)"
  exit 1
fi

max_ver_on_base() {
  git ls-tree -r --name-only "$BASE" -- db/migration 2>/dev/null \
    | grep -E '^db/migration/V[0-9]+__' \
    | sed -n 's/^db\/migration\/V\([0-9][0-9]*\)__.*/\1/p' \
    | sort -n \
    | tail -1
}

MAX="$(max_ver_on_base || true)"
MAX="${MAX:-0}"

mapfile -t CHANGED < <(git diff --name-only "${BASE}...HEAD" -- 'db/migration/V*.sql' 2>/dev/null || true)

if [[ ${#CHANGED[@]} -eq 0 ]]; then
  echo "ci_check_migration_immutability: no versioned migration changes vs $BASE (ok)"
  exit 0
fi

err=0
for f in "${CHANGED[@]}"; do
  [[ "$f" =~ ^db/migration/V([0-9]+)__ ]] || continue
  ver="${BASH_REMATCH[1]}"
  ver=$((10#$ver))
  if (( ver <= MAX )); then
    printf 'ERROR: do not modify historical migration %s (version %03d <= max on base %03d from %s). Add a new V* migration instead. See CLAUDE.md.\n' \
      "$f" "$ver" "$MAX" "$BASE" >&2
    err=1
  fi
done

if (( err )); then
  exit 1
fi

echo "ci_check_migration_immutability: ok (vs $BASE, max V on base=$MAX)"
