#!/bin/sh
# nanodock - Commit message validation hook
# Enforces Conventional Commits format: https://www.conventionalcommits.org
#
# Format: <type>(<optional-scope>): <description>
#
# Allowed types:
#   feat      — New feature or capability
#   fix       — Bug fix
#   docs      — Documentation only changes
#   style     — Formatting, whitespace, no code change
#   refactor  — Code change that neither fixes a bug nor adds a feature
#   perf      — Performance improvement
#   test      — Adding or updating tests
#   build     — Build system or external dependency changes
#   ci        — CI/CD configuration changes
#   chore     — Maintenance tasks, tooling, config
#   revert    — Reverts a previous commit
#   enforce   — Adding or updating enforcement rules/quality gates
#
# Rules:
#   - Type is required and must be one of the above
#   - Scope is optional, wrapped in parentheses: feat(api): ...
#   - Colon + space after type/scope is required
#   - Description must start with lowercase letter
#   - Description must be 5-200 characters
#   - No period at the end of the subject line
#
# Examples:
#   feat(api): parse container labels from daemon response
#   fix(ipc): handle named pipe timeout on Windows
#   docs: update README with usage examples

# Read the commit message (first line only for subject validation)
commit_msg_file="$1"
subject=$(head -1 "$commit_msg_file")

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

# Skip revert commits generated by git
if echo "$subject" | grep -qE '^Revert "'; then
    exit 0
fi

# Allowed types
types="feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|enforce"

# Pattern: type(optional-scope): lowercase description
# - Type must be one of the allowed list
# - Optional scope in parentheses (alphanumeric + hyphens)
# - Colon and space required
# - Description starts with lowercase letter
pattern="^($types)(\([a-z0-9-]+\))?: [a-z]"

if ! echo "$subject" | grep -qE "$pattern"; then
    echo ""
    echo "✗ COMMIT MESSAGE REJECTED"
    echo ""
    echo "  Your message:  \"$subject\""
    echo ""
    echo "  Expected format: <type>(<scope>): <description>"
    echo ""
    echo "  Allowed types:"
    echo "    feat, fix, docs, style, refactor, perf,"
    echo "    test, build, ci, chore, revert, enforce"
    echo ""
    echo "  Rules:"
    echo "    - Description must start with a lowercase letter"
    echo "    - No period at the end"
    echo "    - Scope is optional: feat(api): ..."
    echo ""
    echo "  Examples:"
    echo "    feat(api): parse container labels from daemon response"
    echo "    fix(ipc): handle named pipe timeout on Windows"
    echo "    docs: update README with usage examples"
    echo ""
    exit 1
fi

# Check subject length (description part, after "type: " or "type(scope): ")
desc=$(echo "$subject" | sed -E "s/^($types)(\([a-z0-9-]+\))?: //")
desc_len=${#desc}

if [ "$desc_len" -lt 5 ]; then
    echo ""
    echo "✗ COMMIT MESSAGE TOO SHORT"
    echo "  Description must be at least 5 characters."
    echo "  Got: \"$desc\" ($desc_len chars)"
    echo ""
    exit 1
fi

if [ "$desc_len" -gt 200 ]; then
    echo ""
    echo "✗ COMMIT MESSAGE TOO LONG"
    echo "  Subject line description must be ≤200 characters."
    echo "  Got: \"$desc\" ($desc_len chars)"
    echo ""
    exit 1
fi

# No period at the end
if echo "$subject" | grep -qE '\.$'; then
    echo ""
    echo "✗ COMMIT MESSAGE ENDS WITH PERIOD"
    echo "  Do not end the subject line with a period."
    echo "  Got: \"$subject\""
    echo ""
    exit 1
fi
