#!/bin/bash
# .claude/hooks/pre-bash-guard.sh
# arcrun PreToolUse guard for Bash
#
# 職責：擋下會違反 CLAUDE rules 的 shell 指令
# 退出 code：
#   0 = 允許
#   2 = 擋下（stderr 訊息會回傳給 CC）

set -o pipefail

INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // ""')

block() {
  local rule="$1"
  local reason="$2"
  local fix="$3"
  cat >&2 <<EOF
❌ BLOCKED by arcrun CLAUDE rules
違反項：${rule}
指令：${CMD}
原因：${reason}
正確做法：${fix}
參考：.claude/rules/02-forbidden.md
EOF
  exit 2
}

# ─────────────────────────────────────────────────────────────────────────────
# 規則 1.2 / 3.3：禁止用 mkdir 建立違規的 auth/credential worker 目錄
# ─────────────────────────────────────────────────────────────────────────────
if echo "$CMD" | grep -qE "mkdir.*((auth|credential|jwt|oauth)[-_]worker|new[-_](auth|credential|jwt|oauth))"; then
  block "1.2/3.3" \
    "偵測到嘗試建立新的 auth/credential/jwt/oauth Worker 目錄" \
    "auth primitive 放在 registry/components/auth_*/；不需要另建 worker 目錄"
fi

# 禁止建立同名零件的平行目錄
if echo "$CMD" | grep -qE "mkdir.*/(gmail|telegram|google[-_]sheets|line[-_]notify|http[-_]request)[-_](v2|v3|new|worker|backup)"; then
  block "3.3" \
    "禁止為既有零件建立平行目錄（v2/new/worker/backup）" \
    "直接改 registry/components/<n>/main.go"
fi

# ─────────────────────────────────────────────────────────────────────────────
# 規則 1.3：禁止 wrangler init / generate auth-* credential-* jwt-*
# ─────────────────────────────────────────────────────────────────────────────
if echo "$CMD" | grep -qE "wrangler[[:space:]]+(init|generate).*[[:space:]](auth|credential|jwt|oauth)[-_]"; then
  block "1.3" \
    "禁止用 wrangler init/generate 建立 auth/credential/jwt Worker" \
    "auth primitive 透過 component-worker-template/ 搭配 WASM binary 部署，不要 wrangler init"
fi

# ─────────────────────────────────────────────────────────────────────────────
# 規則 3.1：Service Binding 新增警示
# ─────────────────────────────────────────────────────────────────────────────
# 偵測在 wrangler.toml 新增 [[services]] 的 echo/cat/sed 操作（非 100% 準確，但夠用）
if echo "$CMD" | grep -qE "echo.*\[\[services\]\].*>>"; then
  block "3.1" \
    "偵測到要在 wrangler.toml 新增 [[services]] binding" \
    "零件串接一律走 HTTP URL（cypher binding），不新增 service binding。若有特殊需求，先與 richblack 確認"
fi

# ─────────────────────────────────────────────────────────────────────────────
# 一般性危險指令
# ─────────────────────────────────────────────────────────────────────────────
if echo "$CMD" | grep -qE "rm[[:space:]]+-rf[[:space:]]+(/|/\*|~|\\\$HOME|\.)"; then
  block "general" \
    "偵測到危險的 rm -rf 指令" \
    "明確指定要刪的目錄，不要對根目錄 / home / 當前目錄遞迴刪除"
fi

# 禁止 force push 到 main
if echo "$CMD" | grep -qE "git[[:space:]]+push.*--force.*(main|master)"; then
  block "general" \
    "禁止 force push 到 main/master" \
    "用 feature branch，或和 richblack 確認後手動操作"
fi

# ─────────────────────────────────────────────────────────────────────────────
# 資料外流警示（data-exfil-warning SDD R2）：AI 動手把資料變成可被外部呼叫前先擋
# `acr push`（部署 webhook）/ `acr recipe push`（定義資料去向）= 暴露面動作。
# 不含 `acr creds push`（上傳加密 credential 是保護，非暴露）。
#
# 信任修正（2026-05-30）：無「旗標放行」捷徑——AI 自己能加的旗標 = 自己批准自己。
# 這類動作一律擋，必須由人類在終端機親自執行（CLI 會跳互動、要人類輸入資源名確認）。
# ─────────────────────────────────────────────────────────────────────────────
# 只在「指令本身就是執行 acr push / acr recipe push」時擋（錨定到指令開頭，
# 允許前置 cd .. && 或環境變數）。避免誤判 git commit -m "...acr push..." 這類
# 「字串裡剛好提到 acr push」的情況（commit message / echo / grep 不該被擋）。
if echo "$CMD" | grep -qE "(^|&&|;|\|)[[:space:]]*(cd[[:space:]][^&;|]*(&&|;)[[:space:]]*)?([A-Za-z_]+=[^[:space:]]*[[:space:]]+)*acr[[:space:]]+(recipe[[:space:]]+)?push\b" \
   && ! echo "$CMD" | grep -qE "acr[[:space:]]+creds[[:space:]]+push\b"; then
  cat >&2 <<'EOF'
❌ BLOCKED：資料外流警示（arcrun data-exfil-warning）
原因：acr push / acr recipe push 會把資料/workflow 變成「可被外部呼叫」（暴露面）。
      這種動作你（AI）不能自行執行，也沒有旗標捷徑——需人類明示知情同意（法律憑證）。
正確做法：
  - 把這件事交給人類：請人類在終端機親自執行（CLI 會跳互動、要人類輸入資源名確認）
  - 人類第一次確認後 server 會記住，之後同資源不用再確認
參考：docs/3-specs/data-exfil-warning/
EOF
  exit 2
fi

exit 0
