#!/usr/bin/env bash
# Conventional Commits 提交信息校验闸门（本机 hook）
# 安装：cp templates/commit-msg ~/.githooks/commit-msg && chmod +x ~/.githooks/commit-msg
#        git config --global core.hooksPath ~/.githooks
# 绕过：git commit --no-verify（不建议）；CI 侧 .gitea/scripts/ci_gate.py 会再拦一次，绕不过。
# 规则必须与 .gitea/scripts/ci_gate.py 完全一致 —— 两处不一致 = 本地绿、CI 红（或反之）。
set -uo pipefail

msg_file="${1:-}"
[ -n "$msg_file" ] || { echo "commit-msg: 缺少提交信息文件参数" >&2; exit 1; }
[ -f "$msg_file" ] || exit 0

# 取第一条非注释行作为标题
subject_line=""
while IFS= read -r line; do
  case "$line" in ''|'#'*) continue ;; esac
  subject_line="$line"; break
done < "$msg_file"
[ -n "$subject_line" ] || exit 0

# 放行自动生成的提交
case "$subject_line" in
  Merge\ *|Revert\ \"*|fixup!\ *|squash!\ *|amend!\ *) exit 0 ;;
esac

TYPES="feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert"
RE='^('"$TYPES"')(\([a-zA-Z0-9._/-]+\))?!?: .{3,}$'

fail() {
  cat >&2 <<EOF

❌ 提交信息不合规，已拦截。

   你写的 : $subject_line
   原因   : $1

   规范   : <类型>(<范围>): <简短描述>
   类型   : feat 新功能 | fix 修缺陷 | docs 文档 | style 格式(不改逻辑)
            refactor 重构 | perf 性能 | test 测试 | build 构建/依赖
            ci CI 配置 | chore 杂务 | revert 回滚
   范围   : 可选，小写，如 (card) (weknora) (deploy)

   正确示例
     feat(asset): 新增按歌曲生成应援序列
     fix(parser): 修复表格解析越界导致的 500
     ci: 接入 Gitea Actions 自动编译

   要点
     · 类型小写，冒号后必须有一个空格，描述 ≥3 个字符
     · 标题 ≤72 字符，结尾不要加句号
     · 说明「为什么」写正文（空一行后），一行一件事
     · 破坏性变更：类型后加 !，并在正文写 BREAKING CHANGE: 说明
     · ⚠️ 正文不要直接在 -m 里写反引号 / \$()（会被 shell 先执行）：
          git commit -F - <<'EOF'

   临时绕过（不推荐，CI 仍会拦截）: git commit --no-verify
EOF
  exit 1
}

[ ${#subject_line} -le 72 ] || fail "标题 ${#subject_line} 字符 > 72"
case "$subject_line" in
  *. | *。) fail "标题结尾不要加句号" ;;
esac
printf '%s' "$subject_line" | grep -Eq "$RE" || fail "不符合 <类型>(<范围>): <描述>"