#!/bin/sh
#
# Commit-msg hook: Validate commit message format
# Enforces Conventional Commits specification
# https://www.conventionalcommits.org/
#

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

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

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

# Skip revert commits
if echo "$COMMIT_MSG" | grep -qE "^Revert "; then
    exit 0
fi

echo "${CYAN}▸ Validating commit message...${NC}"

# Conventional commit types
TYPES="feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert"

# Pattern: type(optional-scope): description
# The description must start with lowercase and be at least 3 chars
PATTERN="^($TYPES)(\(.+\))?: .{3,}"

# Get the first line (subject)
SUBJECT=$(echo "$COMMIT_MSG" | head -n 1)

# Check if subject matches conventional commit format
if ! echo "$SUBJECT" | grep -qE "$PATTERN"; then
    echo ""
    echo "${RED}✖ Invalid commit message format!${NC}"
    echo ""
    echo "${YELLOW}Your commit message:${NC}"
    echo "  $SUBJECT"
    echo ""
    echo "${YELLOW}Expected format:${NC}"
    echo "  <type>(<scope>): <description>"
    echo ""
    echo "${YELLOW}Valid types:${NC}"
    echo "  feat     - A new feature"
    echo "  fix      - A bug fix"
    echo "  docs     - Documentation only changes"
    echo "  style    - Code style changes (formatting, etc)"
    echo "  refactor - Code refactoring"
    echo "  perf     - Performance improvements"
    echo "  test     - Adding or updating tests"
    echo "  build    - Build system or dependencies"
    echo "  ci       - CI/CD configuration"
    echo "  chore    - Other changes (maintenance)"
    echo "  revert   - Reverting a previous commit"
    echo ""
    echo "${YELLOW}Examples:${NC}"
    echo "  feat: add lazy singleton support"
    echo "  fix(container): resolve race condition in scope lookup"
    echo "  docs: update README with usage examples"
    echo "  refactor(storage): simplify type erasure implementation"
    echo ""
    exit 1
fi

# Check subject length (should be <= 72 characters)
SUBJECT_LENGTH=${#SUBJECT}
if [ "$SUBJECT_LENGTH" -gt 72 ]; then
    echo ""
    echo "${RED}✖ Commit subject too long!${NC}"
    echo "${YELLOW}  Subject is $SUBJECT_LENGTH characters (max 72)${NC}"
    echo ""
    exit 1
fi

# Check that subject doesn't end with a period
if echo "$SUBJECT" | grep -qE '\.$'; then
    echo ""
    echo "${RED}✖ Commit subject should not end with a period${NC}"
    echo ""
    exit 1
fi

# Check for blank line between subject and body (if body exists)
LINE_COUNT=$(echo "$COMMIT_MSG" | wc -l)
if [ "$LINE_COUNT" -gt 1 ]; then
    SECOND_LINE=$(echo "$COMMIT_MSG" | sed -n '2p')
    if [ -n "$SECOND_LINE" ]; then
        echo ""
        echo "${RED}✖ Missing blank line between subject and body${NC}"
        echo "${YELLOW}  Add an empty line after the subject line${NC}"
        echo ""
        exit 1
    fi
fi

echo "${GREEN}✔ Commit message valid${NC}"

