#!/bin/bash
# Atomic Commit Guidance Hook
#
# This hook provides guidance on atomic commits. It warns but does NOT block.
# To disable: git commit --no-verify
#
# Checks:
# 1. "AND" test - commit message should not contain "and" linking changes
# 2. Commit size - warns if many files or lines changed

COMMIT_MSG_FILE=$1
COMMIT_MSG=$(cat "$COMMIT_MSG_FILE")

# Skip merge commits
if grep -qE "^Merge " "$COMMIT_MSG_FILE"; then
    exit 0
fi

# Skip fixup/squash commits
if grep -qE "^(fixup|squash)!" "$COMMIT_MSG_FILE"; then
    exit 0
fi

# Colors for output
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
BOLD='\033[1m'

# Track if any warnings were issued
HAS_WARNINGS=false

echo ""

# ============================================================================
# Check 1: The "AND" Test
# ============================================================================
# Look for "and" that connects two actions (not just part of a word)
# Common patterns: "add X and fix Y", "update A and refactor B"

# Get just the subject line (first line)
SUBJECT_LINE=$(echo "$COMMIT_MSG" | head -n1)

# Check for "and" in subject connecting actions (case insensitive)
# This regex looks for patterns like "verb... and verb..." or "noun and noun"
#
# VERB LIST MAINTENANCE:
# To add new verbs, append them to the list below separated by |
# Common additions: test, check, validate, process, format, parse, etc.
# The list intentionally excludes common non-action words to reduce false positives
if echo "$SUBJECT_LINE" | grep -qiE ' and (add|fix|update|refactor|remove|implement|create|delete|rename|move|change|modify|improve|enhance|resolve|handle|support|enable|disable|write|apply|set|configure|build|run|cleanup|clean|test|docs|document)'; then
    HAS_WARNINGS=true
    echo -e "${YELLOW}${BOLD}Atomic Commit Warning:${NC} Message contains \"and\" linking multiple changes"
    echo ""
    echo "  Your message: $SUBJECT_LINE"
    echo ""
    echo "  Consider splitting into separate commits:"
    echo "  - One commit per logical change"
    echo "  - Each commit should do ONE thing"
    echo ""
    echo -e "  ${GREEN}Tip:${NC} If you used \"and\", it's usually two commits."
    echo ""
fi

# ============================================================================
# Check 2: Commit Size Warning
# ============================================================================
# Check number of staged files
#
# PORTABILITY NOTE:
# Using awk instead of grep -oE for better cross-platform compatibility.
# BSD grep (macOS) and GNU grep (Linux) handle -oE differently, but awk
# is consistent across platforms.

STAGED_FILES=$(git diff --cached --name-only 2>/dev/null | wc -l | tr -d ' ')
# Count both insertions and deletions for accurate size indication
# Using awk for portable number extraction (works on both macOS and Linux)
STAT_LINE=$(git diff --cached --stat 2>/dev/null | tail -1)
INSERTIONS=$(echo "$STAT_LINE" | awk '{for(i=1;i<=NF;i++) if($i ~ /insertion/) print $(i-1)}')
DELETIONS=$(echo "$STAT_LINE" | awk '{for(i=1;i<=NF;i++) if($i ~ /deletion/) print $(i-1)}')
INSERTIONS=${INSERTIONS:-0}
DELETIONS=${DELETIONS:-0}
STAGED_LINES=$((INSERTIONS + DELETIONS))

# Thresholds (adjust as needed)
FILES_THRESHOLD=10
LINES_THRESHOLD=500

if [ "$STAGED_FILES" -gt "$FILES_THRESHOLD" ]; then
    HAS_WARNINGS=true
    echo -e "${YELLOW}${BOLD}Commit Size Warning:${NC} $STAGED_FILES files in this commit"
    echo ""
    echo "  Large commits are harder to review and debug."
    echo "  Consider if this could be split into smaller commits."
    echo ""
    echo -e "  ${GREEN}Tip:${NC} Use 'git add -p' to stage specific changes."
    echo ""
fi

if [ "$STAGED_LINES" -gt "$LINES_THRESHOLD" ]; then
    HAS_WARNINGS=true
    echo -e "${YELLOW}${BOLD}Commit Size Warning:${NC} ~$STAGED_LINES lines changed"
    echo ""
    echo "  Large diffs are harder to review."
    echo "  Consider breaking into smaller logical units."
    echo ""
fi

# ============================================================================
# Summary
# ============================================================================

if [ "$HAS_WARNINGS" = true ]; then
    echo "────────────────────────────────────────────────────────────────"
    echo -e "${GREEN}This is guidance only - commit will proceed.${NC}"
    echo "See: .claude/knowledge/git/atomic-commits.md"
    echo "────────────────────────────────────────────────────────────────"
    echo ""
fi

# Always exit 0 (don't block commits, just warn)
exit 0
