"""
Bartholomew Native Pre-Commit Secret Scanner
============================================
Intercepts unmasked API keys, tokens, and private credentials in staged git changes.
Blocks git commit if any real secret pattern or high-entropy key is detected.
"""

import sys
import subprocess
import re

SECRET_PATTERNS = [
    (re.compile(r"\bgh[opusr]_[a-zA-Z0-9]{20,}\b", re.IGNORECASE), "GitHub Access Token (ghp_/gho_/ghs_)"),
    (re.compile(r"\bgithub_pat_[a-zA-Z0-9]{22,}\b"), "GitHub Fine-Grained Token (github_pat_)"),
    (re.compile(r"AKIA[0-9A-Z]{16}"), "AWS Access Key ID (AKIA)"),
    (re.compile(r"sk-(proj|live|test)-[a-zA-Z0-9]{20,}"), "OpenAI / Stripe Secret Key (sk-)"),
    (re.compile(r"whsec_[a-zA-Z0-9]{20,}"), "Stripe Webhook Secret (whsec_)"),
    (re.compile(r"-----BEGIN\s+([A-Z0-9_-]+\s+)?PRIVATE\s+KEY-----", re.IGNORECASE), "Private Cryptographic Key PEM"),
    (re.compile(r"npm_[a-zA-Z0-9]{36}"), "npm Access Token (npm_)"),
    (re.compile(r"pypi-[a-zA-Z0-9_-]{50,}"), "PyPI API Token (pypi-)")
]

# Allow mock test samples explicitly
SAFE_MOCK_ALLOWLIST = [
    "AKIA_MOCK_TEST",
    "AKIAIOSFODNN7EXAMPLE",
    "sk-proj-00000000",
    "ghp_MOCK_TEST_TOKEN",
    "sk_live_YOUR_STRIPE",
    "scripts/deep_security_audit.py",
    "npm_package/test.js",
    "npm_package/cli.js",
    "npm_package/bin/cli.js"
]

def scan_staged_diff():
    try:
        diff_output = subprocess.check_output(
            ["git", "diff", "--cached", "-U0"],
            stderr=subprocess.STDOUT,
            text=True,
            encoding="utf-8",
            errors="ignore"
        )
    except Exception as e:
        print(f"[!] Warning: Could not run git diff: {e}")
        return 0

    violations = []
    current_file = "Unknown"

    for line in diff_output.splitlines():
        if line.startswith("+++ b/"):
            current_file = line[6:]
            continue

        # Skip test and demo simulation files
        if any(ignored in current_file for ignored in ["deep_security_audit.py", "test_", "demo_", "cli.js"]):
            continue

        # Only scan newly added or modified lines
        if line.startswith("+") and not line.startswith("+++"):
            content = line[1:]

            # Skip allowed mock tokens
            if any(mock in content for mock in SAFE_MOCK_ALLOWLIST):
                continue

            for pattern, desc in SECRET_PATTERNS:
                match = pattern.search(content)
                if match:
                    violations.append({
                        "file": current_file,
                        "secret_type": desc,
                        "snippet": content.strip()[:60] + "..."
                    })

    if violations:
        print("=" * 80)
        print("[!] BARTHOLOMEW PRE-COMMIT GATE: COMMIT ABORTED (SECRET LEAK DETECTED)")
        print("=" * 80)
        for v in violations:
            print(f"  [VIOLATION] File:        {v['file']}")
            print(f"              Secret Type: {v['secret_type']}")
            print(f"              Preview:     {v['snippet']}")
            print("-" * 80)
        print("To protect your account, Bartholomew prevented this commit from being saved.")
        print("Please sanitize the file or move private keys to .env before committing.")
        print("=" * 80)
        return 1

    return 0

if __name__ == "__main__":
    sys.exit(scan_staged_diff())
