#!/usr/bin/env bash
# Vibecrafted commit-message helper.
#
# Git runs this before commit-msg. Keep the final validator strict, but fill the
# mechanical trailers agents otherwise have to reconstruct by hand.

set -euo pipefail

msg_file="${1:-}"
source="${2:-}"

if [ -z "$msg_file" ] || [ ! -f "$msg_file" ]; then
    printf 'prepare-commit-msg: expected path to commit message file\n' >&2
    exit 2
fi

# Merge/revert/squash/fixup messages are generated by Git and validated
# separately by commit-msg.
first_line="$(head -n1 "$msg_file" | tr -d '\r')"
case "$first_line" in
    "Merge "*|"Revert "*|"fixup!"*|"squash!"*|"amend!"*) exit 0 ;;
esac

types='feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|release'
subject_pattern="^\\[([a-z][a-z0-9_-]*)/[a-z0-9][a-z0-9._-]*\\] (${types})(\\(.+\\))?: .+$"

agent=""
if [[ "$first_line" =~ $subject_pattern ]]; then
    agent="${BASH_REMATCH[1]}"
else
    # Let commit-msg report the exact shape problem. This helper only
    # normalizes messages that already declare the agent/runtime prefix.
    exit 0
fi

session_id_raw="${CODEX_SESSION_ID:-${CLAUDE_CODE_SESSION_ID:-${ATUIN_SESSION:-}}}"
# Git hooks do not receive the harness stdin the way Claude/Codex session hooks
# do, so the env vars above are often empty in this subprocess. Ask aicx — it
# authoritatively knows the current session per runtime — before inventing a
# random UUID, so the session_id trailer keeps real provenance (commit ->
# transcript -> aicx chunks).
if [ -z "$session_id_raw" ] && command -v aicx >/dev/null 2>&1; then
    session_id_raw="$(aicx sessions current 2>/dev/null || true)"
fi
if printf '%s' "$session_id_raw" | grep -Eq '^[0-9a-fA-F]{32}$'; then
    session_id="$(printf '%s' "$session_id_raw" | sed -E 's/^(.{8})(.{4})(.{4})(.{4})(.{12})$/\1-\2-\3-\4-\5/' | tr 'A-F' 'a-f')"
elif printf '%s' "$session_id_raw" | grep -Eq '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$'; then
    session_id="$(printf '%s' "$session_id_raw" | tr 'A-F' 'a-f')"
elif command -v uuidgen >/dev/null 2>&1; then
    session_id="$(uuidgen | tr 'A-F' 'a-f')"
else
    session_id="00000000-0000-4000-8000-000000000000"
fi

if command -v date >/dev/null 2>&1; then
    timestamp="$(date +%Y-%m-%dT%H:%M:%S%z | sed -E 's/([+-][0-9]{2})([0-9]{2})$/\1:\2/')"
else
    timestamp="1970-01-01T00:00:00Z"
fi

runtime="${VIBECRAFTED_COMMIT_RUNTIME:-${VIBECRAFTED_RUNTIME:-}}"
if [ -z "$runtime" ]; then
    case "${TERM_PROGRAM:-}" in
        iTerm.app|iTerm2) runtime="iterm2" ;;
        Apple_Terminal) runtime="terminal" ;;
        *) runtime="interactive" ;;
    esac
fi

append_trailer() {
    local key="$1"
    local value="$2"
    if grep -Eq "^${key}:" "$msg_file"; then
        return 0
    fi
    printf '\n%s: %s\n' "$key" "$value" >> "$msg_file"
}

append_trailer "Authored-By" "${agent} <agents@vetcoders.io>"
append_trailer "session_id" "$session_id"
append_trailer "time" "$timestamp"
append_trailer "runtime" "$runtime"

if [ "$source" != "message" ]; then
    printf 'prepare-commit-msg: added Vibecrafted trailers for %s\n' "$agent" >&2
fi
