/**
 * Request Body Validation Detection
 *
 * Detection logic for request.json() / req.json() usage without
 * proper schema validation.
 */

import type { Vulnerability } from '../../../shared/types'
import { isComment } from '../../../parse/file-classifier'
import { hasManualValidation } from './utils/schema-validation'
import { hasThrowingAuthHelper } from './utils/helpers'

const BASE_CONFIDENCE = 0.35

/**
 * Detect request.json() / req.json() and suggest schema validation
 * This is NOT a dangerous function - it's a prompt for best practices
 */
export function detectRequestJsonValidation(
  content: string,
  filePath: string,
  isTestFile: boolean,
  vulnerabilities: Vulnerability[]
): void {
  // Only check API route files
  if (
    !/\/(api|routes?|handlers?|controllers?)\//i.test(filePath) &&
    !/route\.(ts|js)$/i.test(filePath)
  ) {
    return
  }

  // Skip if route has throwing auth helper - these are already protected routes
  // and the schema validation suggestion is lower priority
  if (hasThrowingAuthHelper(content)) {
    return
  }

  const lines = content.split('\n')
  // Matches: request.json(), req.json(), await request.json(), etc.
  const requestJsonPattern = /\b(request|req)\.json\s*\(\s*\)/gi

  // Check if file has schema validation (library-based)
  const hasSchemaLibrary =
    /\b(zod|yup|joi|ajv|superstruct|valibot|typebox)\b/i.test(content) ||
    /\.parse\s*\(|\.validate\s*\(|\.safeParse\s*\(/i.test(content)

  // If file has schema library validation, don't report
  if (hasSchemaLibrary) return

  // Check for manual validation patterns (less robust but still indicates intent)
  const hasManualCheck = hasManualValidation(content)

  // Track instances for potential aggregation
  const instances: { lineNumber: number; lineContent: string }[] = []

  lines.forEach((line, index) => {
    if (isComment(line)) return

    requestJsonPattern.lastIndex = 0
    if (!requestJsonPattern.test(line)) return

    // Check if there's validation nearby (within 10 lines after)
    const startCheck = index
    const endCheck = Math.min(lines.length, index + 10)
    const nearbyContent = lines.slice(startCheck, endCheck).join('\n')

    // If there's validation in the nearby lines, skip
    if (
      /\.parse\s*\(|\.validate\s*\(|\.safeParse\s*\(|schema\./i.test(
        nearbyContent
      )
    ) {
      return
    }

    // If manual validation is present, skip individual reporting but track for aggregate
    if (hasManualCheck) {
      instances.push({ lineNumber: index + 1, lineContent: line.trim() })
      return
    }

    if (isTestFile) {
      return // Don't report in test files
    }

    instances.push({ lineNumber: index + 1, lineContent: line.trim() })
  })

  // Don't report if no instances found
  if (instances.length === 0) return

  // If manual validation exists, create a single info-level note
  if (hasManualCheck && instances.length > 0) {
    vulnerabilities.push({
      id: `request-json-manual-${filePath}`,
      filePath,
      lineNumber: instances[0].lineNumber,
      lineContent: instances[0].lineContent,
      severity: 'info',
      category: 'dangerous_function',
      title: 'Request body with manual validation',
      description: `API endpoint parses request body with manual validation patterns detected. Consider using a schema library (zod, yup) for more robust type-safe validation.`,
      suggestedFix:
        'While manual validation works, schema libraries provide better TypeScript integration and error messages.',
      confidence: 'low',
      baseConfidence: BASE_CONFIDENCE,
      layer: 2,
        source: 'structural' as const,
    })
    return
  }

  // Aggregate if multiple instances without validation
  if (instances.length >= 2) {
    const lineNumbers = instances.map(i => i.lineNumber).slice(0, 5)
    vulnerabilities.push({
      id: `request-json-aggregated-${filePath}`,
      filePath,
      lineNumber: instances[0].lineNumber,
      lineContent: `${instances.length} instances`,
      severity: 'info',
      category: 'dangerous_function',
      title: `Request body without schema validation (${instances.length} instances)`,
      description: `API endpoint parses request body without visible schema validation at lines: ${lineNumbers.join(', ')}. Consider validating the shape of incoming data.`,
      suggestedFix:
        'Add schema validation (e.g., zod): const body = await request.json(); const data = schema.parse(body);',
      confidence: 'low',
      baseConfidence: BASE_CONFIDENCE,
      layer: 2,
        source: 'structural' as const,
    })
  } else {
    // Single instance
    vulnerabilities.push({
      id: `request-json-${filePath}-${instances[0].lineNumber}`,
      filePath,
      lineNumber: instances[0].lineNumber,
      lineContent: instances[0].lineContent,
      severity: 'info',
      category: 'dangerous_function',
      title: 'Request body without schema validation',
      description:
        'API endpoint parses request body without visible schema validation. Consider validating the shape of incoming data.',
      suggestedFix:
        'Add schema validation (e.g., zod): const body = await request.json(); const data = schema.parse(body);',
      confidence: 'low',
      baseConfidence: BASE_CONFIDENCE,
      layer: 2,
        source: 'structural' as const,
    })
  }
}
