#!/bin/sh
set -eu

branch=$(git symbolic-ref --quiet --short HEAD 2>/dev/null || printf '')

if [ "$branch" = "main" ]; then
	cat >&2 <<'EOF'
Push blocked: current branch is main.

Switch to a feature branch first:
  git switch <branch-name>
EOF
	exit 1
fi

zero_sha=0000000000000000000000000000000000000000
check_elisp=false

while read local_ref local_sha _remote_ref remote_sha
do
	if [ "$local_ref" = "refs/heads/main" ]; then
		cat >&2 <<'EOF'
Push blocked: refusing to push refs/heads/main.

Push a feature branch instead.
EOF
		exit 1
	fi

	if [ "$local_sha" = "$zero_sha" ]; then
		continue
	fi

	if [ "$remote_sha" = "$zero_sha" ]; then
		base=$(git merge-base "$local_sha" main 2>/dev/null || printf '')
		if [ -n "$base" ]; then
			range="$base..$local_sha"
		else
			range="$local_sha"
		fi
	else
		range="$remote_sha..$local_sha"
	fi

	if git diff --name-only --diff-filter=ACMR "$range" -- '*.el' | grep -q .
	then
		check_elisp=true
	fi
done

if [ "$check_elisp" = true ]; then
	printf '%s\n' "Running make check-elisp for pushed Elisp changes..."
	make check-elisp

	if ! git diff --quiet -- '*.el'; then
		cat >&2 <<'EOF'
Push blocked: make check-elisp changed Elisp files.

Review, stage, and commit those changes before pushing.
EOF
		exit 1
	fi
fi

exit 0
