#!/usr/bin/env bash
# .githooks/pre-commit — blocks sensitive files and credential patterns from being committed
set -euo pipefail

RED='\033[0;31m'; YELLOW='\033[1;33m'; BOLD='\033[1m'; NC='\033[0m'

BLOCKED=0
STAGED=$(git diff --cached --name-only --diff-filter=ACM 2>/dev/null)

if [[ -z "$STAGED" ]]; then
    exit 0
fi

# ── Blocked filenames ──────────────────────────────────────────────────────────
BLOCKED_FILES=(
    ".env"
    ".env.local"
    ".env.production"
    ".env.staging"
    "*.pem"
    "*.key"
    "*.p12"
    "*.pfx"
    "id_rsa"
    "id_ecdsa"
    "id_ed25519"
    "id_dsa"
    "*.ppk"
    "secrets.yml"
    "secrets.yaml"
    "credentials.json"
    "service-account*.json"
    "*.keystore"
    "htpasswd"
    ".htpasswd"
)

while IFS= read -r file; do
    filename="$(basename "$file")"
    for pattern in "${BLOCKED_FILES[@]}"; do
        # shellcheck disable=SC2254
        case "$filename" in
            $pattern)
                echo -e "${RED}BLOCKED:${NC} ${BOLD}$file${NC} matches blocked filename pattern '${YELLOW}$pattern${NC}'"
                BLOCKED=1
                ;;
        esac
    done
done <<< "$STAGED"

# ── Blocked content patterns ───────────────────────────────────────────────────
declare -A CONTENT_PATTERNS=(
    ["RSA/EC private key header"]="-----BEGIN (RSA|EC|DSA|OPENSSH) PRIVATE KEY"
    ["AWS access key"]="AKIA[0-9A-Z]{16}"
    ["GitHub token"]="ghp_[A-Za-z0-9]{36}"
    ["Generic API key assignment"]="(api_key|API_KEY|secret_key|SECRET_KEY)\s*=\s*['\"][A-Za-z0-9_\-]{16,}"
    ["Stripe secret key"]="sk_(live|test)_[A-Za-z0-9]{24,}"
    ["Forgejo/Gitea token (40 hex chars)"]="[a-f0-9]{40}"
)

while IFS= read -r file; do
    # Skip binary files
    if git diff --cached -- "$file" | grep -qP "^\+.*\x00"; then
        continue
    fi
    for label in "${!CONTENT_PATTERNS[@]}"; do
        pattern="${CONTENT_PATTERNS[$label]}"
        matches=$(git diff --cached -- "$file" | grep "^+" | grep -cP "$pattern" 2>/dev/null || true)
        if [[ "$matches" -gt 0 ]]; then
            echo -e "${RED}BLOCKED:${NC} ${BOLD}$file${NC} contains pattern matching '${YELLOW}$label${NC}'"
            BLOCKED=1
        fi
    done
done <<< "$STAGED"

# ── Result ─────────────────────────────────────────────────────────────────────
if [[ "$BLOCKED" -eq 1 ]]; then
    echo ""
    echo -e "${RED}Commit rejected.${NC} Remove sensitive files/content before committing."
    echo -e "To bypass in an emergency: ${YELLOW}git commit --no-verify${NC} (use with extreme caution)"
    exit 1
fi

exit 0
