#!/bin/bash
#
# Commit message hook to enforce conventional commit format
# Format: <type>(<scope>): <subject>
#
# Types: feat, fix, docs, style, refactor, test, chore, perf, ci, build
#

# Redirect output to stderr
exec 1>&2

commit_msg_file="$1"
commit_msg=$(cat "$commit_msg_file")

# Maximum line lengths
max_subject_length=72
max_body_length=80

# Check if commit message is empty
if [ -z "$commit_msg" ]; then
    echo "Error: Commit message is empty"
    exit 1
fi

# Read first line (subject)
subject=$(echo "$commit_msg" | head -n1)

# Skip for merge commits and revert commits
if echo "$subject" | grep -qE "^Merge |^Revert "; then
    exit 0
fi

# Check for conventional commit format
# Format: type(scope): subject
# Or: type: subject (without scope)
if ! echo "$subject" | grep -qE "^((feat|fix|docs|style|refactor|test|chore|perf|ci|build)(\(.+\))?: .+)$"; then
    echo "Error: Commit message does not follow conventional commit format"
    echo ""
    echo "Format: <type>(<scope>): <subject>"
    echo ""
    echo "Types:"
    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 "  test:     Adding or updating tests"
    echo "  chore:    Maintenance tasks"
    echo "  perf:     Performance improvements"
    echo "  ci:       CI/CD changes"
    echo "  build:    Build system changes"
    echo ""
    echo "Examples:"
    echo "  feat(parser): add support for nested lists"
    echo "  fix(compiler): resolve memory leak in AST nodes"
    echo "  docs: update README with build instructions"
    echo ""
    exit 1
fi

# Check subject length
subject_length=${#subject}
if [ $subject_length -gt $max_subject_length ]; then
    echo "Warning: Subject line is too long ($subject_length > $max_subject_length characters)"
    echo "Consider breaking it into multiple lines"
fi

# Check body line lengths (if present)
line_num=2
while IFS= read -r line; do
    if [ -n "$line" ] && [ ${#line} -gt $max_body_length ]; then
        echo "Warning: Line $line_num in commit message is too long (${#line} > $max_body_length characters)"
    fi
    ((line_num++))
done < <(echo "$commit_msg" | tail -n +2)

exit 0



