/**
 * Cursor IDE Integration
 * Generates .cursor/rules/security.mdc format
 */

import type { ScanResult, Vulnerability } from '../../../shared/types'
import { sortBySeverity } from '../grouping'

/**
 * Extract unique directory paths from vulnerabilities for glob patterns
 */
function extractGlobPatterns(vulnerabilities: Vulnerability[]): string[] {
  const directories = new Set<string>()

  for (const vuln of vulnerabilities) {
    // Get directory path (e.g., 'src/api' from 'src/api/users.ts')
    const parts = vuln.filePath.split('/')
    if (parts.length > 1) {
      // Take up to 2 levels of directory
      const dir = parts.slice(0, Math.min(parts.length - 1, 2)).join('/')
      directories.add(`${dir}/**`)
    }
  }

  return Array.from(directories).sort()
}

/**
 * Format fix pattern (DO NOT / DO) for a vulnerability
 */
function formatFixPattern(vuln: Vulnerability): string {
  const category = vuln.category
  let md = ''

  // Common patterns by category
  switch (category) {
    case 'sql_injection':
      md += `**DO NOT** concatenate user input into SQL queries.\n\n`
      md += `\`\`\`typescript\n// BAD\nconst query = \`SELECT * FROM users WHERE id = \${userId}\`\n\n// GOOD\nconst query = 'SELECT * FROM users WHERE id = ?'\n\`\`\`\n`
      break

    case 'xss':
      md += `**DO NOT** insert user input into HTML without escaping.\n\n`
      md += `\`\`\`typescript\n// BAD\nelement.innerHTML = userInput\n\n// GOOD\nelement.textContent = userInput\n\`\`\`\n`
      break

    case 'hardcoded_secret':
    case 'high_entropy_string':
      md += `**DO NOT** hardcode secrets or API keys in source code.\n\n`
      md += `\`\`\`typescript\n// BAD\nconst apiKey = 'sk-abc123...'\n\n// GOOD\nconst apiKey = process.env.API_KEY\n\`\`\`\n`
      break

    case 'missing_auth':
      md += `**DO NOT** expose endpoints without authentication.\n\n`
      md += `\`\`\`typescript\n// BAD\napp.get('/api/data', handler)\n\n// GOOD\napp.get('/api/data', authMiddleware, handler)\n\`\`\`\n`
      break

    case 'dangerous_function':
      md += `**DO NOT** use eval() or similar dangerous functions with user input.\n\n`
      md += `\`\`\`typescript\n// BAD\neval(userInput)\n\n// GOOD\nJSON.parse(userInput)\n\`\`\`\n`
      break

    default:
      // Generic fix pattern
      if (vuln.fixSteps && vuln.fixSteps.length > 0) {
        md += `**FIX:**\n`
        vuln.fixSteps.forEach((step, i) => {
          md += `${i + 1}. ${step}\n`
        })
      } else if (vuln.suggestedFix) {
        md += `**FIX:** ${vuln.suggestedFix}\n`
      }
  }

  return md
}

/**
 * Format scan result as Cursor MDC rules
 *
 * @param result - The scan result to format
 * @returns MDC format string for .cursor/rules/security.mdc
 */
export function formatCursorRules(result: ScanResult): string {
  const { vulnerabilities, timestamp } = result

  // Sort by severity
  const sorted = sortBySeverity(vulnerabilities)

  // Extract glob patterns
  const globs = extractGlobPatterns(sorted)

  let md = ''

  // MDC Frontmatter
  md += `---\n`
  md += `description: Oculum Security Findings\n`
  if (globs.length > 0) {
    md += `globs: "${globs.join(',')}"\n`
  }
  md += `alwaysApply: false\n`
  md += `---\n\n`

  // No findings case
  if (vulnerabilities.length === 0) {
    md += `# Security Scan Results\n\n`
    md += `No security issues found. Last scan: ${timestamp}\n\n`
    md += `*Run \`oculum scan --cursor --clear\` to remove this file.*\n`
    return md
  }

  // Header
  md += `# Security Issues (${vulnerabilities.length})\n\n`
  md += `> Last scan: ${timestamp}\n\n`

  // Group by severity
  const bySeverity = new Map<string, Vulnerability[]>()
  for (const vuln of sorted) {
    const group = bySeverity.get(vuln.severity) || []
    group.push(vuln)
    bySeverity.set(vuln.severity, group)
  }

  // Output by severity
  for (const [severity, vulns] of bySeverity) {
    md += `## ${severity.toUpperCase()} (${vulns.length})\n\n`

    for (const vuln of vulns.slice(0, 10)) {
      md += `### ${vuln.title}\n\n`
      md += `**File:** \`${vuln.filePath}:${vuln.lineNumber}\`\n\n`

      // Add fix pattern
      md += formatFixPattern(vuln)
      md += '\n'
    }

    if (vulns.length > 10) {
      md += `> + ${vulns.length - 10} more ${severity} issues\n\n`
    }
  }

  // Footer
  md += `---\n\n`
  md += `*Run \`oculum scan --cursor --clear\` after fixing to remove this file.*\n`

  return md
}
