#!/bin/sh
# Framework pre-commit hook (shared by R, Python, and fw)
# Managed by Framework. Configure it with git_hooks_*() in R or Python.
#
# The checks themselves live in the language packages, which read
# git.hooks in settings.yml to decide what to run. This script only finds a
# runtime. A project with no usable runtime fails the commit, because the
# hook guards against committing restricted data. Bypass with
# `git commit --no-verify` only when you know the commit is safe.

set -u

cd "$(git rev-parse --show-toplevel)" || exit 1

# Each runner returns 127 when its runtime or the framework package is
# missing, so the next runtime gets a turn and the message below can say why

run_r() {
  command -v Rscript >/dev/null 2>&1 || return 127
  # framework 1.x from CRAN has no shared hook entry point
  probe='ok <- requireNamespace("framework", quietly = TRUE) && exists(".hook_run", envir = asNamespace("framework"))'
  Rscript -e "$probe; quit(status = if (ok) 0 else 127)" >/dev/null 2>&1 || return 127
  Rscript -e 'quit(status = framework:::.hook_run("pre-commit"))'
}

run_python() {
  if [ -x .venv/bin/python ]; then
    set -- .venv/bin/python
  elif [ -x .venv/Scripts/python.exe ]; then
    set -- .venv/Scripts/python.exe
  elif [ -f uv.lock ] && command -v uv >/dev/null 2>&1; then
    set -- uv run --frozen python
  elif command -v python3 >/dev/null 2>&1; then
    set -- python3
  else
    return 127
  fi
  "$@" -c 'import framework' >/dev/null 2>&1 || return 127
  "$@" -m framework hook pre-commit
}

has_rproj() {
  for f in ./*.Rproj; do
    [ -e "$f" ] && return 0
  done
  return 1
}

# fw's detection plus *.Rproj, which every R-built project has even without
# renv. R markers are checked first; a project with both runs the first
# runtime that is installed.
status=127
if [ -f renv.lock ] || [ -f .Rprofile ] || has_rproj; then
  run_r
  status=$?
fi
if [ "$status" -eq 127 ] && { [ -f pyproject.toml ] || [ -f uv.lock ] || [ -d .venv ]; }; then
  run_python
  status=$?
fi

if [ "$status" -eq 127 ]; then
  echo "Framework hook: found neither R with framework 2.0 or later nor Python with framework-py." >&2
  echo "Install one of them, or run 'git commit --no-verify' if you are sure this commit is safe." >&2
  exit 1
fi
exit "$status"
