#!/usr/bin/env bash
# PreToolUse(Bash) — 게이트 우회 차단.
# `git commit --no-verify`(-n)·`git push --no-verify`는 pre-commit/pre-push 게이트의
# 뒷문이다. 게이트가 실패하면 우회가 아니라 코드를 고치는 게 답이다.
# 오탐 방지: 따옴표 안 문자열 제거 후, commit/push 서브커맨드 범위에서만 매칭
# (git log -n·git grep -n·git push -n(dry-run)은 무해 — 통과).

set -u
input=$(cat 2>/dev/null || true)
cmd=$(printf '%s' "$input" | node "$(dirname "$0")/read-json-field.mjs" tool_input.command 2>/dev/null || true)
[ -n "$cmd" ] || exit 0

# git 명령이 아니면 통과
case "$cmd" in *git*) ;; *) exit 0 ;; esac

# 따옴표 안 문자열 제거 (커밋 메시지 속 "--no-verify" 언급 오탐 방지)
stripped=$(printf '%s' "$cmd" | sed -E "s/'[^']*'//g; s/\"[^\"]*\"//g")

deny() {
  printf '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"%s"}}\n' "$1"
  exit 0
}

# 훅 자체를 끄는 경로 — 플래그가 아니라 환경·설정으로 우회한다.
# 실측: 둘 다 pre-commit을 건너뛰고 커밋이 성사됐다(`HUSKY=0`은 husky 공식 킬스위치,
# `core.hooksPath`는 순수 git 기능). --no-verify가 막힌 다음에 손이 가는 경로라 함께 막는다.
if printf '%s' "$stripped" | grep -qE '(^|[[:space:]])HUSKY=0([[:space:]]|$)'; then
  deny "HUSKY=0은 pre-commit·pre-push 게이트를 통째로 끕니다. 게이트가 실패하면 우회 말고 코드를 고치세요 (fix-error 스킬)."
fi

if printf '%s' "$stripped" | grep -qE 'core\.hooksPath[[:space:]]*='; then
  deny "core.hooksPath를 바꾸는 것은 게이트 훅을 통째로 갈아치우는 것이라 차단됩니다. 게이트가 잘못됐다면 스크립트를 고치고 gate-selftest를 통과시키세요."
fi

# commit: --no-verify와 -n(동의어) 차단. -n은 -nm처럼 다른 단축 플래그와 붙여 쓸 수 있어
# 뒤에 공백을 요구하면 `git commit -nm "msg"`가 그대로 빠져나간다(실측으로 커밋 성사 확인).
if printf '%s' "$stripped" | grep -qE 'git([[:space:]]+-[A-Za-z-]+)*[[:space:]]+commit[^|;&]*([[:space:]]--no-verify([[:space:]]|$)|[[:space:]]-[A-Za-z]*n[A-Za-z]*([[:space:]]|$))'; then
  deny "git commit --no-verify는 품질 게이트의 뒷문이라 차단됩니다. 게이트가 실패하면 우회 말고 코드를 고치세요 (fix-error 스킬). 게이트 자체가 잘못됐다면 .oxlintrc.json/스크립트를 수정하고 gate-selftest를 통과시키세요."
fi

# push: --no-verify만 차단 (-n은 --dry-run이라 무해)
if printf '%s' "$stripped" | grep -qE 'git([[:space:]]+-[A-Za-z-]+)*[[:space:]]+push[^|;&]*[[:space:]]--no-verify([[:space:]]|$)'; then
  deny "git push --no-verify는 pre-push 풀 게이트의 뒷문이라 차단됩니다. pnpm verify를 통과시킨 뒤 push하세요."
fi

exit 0
