#!/bin/sh
# commit-msg hook: enforce the repository's commit format and prose rules.
# Install per clone (hooks are not cloned): git config core.hooksPath .githooks
# See core/commits.md and core/git-discipline.md.

set -eu

msg_file="${1:?usage: commit-msg <message-file>}"
clean=$(mktemp "${TMPDIR:-/tmp}/rules-swift-commit-message.XXXXXX")
trap 'rm -f "$clean"' EXIT HUP INT TERM

# Ignore Git's comment lines and everything after the scissors marker.
awk '
    /^# ------------------------ >8 ------------------------$/ { exit }
    !/^#/ { print }
' "$msg_file" > "$clean"

subject=$(sed -n '1p' "$clean")

if [ -z "$subject" ]; then
    echo "commit-msg: subject must not be empty." >&2
    exit 1
fi

if [ "${#subject}" -gt 72 ]; then
    echo "commit-msg: subject exceeds 72 characters (${#subject})." >&2
    exit 1
fi

if ! printf '%s\n' "$subject" | grep -qE '^(feat|fix|docs|style|refactor|perf|test|build|ci|chore)(\([a-z0-9._-]+\))?!?: [^ ].*[^.]$'; then
    echo "commit-msg: use <type>(<scope>): imperative description, with an allowed Conventional Commit type and no trailing period." >&2
    exit 1
fi

case "$subject" in
    *'!:'*)
        if ! grep -qE '^BREAKING CHANGE: .+' "$clean"; then
            echo "commit-msg: a breaking subject requires a BREAKING CHANGE footer with a migration explanation." >&2
            exit 1
        fi
        ;;
    *)
        if grep -q '^BREAKING CHANGE:' "$clean"; then
            echo "commit-msg: a BREAKING CHANGE footer requires ! in the subject." >&2
            exit 1
        fi
        ;;
esac

if grep -qiE '(claude|anthropic|cursor|copilot|codex|openai|chatgpt|gpt-[0-9a-z.-]*|gemini|antigravity|(^|[^[:alnum:]])AI([^[:alnum:]]|$)|LLM|assistant|machine-generated|co-pilot|pair-programmer|robot)' "$clean"; then
    echo "commit-msg: Rule 5.1 forbids tool or automated-author attribution." >&2
    exit 1
fi

if grep -q "$(printf '\342\200\224')" "$clean"; then
    echo "commit-msg: Rule 5.2 forbids em dashes; use commas, colons, or restructure." >&2
    exit 1
fi

if grep -q "$(printf '\360\237\244\226')" "$clean" \
    || grep -q "$(printf '\342\234\250')" "$clean"; then
    echo "commit-msg: Rule 5.1 forbids tool-signature emoji." >&2
    exit 1
fi

if grep -q "$(printf '\342\200\213')" "$clean" \
    || grep -q "$(printf '\357\273\277')" "$clean"; then
    echo "commit-msg: Rule 5.1 forbids hidden watermark characters." >&2
    exit 1
fi

if awk 'length($0) > 72 { found = 1 } END { exit found ? 0 : 1 }' "$clean"; then
    echo "commit-msg: body and footer lines must be wrapped at 72 characters." >&2
    exit 1
fi

exit 0
