#!/usr/bin/env bash
# pre-commit hook: forbid committing compiled Go binaries at the repo root.
# Install: `make install-hooks` (idempotent — sets git core.hooksPath hooks/).
# Bypass:  `git commit --no-verify`.
set -euo pipefail

# Only check newly-added files at exactly the repo root (no subdirs, no modifications).
# `2>/dev/null || true` defends against rare git-diff failures (corrupted index, etc.)
# propagating through `set -e` and killing the hook before any catches run.
# Parens group OR tightly so awk errors aren't accidentally swallowed.
STAGED_ROOT_FILES=$( (git diff --cached --name-only --diff-filter=A 2>/dev/null || true) | awk -F/ 'NF==1')
[ -z "$STAGED_ROOT_FILES" ] && exit 0

# Without `go` on PATH we cannot reliably detect build artifacts — warn + exit safe.
command -v go >/dev/null 2>&1 || { echo "WARN: go not on PATH; skipping root-binary check." >&2; exit 0; }

# Use `while IFS= read -r` instead of `for f in $(...)` to be safe against
# whitespace in filenames.
while IFS= read -r f; do
    [ -d "$f" ] && continue
    [ -e "$f" ] || continue

    # Catch 1: a root binary whose name matches a Go cmd/<name>/ package.
    if [ -d "cmd/$f" ] && ls "cmd/$f"/*.go >/dev/null 2>&1; then
        echo "REJECT: '$f' looks like the build output of cmd/$f/." >&2
        echo "  'go build ./cmd/$f/' would produce this file at the repo root." >&2
        echo "  Fix: add /$f to .gitignore, rebuild from cmd/$f/." >&2
        exit 1
    fi

    # Catch 2: executable regular file at root. Broadens coverage to
    # arbitrary-ELF-at-root with unrelated names (Catch 1 only matches cmd/<n>/).
    if [ -x "$f" ] && [ -f "$f" ]; then
        echo "REJECT: '$f' is an executable file at the repo root." >&2
        echo "  Executables at the repo root are treated as build artifacts." >&2
        echo "  Fix: add /$f to .gitignore, or build into cmd/$f/ or internal/." >&2
        echo "  Opt out per-file: git update-index --chmod=-x $f" >&2
        exit 1
    fi

    # Catch 3: the staged root file is itself a buildable Go target.
    if go build -o /dev/null "./$f" 2>/dev/null; then
        echo "REJECT: '$f' is a buildable Go target at the root." >&2
        echo "  'go build ./$f' succeeded, so this is treated as a build artifact." >&2
        echo "  Fix: add /$f to .gitignore, or move source under cmd/$f/ or internal/." >&2
        exit 1
    fi
done <<< "$STAGED_ROOT_FILES"

exit 0
