/**
 * Layer 1: File Extension Red Flags
 * Detects dangerous files that should not be in a repository
 */

import type { Vulnerability, VulnerabilitySeverity } from '../../shared/types'
import type { ParsedFile } from '../../shared/parsed-file'
import { isToolingDirectory } from '../../parse/file-classifier'

const BASE_CONFIDENCE = 0.60

// Dangerous file extensions and names that should not be committed
const DANGEROUS_FILE_PATTERNS = [
  // Private keys
  { pattern: /\.pem$/i, name: 'PEM Private Key', severity: 'critical' as const },
  { pattern: /\.key$/i, name: 'Private Key File', severity: 'critical' as const },
  { pattern: /\.p12$/i, name: 'PKCS#12 Certificate', severity: 'critical' as const },
  { pattern: /\.pfx$/i, name: 'PFX Certificate', severity: 'critical' as const },
  { pattern: /\.p8$/i, name: 'PKCS#8 Private Key', severity: 'critical' as const },
  
  // SSH keys
  { pattern: /id_rsa$/i, name: 'RSA SSH Private Key', severity: 'critical' as const },
  { pattern: /id_dsa$/i, name: 'DSA SSH Private Key', severity: 'critical' as const },
  { pattern: /id_ecdsa$/i, name: 'ECDSA SSH Private Key', severity: 'critical' as const },
  { pattern: /id_ed25519$/i, name: 'Ed25519 SSH Private Key', severity: 'critical' as const },
  
  // Environment files (should be gitignored)
  { pattern: /^\.env$/i, name: 'Environment File', severity: 'critical' as const },
  { pattern: /^\.env\.local$/i, name: 'Local Environment File', severity: 'critical' as const },
  { pattern: /^\.env\.production$/i, name: 'Production Environment File', severity: 'critical' as const },
  { pattern: /^\.env\.development$/i, name: 'Development Environment File', severity: 'high' as const },
  { pattern: /^\.env\.staging$/i, name: 'Staging Environment File', severity: 'high' as const },
  
  // Credential files
  { pattern: /\.pgpass$/i, name: 'PostgreSQL Password File', severity: 'critical' as const },
  { pattern: /\.npmrc$/i, name: 'NPM Configuration (may contain tokens)', severity: 'high' as const },
  { pattern: /\.pypirc$/i, name: 'PyPI Configuration (may contain tokens)', severity: 'high' as const },
  { pattern: /\.netrc$/i, name: 'Netrc File (contains credentials)', severity: 'critical' as const },
  { pattern: /\.htpasswd$/i, name: 'Apache Password File', severity: 'critical' as const },
  
  // Database files
  { pattern: /\.sqlite$/i, name: 'SQLite Database', severity: 'medium' as const },
  { pattern: /\.sqlite3$/i, name: 'SQLite Database', severity: 'medium' as const },
  { pattern: /\.db$/i, name: 'Database File', severity: 'medium' as const },
  
  // Backup files that may contain secrets
  { pattern: /\.bak$/i, name: 'Backup File', severity: 'low' as const },
  { pattern: /\.backup$/i, name: 'Backup File', severity: 'low' as const },
  { pattern: /\.old$/i, name: 'Old File Backup', severity: 'low' as const },
  
  // Keystore files
  { pattern: /\.jks$/i, name: 'Java Keystore', severity: 'high' as const },
  { pattern: /\.keystore$/i, name: 'Keystore File', severity: 'high' as const },
]

// Files that are okay in certain contexts but should be reviewed
const CONTEXT_SENSITIVE_PATTERNS = [
  { pattern: /\.env\.example$/i, name: 'Environment Example File', checkContent: true },
  { pattern: /\.env\.sample$/i, name: 'Environment Sample File', checkContent: true },
  { pattern: /\.env\.template$/i, name: 'Environment Template File', checkContent: true },
]

export function detectDangerousFiles(
  content: string,
  filePath: string,
  options?: { parsed?: ParsedFile }
): Vulnerability[] {
  const vulnerabilities: Vulnerability[] = []
  const fileName = filePath.split('/').pop() || ''

  // Check for dangerous file patterns
  const inToolingDir = isToolingDirectory(filePath)

  for (const { pattern, name, severity } of DANGEROUS_FILE_PATTERNS) {
    if (pattern.test(fileName) || pattern.test(filePath)) {
      // Downgrade severity to 'info' for files in tooling directories
      // These are typically build scripts, CLI tools, etc. where certain file patterns are expected
      const effectiveSeverity: VulnerabilitySeverity = inToolingDir ? 'info' : severity

      vulnerabilities.push({
        id: `file-flag-${filePath}`,
        filePath,
        lineNumber: 1,
        lineContent: `File: ${fileName}`,
        severity: effectiveSeverity,
        category: 'dangerous_file',
        title: `Dangerous file detected: ${name}`,
        description: inToolingDir
          ? `This file type (${name}) is in a tooling/scripts directory and may be expected there. Review to ensure no actual secrets are committed.`
          : `This file type (${name}) should not be committed to version control as it may contain sensitive information.`,
        suggestedFix: 'Add this file to .gitignore and remove it from the repository. If it contains secrets, rotate them immediately.',
        confidence: inToolingDir ? 'medium' : 'high',
        baseConfidence: BASE_CONFIDENCE,
        layer: 1,
        source: 'config' as const,
      })
    }
  }

  // Check context-sensitive files for actual secrets
  for (const { pattern, name, checkContent } of CONTEXT_SENSITIVE_PATTERNS) {
    if ((pattern.test(fileName) || pattern.test(filePath)) && checkContent) {
      // Check if the example/sample file contains what looks like real values
      const suspiciousPatterns = [
        /[a-zA-Z0-9_]+=sk-[a-zA-Z0-9]{20,}/,  // API keys
        /[a-zA-Z0-9_]+=ghp_[a-zA-Z0-9]{36,}/, // GitHub tokens
        /[a-zA-Z0-9_]+=eyJ[a-zA-Z0-9_-]+\./,  // JWT tokens
        /password\s*=\s*[^\s$]{8,}/i,          // Passwords (not env vars)
      ]

      const lines = options?.parsed?.lines ?? content.split('\n')
      for (let i = 0; i < lines.length; i++) {
        const line = lines[i]
        // Skip lines that reference environment variables
        if (line.includes('${') || line.includes('$env:') || line.includes('process.env')) {
          continue
        }
        
        for (const suspicious of suspiciousPatterns) {
          if (suspicious.test(line)) {
            vulnerabilities.push({
              id: `file-flag-content-${filePath}-${i + 1}`,
              filePath,
              lineNumber: i + 1,
              lineContent: line.trim(),
              severity: 'high',
              category: 'dangerous_file',
              title: `${name} may contain real secrets`,
              description: 'This example/sample file appears to contain real secret values instead of placeholders.',
              suggestedFix: 'Replace real values with placeholders like YOUR_API_KEY_HERE or use environment variable references.',
              confidence: 'medium',
              baseConfidence: BASE_CONFIDENCE,
              layer: 1,
        source: 'config' as const,
            })
            break
          }
        }
      }
    }
  }

  return vulnerabilities
}
