#!/usr/bin/env bash
# secret-scan.sh — Scans for private keys and high-entropy secrets
# Usage: bash tools/secret-scan.sh [directory]
# Uses .secret-scan-allowlist for false positives (one file path per line)

set -e

SCAN_DIR="${1:-.}"
ALLOWLIST=".secret-scan-allowlist"
FINDINGS=0

# Build find exclusions
EXCLUDES=(-not -path "*/node_modules/*" -not -path "*/.git/*" -not -path "*/coverage/*" -not -path "*/dist/*")

# Load allowlist
ALLOWLIST_PATHS=()
if [ -f "$ALLOWLIST" ]; then
    while IFS= read -r line || [ -n "$line" ]; do
        [[ "$line" =~ ^#.*$ || -z "$line" ]] && continue
        ALLOWLIST_PATHS+=("$line")
    done < "$ALLOWLIST"
fi

is_allowed() {
    local file="$1"
    for allowed in "${ALLOWLIST_PATHS[@]}"; do
        if [[ "$file" == *"$allowed"* ]]; then
            return 0
        fi
    done
    return 1
}

echo "Scanning $SCAN_DIR for secrets..."

# Scan for private keys
while IFS= read -r file; do
    [ -f "$file" ] || continue
    is_allowed "$file" && continue
    if grep -qE '-----BEGIN (RSA |EC |OPENSSH |DSA )?PRIVATE KEY-----' "$file" 2>/dev/null; then
        echo "FINDING [private-key]: $file"
        FINDINGS=$((FINDINGS + 1))
    fi
done < <(find "$SCAN_DIR" "${EXCLUDES[@]}" -type f)

# Scan for high-entropy hex strings (40+ chars)
while IFS= read -r file; do
    [ -f "$file" ] || continue
    is_allowed "$file" && continue
    if grep -qE '[0-9a-f]{40,}' "$file" 2>/dev/null; then
        # Filter out common false positives (git SHAs in lock files, etc.)
        BASENAME=$(basename "$file")
        if [[ "$BASENAME" != "package-lock.json" && "$BASENAME" != "*.lock" ]]; then
            MATCHES=$(grep -oE '[0-9a-f]{40,}' "$file" 2>/dev/null || true)
            if [ -n "$MATCHES" ]; then
                echo "FINDING [high-entropy-hex]: $file"
                FINDINGS=$((FINDINGS + 1))
            fi
        fi
    fi
done < <(find "$SCAN_DIR" "${EXCLUDES[@]}" -type f -not -name "package-lock.json" -not -name "*.lock")

if [ "$FINDINGS" -gt 0 ]; then
    echo "secret-scan: $FINDINGS finding(s) — FAIL"
    exit 1
else
    echo "secret-scan: clean — PASS"
    exit 0
fi
