#!/bin/bash
# check-issue-branch.sh — v1.10.0 W0a/I02: 分支名 + 提交消息 之规矩器
#
# 承: docs/WORKFLOW.md §9(一 issue 一分支 fix/<n>-<slug> · 提交消息带 (#<n>) · 按路径 add ·
#     禁 force)∧ openspec/specs/v1.10.0-goal-and-plan.md §二 M0 ∧ V1_10_0_RULINGS_03
#     T3(临时键先行)/T6(建号前用 v1100-<slug> 临时分支)。
#
# ★ 用法:
#   check-issue-branch.sh --branch <name>            # 判分支名(rc=0 合 / rc=1 拒)
#   check-issue-branch.sh --message <text|file>      # 判提交消息(rc=0 合 / rc=1 拒)
#   check-issue-branch.sh --message <t> --allow-pre-issue   # 建号前宽限(仅告警, 不拒)
#   check-issue-branch.sh --selftest                 # 自检: 4 正 4 负, 逐臂判出口码
#
# ★ 射程与限(照实 · 禁默扩):
#   1. 本器**不**判「按路径 add」(事后不可判 —— index 已混);该条系操作纪律, 由评审面兜底。
#   2. 本器**不**判 force push —— git pre-push 钩子之入参**不含** `--force`(只有 remote 名/URL),
#      故 fork 面不可达。可行替代: 本器之 --selftest 不覆盖之; 纪律面由 `WORKFLOW` §9 与评审兜底。
#      (此处显名: 原拆分 AC 之「pre-push 面检 --force 形」**不可实现**, 已报 ar 更正。)
#   3. 分支名之 v1100-<slug> 支系**临时形**(T6); 建号后须改 fix/<n>-<slug>。
#
# 出口码: 0 = 合 / 1 = 拒(具名原因打到 stderr)/ 2 = 用法错
set -uo pipefail

MODE=""
VALUE=""
ALLOW_PRE_ISSUE=0

usage() {
    sed -n '2,26p' "$0" | sed 's/^# \{0,1\}//'
    exit 2
}

check_branch() {
    local name="$1"
    if printf '%s' "$name" | grep -E '^fix/[0-9]+-[a-z0-9][a-z0-9-]*$' >/dev/null; then
        echo "ok: 分支名合规(fix/<n>-<slug>): $name"
        return 0
    fi
    if printf '%s' "$name" | grep -E '^v1100-[a-z0-9][a-z0-9-]*$' >/dev/null; then
        echo "ok: 分支名合规(建号前临时形 v1100-<slug> · 承 T6): $name"
        return 0
    fi
    echo "REJECT: 分支名不合规: '$name'" >&2
    echo "        期望: fix/<n>-<slug>(一 issue 一分支)或建号前 v1100-<slug>(T6)" >&2
    return 1
}

check_message() {
    local text="$1"
    if [ -f "$text" ]; then text="$(cat "$text")"; fi
    if printf '%s' "$text" | grep -E '\(#[0-9]+\)' >/dev/null; then
        echo "ok: 提交消息含 issue 关联 (#<n>)"
        return 0
    fi
    if [ "$ALLOW_PRE_ISSUE" = "1" ]; then
        echo "warn: 提交消息缺 (#<n>) —— 建号前宽限(--allow-pre-issue),建号后须补"
        return 0
    fi
    echo "REJECT: 提交消息缺 issue 关联 (#<n>)" >&2
    echo "        期望: 消息体内含 (#'真号');建号前之批用 --allow-pre-issue" >&2
    return 1
}

selftest() {
    local pass=0 fail=0
    st() { # $1=名 $2=期望rc $3=实际rc
        if [ "$2" = "$3" ]; then printf '  ✓ %s (rc=%s)\n' "$1" "$3"; pass=$((pass+1));
        else printf '  ✗ %s (期望 %s 得 %s)\n' "$1" "$2" "$3"; fail=$((fail+1)); fi
    }
    echo "== selftest: check-issue-branch.sh =="
    check_branch "fix/1-add-issue-template" >/dev/null 2>&1; st "正控 分支 fix/1-…" 0 $?
    check_branch "v1100-w0a-rules" >/dev/null 2>&1;        st "正控 分支 v1100-…" 0 $?
    check_message "feat: x (#12)" >/dev/null 2>&1;         st "正控 消息带 (#12)" 0 $?
    ALLOW_PRE_ISSUE=1 check_message "feat: x" >/dev/null 2>&1; st "正控 宽限缺号" 0 $?
    check_branch "master" >/dev/null 2>&1;                 st "负控 分支 master" 1 $?
    check_branch "fix/no-number" >/dev/null 2>&1;          st "负控 分支无号" 1 $?
    check_message "feat: x" >/dev/null 2>&1;               st "负控 消息缺号" 1 $?
    check_message "feat: x (#abc)" >/dev/null 2>&1;        st "负控 号非数" 1 $?
    echo "== 结果: PASS=$pass FAIL=$fail =="
    [ "$fail" -eq 0 ] || return 1
}

while [ $# -gt 0 ]; do
    case "$1" in
        --branch) MODE=branch; VALUE="${2:-}"; shift 2 || { usage; };;
        --message) MODE=message; VALUE="${2:-}"; shift 2 || { usage; };;
        --allow-pre-issue) ALLOW_PRE_ISSUE=1; shift;;
        --selftest) MODE=selftest; shift;;
        -h|--help) usage;;
        *) echo "未知参数: $1" >&2; usage;;
    esac
done

case "$MODE" in
    branch) check_branch "$VALUE";;
    message) check_message "$VALUE";;
    selftest) selftest;;
    *) usage;;
esac