#!/bin/bash
# install-pre-commit.sh — Instala hook pre-commit anti-secrets en este clon del repo.
#
# Uso (una sola vez por dev local):
#   bash infrastructure/scripts/utility/install-pre-commit.sh
#
# Lo que detecta el hook:
#   - Stripe live keys (sk_live_*, pk_live_*)
#   - Airtable PATs (pat[A-Za-z0-9]{14,})
#   - Slack webhook URLs completas (con secret token)
#   - Strings explícitos del incidente histórico (MAIL_PASSWORD viejo)
#   - AWS keys (AKIA[0-9A-Z]{16})
#   - Backblaze application keys (K00[0-9A-Za-z]+)
#   - Generic high-entropy patterns en lines de asignación

set -uo pipefail

REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null)"
if [[ -z "$REPO_ROOT" ]]; then
    echo "ERROR: ejecutar dentro del clon git de cd-system" >&2
    exit 1
fi

HOOK_PATH="$REPO_ROOT/.git/hooks/pre-commit"

cat > "$HOOK_PATH" <<'HOOK_EOF'
#!/bin/bash
# pre-commit anti-secrets — instalado por infrastructure/scripts/utility/install-pre-commit.sh
# NO lo edites a mano: re-ejecutá el installer si hay cambios.

set -uo pipefail

# Solo escanear archivos staged para commit
STAGED=$(git diff --cached --name-only --diff-filter=ACM)

if [[ -z "$STAGED" ]]; then
    exit 0
fi

# Ignore lista: archivos donde es OK encontrar fixtures/tests/secrets ejemplificados
# Incluye el propio installer porque tiene los patrones regex (auto-falsa-detección).
IGNORE_PATTERN='(\.env\.example$|infrastructure/env-templates/|infrastructure/scripts/utility/install-pre-commit\.sh$|tests/fixtures/|docs/_legacy/|\.lock$|composer\.lock|package-lock\.json|\.git/hooks/pre-commit$)'

PATTERNS=(
    # Stripe live
    'sk_live_[A-Za-z0-9]{20,}'
    'pk_live_[A-Za-z0-9]{20,}'
    # Stripe restricted
    'rk_live_[A-Za-z0-9]{20,}'
    # Airtable PAT
    'pat[A-Za-z0-9]{14,}\.[A-Fa-f0-9]{60,}'
    # Slack webhook completo
    'hooks\.slack\.com/services/T[A-Z0-9]+/B[A-Z0-9]+/[A-Za-z0-9]{16,}'
    # Slack bot tokens
    'xox[baprs]-[A-Za-z0-9-]{10,}'
    # AWS Access Key
    'AKIA[0-9A-Z]{16}'
    # Backblaze application key (K00*)
    'K00[A-Za-z0-9+/]{30,}'
    # GitHub PAT (ghp_, gho_)
    'gh[pousr]_[A-Za-z0-9]{36,}'
    # Hardcoded MAIL_PASSWORD del incidente histórico
    '6A5cnothb8it7QbHJQJQ'
    # Generic: línea con SECRET=valor o PASSWORD=valor con string largo
    '(SECRET|PASSWORD|TOKEN|API_KEY)=[A-Za-z0-9+/=]{24,}'
)

FOUND=0
for FILE in $STAGED; do
    # Skip ignore paths
    if echo "$FILE" | grep -qE "$IGNORE_PATTERN"; then
        continue
    fi
    # Skip si el archivo ya no existe (deleted)
    if [ ! -f "$FILE" ]; then
        continue
    fi

    for PATTERN in "${PATTERNS[@]}"; do
        # Buscar SOLO en las líneas staged (diff added)
        MATCH=$(git diff --cached -U0 -- "$FILE" | grep -E "^\+" | grep -vE "^\+\+\+" | grep -E "$PATTERN" || true)
        if [[ -n "$MATCH" ]]; then
            echo "❌ POSIBLE SECRETO en $FILE (patrón: $PATTERN):"
            echo "$MATCH" | head -3 | sed 's/^/    /'
            echo
            FOUND=1
        fi
    done
done

if [ $FOUND -ne 0 ]; then
    echo "════════════════════════════════════════════════════════════════"
    echo "  Pre-commit BLOQUEADO — uno o más patrones de secretos encontrados."
    echo
    echo "  Si es falso positivo:"
    echo "    git commit --no-verify  # bypass UNA vez (con cuidado)"
    echo
    echo "  Si es real:"
    echo "    1. Sacar el valor del archivo (mover a env / secret store)"
    echo "    2. ROTAR el secreto (asumir comprometido)"
    echo "    3. git add + git commit normal"
    echo "════════════════════════════════════════════════════════════════"
    exit 1
fi

exit 0
HOOK_EOF

chmod +x "$HOOK_PATH"
echo "✅ pre-commit hook instalado en $HOOK_PATH"
echo
echo "Para test (sin commitear):"
echo "  echo 'TOKEN=sk_live_aaaaaaaaaaaaaaaaaaaaaaaaaa' > /tmp/test-secret.txt"
echo "  cd $REPO_ROOT && git add /tmp/test-secret.txt && .git/hooks/pre-commit"
echo "  # debería detectar el patrón Stripe"
