#!/bin/bash
# Pre-commit hook: block binary and image files from being committed.
# Allowed exceptions are listed in .binary-allowlist (one glob pattern per line).
set -euo pipefail

ALLOWLIST_FILE=".binary-allowlist"

# Binary/image extensions to block
BLOCKED_EXTENSIONS=(
    # Images
    png jpg jpeg gif webp svg ico bmp tiff tif psd
    # Audio/Video
    mp3 mp4 wav avi mkv flac ogg wma aac m4a mov wmv flv
    # Archives
    zip tar gz tgz bz2 xz 7z rar
    # Documents
    pdf doc docx xls xlsx ppt pptx
    # Fonts
    ttf woff woff2 eot otf
    # Compiled / binary
    o so a exe dll dylib pyc pyo class
    # Data
    apkg bin flat db sqlite sqlite3
)

# Build regex pattern from extensions
pattern=""
for ext in "${BLOCKED_EXTENSIONS[@]}"; do
    if [ -z "$pattern" ]; then
        pattern="\\.(${ext}"
    else
        pattern="${pattern}|${ext}"
    fi
done
pattern="${pattern})$"

# Load allowlist
allowed_patterns=()
if [ -f "$ALLOWLIST_FILE" ]; then
    while IFS= read -r line; do
        # Skip comments and empty lines
        [[ "$line" =~ ^[[:space:]]*# ]] && continue
        [[ -z "${line// /}" ]] && continue
        allowed_patterns+=("$line")
    done < "$ALLOWLIST_FILE"
fi

is_allowed() {
    local file="$1"
    for pat in "${allowed_patterns[@]+"${allowed_patterns[@]}"}"; do
        # Use bash pattern matching (glob)
        # shellcheck disable=SC2254
        case "$file" in
            $pat) return 0 ;;
        esac
    done
    return 1
}

found=0
for file in "$@"; do
    # Skip files not tracked by git (deleted from index or untracked)
    git ls-files --error-unmatch "$file" >/dev/null 2>&1 || continue
    # Check if the file matches a blocked extension
    if echo "$file" | grep -qiE "$pattern"; then
        if is_allowed "$file"; then
            continue
        fi
        echo "BLOCKED: $file"
        echo "  Binary/image files should not be committed to the repo."
        echo "  Move to ../testsAndMisc_binaries/ instead."
        echo "  To allow this file, add a glob pattern to $ALLOWLIST_FILE"
        found=1
    fi
done

if [ "$found" -eq 1 ]; then
    echo ""
    echo "ERROR: Attempted to commit binary/image files."
    echo "Options:"
    echo "  1. Move files to ../testsAndMisc_binaries/ (preferred)"
    echo "  2. Add pattern to $ALLOWLIST_FILE (for essential files only)"
    exit 1
fi
