#!/usr/bin/env bash
# CVC pre-commit guard — reject any commit that contains a Telegram bot
# token, an OpenAI/Anthropic/Copilot API key, or any other recognized
# secret pattern. Runs in <100ms on a clean tree.
#
# Failure mode: the commit is BLOCKED. The developer must remove the
# secret from the file (or move it to ~/.cvc/ or another .gitignored
# location) before the commit can succeed.
#
# Add new patterns to PATTERNS below as new secret formats are
# discovered. Keep them anchored to well-known prefixes so we don't
# false-positive on innocuous numbers.
set -e

# Patterns that should NEVER appear in tracked source code.
# Format: "regex|human-readable description"
PATTERNS=(
  'TELEGRAM_BOT_TOKEN=[0-9]+:AA[A-Za-z0-9_-]+|Telegram bot token in env-style assignment'
  'token="[0-9]+:AA[A-Za-z0-9_-]+"|Telegram bot token hardcoded as Python string'
  "'[0-9]+:AA[A-Za-z0-9_-]+'|Telegram bot token as single-quoted string"
  'sk-[A-Za-z0-9]{20,}|OpenAI-style API key (sk-…)'
  'sk-ant-[A-Za-z0-9_-]{20,}|Anthropic API key (sk-ant-…)'
  'ghp_[A-Za-z0-9]{20,}|GitHub personal access token (ghp_…)'
  'github_pat_[A-Za-z0-9_]{20,}|GitHub fine-grained PAT (github_pat_…)'
)

# Only check STAGED changes (what's about to be committed), not the
# full working tree. This lets devs keep secrets in working files
# while iterating; the secret only fails when they try to commit it.
STAGED=$(git diff --cached --diff-filter=ACMR --name-only 2>/dev/null || true)
if [[ -z "$STAGED" ]]; then
  exit 0
fi

FAILED=0
for file in $STAGED; do
  # Skip deleted files and binary files.
  [[ -f "$file" ]] || continue
  file_type=$(file --mime-type -b "$file" 2>/dev/null || echo "text/plain")
  [[ "$file_type" == text/* ]] || continue
  for pat in "${PATTERNS[@]}"; do
    regex="${pat%%|*}"
    desc="${pat##*|}"
    if grep -E -nH -- "$regex" "$file" >/dev/null 2>&1; then
      echo "❌ pre-commit: blocked — $desc"
      echo "   in file: $file"
      grep -E -n -- "$regex" "$file" | head -3 | sed 's/^/   > /'
      echo ""
      echo "   Move the secret to a .gitignored location (e.g. ~/.cvc/, .env, "
      echo "   environment variable) and re-stage the file. Telegram credentials "
      echo "   specifically belong in ~/.cvc/channels/<name>.yaml, never in the "
      echo "   CVC source tree."
      echo ""
      FAILED=1
    fi
  done
done

if [[ $FAILED -ne 0 ]]; then
  echo "❌ Commit blocked. Remove the secret(s) above and try again."
  echo "   To bypass (NOT recommended): git commit --no-verify"
  exit 1
fi

exit 0
