#!/usr/bin/env bash
#
# Blocks commits that introduce obvious secrets (Azure keys, connection strings, private keys, etc.).
# This scans only staged changes (the git index) to avoid false positives from unstaged work.
#
# Note: Avoid printing matched lines to keep secrets out of terminal scrollback/logs.

set -euo pipefail

ROOT="$(git rev-parse --show-toplevel 2>/dev/null || true)"
if [[ -z "${ROOT}" ]]; then
  exit 0
fi

cd "${ROOT}"

# Nothing staged -> nothing to scan.
if git diff --cached --quiet; then
  exit 0
fi

DIFF="$(git diff --cached --no-color --unified=0)"
if [[ -z "${DIFF}" ]]; then
  exit 0
fi

perl -ne '
  our ($file, %hits, $exit);

  if (/^\+\+\+ b\/(.*)$/) {
    $file = $1;
    next;
  }

  next unless defined $file;
  next unless /^\+(?!\+\+\+)(.*)$/;
  my $line = $1;

  my @checks = (
    ["PRIVATE_KEY_BLOCK", qr/-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----/i],

    # Azure connection strings / keys (high signal, low false positives)
    ["AZURE_STORAGE_ACCOUNT_KEY", qr/AccountKey=[A-Za-z0-9+\/=_-]{20,}/],
    ["AZURE_SHARED_ACCESS_KEY", qr/SharedAccessKey=[A-Za-z0-9+\/=_-]{20,}/],

    # Common env var leaks
    ["COSMOS_KEY_ASSIGNMENT", qr/\bCOSMOS_KEY\s*=\s*[A-Za-z0-9+\/=_-]{20,}/],
    ["AZURE_OPENAI_KEY_ASSIGNMENT", qr/\bAZURE_OPENAI_KEY\s*=\s*[A-Za-z0-9+\/=_-]{20,}/],
    ["AZURE_SPEECH_KEY_ASSIGNMENT", qr/\bAZURE_SPEECH_KEY\s*=\s*[A-Za-z0-9+\/=_-]{20,}/],
    ["JWT_SECRET_HEX_ASSIGNMENT", qr/\bJWT_SECRET\s*=\s*[0-9a-fA-F]{32,}\b/],

    # OpenAI / Stripe / Perplexity
    ["OPENAI_API_KEY", qr/\bOPENAI_API_KEY\s*=\s*sk-[A-Za-z0-9]{20,}/],
    ["OPENAI_KEY_LIKE", qr/\bsk-[A-Za-z0-9]{20,}\b/],
    ["STRIPE_SECRET_KEY", qr/\bsk_(?:live|test)_[A-Za-z0-9]{20,}\b/],
    ["STRIPE_WEBHOOK_SECRET", qr/\bwhsec_[A-Za-z0-9]{20,}\b/],
    ["PERPLEXITY_API_KEY", qr/\bpplx-[A-Za-z0-9]{20,}\b/],

    # Cloud provider patterns
    ["AWS_ACCESS_KEY_ID", qr/\bAKIA[0-9A-Z]{16}\b/],
    ["GOOGLE_API_KEY", qr/\bAIza[0-9A-Za-z\-_]{35}\b/],
  );

  for my $check (@checks) {
    my ($name, $re) = @$check;
    if ($line =~ $re) {
      $hits{$name}{$file} = 1;
      $exit = 1;
    }
  }

  END {
    if (!$exit) {
      exit 0;
    }

    print STDERR "✗ Potential secrets detected in staged changes:\n";
    for my $name (sort keys %hits) {
      for my $path (sort keys %{ $hits{$name} }) {
        print STDERR "  - ${name}: ${path}\n";
      }
    }
    print STDERR "\nCommit aborted.\n";
    print STDERR "Move secrets to Azure Key Vault (or env vars injected at deploy-time), then retry.\n";
    print STDERR "If you believe this is a false positive, refactor the value into a placeholder.\n";
    exit 1;
  }
' <<< "${DIFF}"

