"""Secret detection patterns."""

import re

# AWS Access Key
AWS_ACCESS_KEY = re.compile(r"AKIA[0-9A-Z]{16}")

# AWS Secret Key (40 alphanumeric characters)
AWS_SECRET_KEY = re.compile(r"(?:aws_secret_access_key\s*=\s*['\"]?)([A-Za-z0-9/+=]{40})(?:['\"]?)")

# GitHub Token
GITHUB_TOKEN = re.compile(r"gh[pousr]_[A-Za-z0-9]{36}")

# Slack Token
SLACK_TOKEN = re.compile(r"xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[A-Za-z0-9]{24,32}")

# Stripe API Key
STRIPE_KEY = re.compile(r"sk_(?:live|test)_[0-9a-zA-Z]{24,}")

# Google API Key
GOOGLE_API_KEY = re.compile(r"AIza[0-9A-Za-z\\-_]{35}")

# Twilio API Key
TWILIO_KEY = re.compile(r"SK[a-f0-9]{32}")

# SendGrid API Key
SENDGRID_KEY = re.compile(r"SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}")

# Mailgun API Key
MAILGUN_KEY = re.compile(r"key-[a-f0-9]{32}")

# JWT Token (basic pattern)
JWT_TOKEN = re.compile(r"eyJ[A-Za-z0-9_-]*\.eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]*")

# Generic password patterns in code
PASSWORD_ASSIGNMENT = re.compile(
    r"(?:password|passwd|pwd|pass)\s*[=:]\s*['\"]([^'\"]{8,})['\"]",
    re.IGNORECASE
)

# API key patterns in code
API_KEY_ASSIGNMENT = re.compile(
    r"(?:api[_-]?key|apikey|api[_-]?secret)\s*[=:]\s*['\"]([^'\"]{16,})['\"]",
    re.IGNORECASE
)

# Database connection strings
DB_CONNECTION = re.compile(
    r"(?:mysql|postgresql|mongodb)://[^:]+:([^@]+)@",
    re.IGNORECASE
)

# Private keys
PRIVATE_KEY = re.compile(
    r"-----BEGIN (?:RSA |EC )?PRIVATE KEY-----"
)

# Secret key patterns (common in config files)
SECRET_KEY_ASSIGNMENT = re.compile(
    r"(?:secret[_-]?key|secret[_-]?token)\s*[=:]\s*['\"]([^'\"]{16,})['\"]",
    re.IGNORECASE
)


# Pattern categories with severity
SECRET_PATTERNS = {
    "AWS Access Key": (AWS_ACCESS_KEY, "CRITICAL"),
    "AWS Secret Key": (AWS_SECRET_KEY, "CRITICAL"),
    "GitHub Token": (GITHUB_TOKEN, "CRITICAL"),
    "Slack Token": (SLACK_TOKEN, "HIGH"),
    "Stripe API Key": (STRIPE_KEY, "CRITICAL"),
    "Google API Key": (GOOGLE_API_KEY, "HIGH"),
    "Twilio API Key": (TWILIO_KEY, "HIGH"),
    "SendGrid API Key": (SENDGRID_KEY, "HIGH"),
    "Mailgun API Key": (MAILGUN_KEY, "HIGH"),
    "JWT Token": (JWT_TOKEN, "MEDIUM"),
    "Password Assignment": (PASSWORD_ASSIGNMENT, "HIGH"),
    "API Key Assignment": (API_KEY_ASSIGNMENT, "HIGH"),
    "Database Connection": (DB_CONNECTION, "CRITICAL"),
    "Private Key": (PRIVATE_KEY, "CRITICAL"),
    "Secret Key Assignment": (SECRET_KEY_ASSIGNMENT, "HIGH"),
}


# Known test/placeholder values that should be ignored
KNOWN_PLACEHOLDERS = {
    "your-api-key-here",
    "YOUR_API_KEY",
    "YOUR_SECRET_KEY",
    "REPLACE_ME",
    "CHANGEME",
    "CHANGE_THIS",
    "example.com",
    "test@example.com",
    "password",
    "secret",
    "admin",
    "12345678",
    "xxxxxxxx",
}


def is_placeholder(value: str) -> bool:
    """Check if a value looks like a placeholder."""
    value_upper = value.upper()

    # Check against known placeholders
    if value_upper in {p.upper() for p in KNOWN_PLACEHOLDERS}:
        return True

    # Check for common placeholder patterns
    if "XXXX" in value_upper:
        return True
    if "YOUR" in value_upper and ("KEY" in value_upper or "SECRET" in value_upper or "PASSWORD" in value_upper):
        return True
    if value_upper.startswith("REPLACE") or value_upper.startswith("CHANGE"):
        return True
    if value == "=" * len(value):  # All equal signs
        return True
    if value == "*" * len(value):  # All asterisks
        return True
    if "_HERE" in value_upper or "-HERE" in value_upper:  # Common placeholder suffix
        return True

    return False
