/**
 * Comment Analyzer Utility
 * Analyzes comment INTENTION - distinguishing explanatory comments from disabled code
 *
 * This addresses false positives where comments describing auth checks are flagged
 * as "disabled authentication" when they're actually explaining the code that follows.
 *
 * Key insight: A comment before active code is EXPLANATORY, not disabled code.
 * Only flag comments when:
 * 1. The comment is followed by MORE commented code (disabled code block)
 * 2. The comment matches explicit disable patterns (TODO: add auth, FIXME: needs auth)
 */

export interface CommentAnalysis {
  /** Type of comment based on context */
  type: 'explanatory' | 'disabled_code' | 'todo_fixme' | 'unknown'
  /** Whether this comment represents a security concern */
  isSecurityRelevant: boolean
  /** Optional reason for the classification */
  reason?: string
}

/**
 * Patterns that explicitly indicate missing/disabled security
 * These are genuine concerns even in isolation
 */
const EXPLICIT_DISABLE_PATTERNS = [
  // Explicit disable statements
  /\/\/\s*(auth|authentication|authorization)\s+(check\s+)?(disabled|removed|skipped)/i,
  /\/\/\s*(skip|bypass|disable)\s+(auth|authentication|authorization)/i,
  /\/\/\s*no\s+auth\s*(required|needed|check)?/i,

  // TODO/FIXME patterns indicating missing security
  /\/\/\s*TODO:?\s*(add|implement|enable)\s+(auth|authentication|authorization|security)/i,
  /\/\/\s*FIXME:?\s*(add|implement|enable|missing)\s+(auth|authentication|authorization)/i,
  /\/\/\s*HACK:?\s*(no|skip|bypass)\s+(auth|authentication)/i,

  // Temporary bypass patterns
  /\/\/\s*(temporarily?|temp)\s+(disabled?|removed?|skipped?)\s+(auth|authentication)/i,
  /\/\/\s*(for\s+)?test(ing)?\s*(only)?:?\s*(skip|no|disable)\s+auth/i,
]

/**
 * Auth-related keywords that might appear in comments
 * Used to detect if a comment is about authentication/authorization
 */
const AUTH_KEYWORDS = [
  'auth',
  'authentication',
  'authorization',
  'permission',
  'verify',
  'check',
  'validate',
  'ensure',
  'require',
  'protect',
  'guard',
  'secure',
  'token',
  'session',
  'credential',
]

/**
 * Patterns indicating active auth implementation in code
 */
const AUTH_IMPLEMENTATION_PATTERNS = [
  /\bawait\s+auth\(/i,
  /\bassert[A-Z]\w*Auth/i,
  /\bverify[A-Z]\w*/i,
  /\bcheck[A-Z]\w*Permission/i,
  /\brequire[A-Z]\w*Auth/i,
  /\bensure[A-Z]\w*Auth/i,
  /\bgetServerSession/i,
  /\bcurrentUser/i,
  /\bgetCurrentUser/i,
  /\bvalidate[A-Z]\w*Token/i,
  /\bisAuthenticated/i,
  /\bhasPermission/i,
  /\bhasRole/i,
  /\.protect\(/i,
  /\.authorize\(/i,
]

/**
 * Check if a line is a comment
 */
function isCommentLine(line: string): boolean {
  const trimmed = line.trim()
  return (
    trimmed.startsWith('//') ||
    trimmed.startsWith('#') ||
    trimmed.startsWith('*') ||
    trimmed.startsWith('/*')
  )
}

/**
 * Check if a line is empty or whitespace only
 */
function isEmptyLine(line: string): boolean {
  return line.trim().length === 0
}

/**
 * Check if comment contains auth-related keywords
 */
function hasAuthKeyword(line: string): boolean {
  const lowerLine = line.toLowerCase()
  return AUTH_KEYWORDS.some(keyword => lowerLine.includes(keyword))
}

/**
 * Check if a line contains active auth implementation
 */
function hasAuthImplementation(line: string): boolean {
  return AUTH_IMPLEMENTATION_PATTERNS.some(pattern => pattern.test(line))
}

/**
 * Analyze the INTENTION of a comment at a specific line
 *
 * @param lines - Array of all lines in the file
 * @param commentLineIndex - The 0-indexed line number of the comment to analyze
 * @returns CommentAnalysis with type and security relevance
 */
export function analyzeCommentIntention(
  lines: string[],
  commentLineIndex: number
): CommentAnalysis {
  const commentLine = lines[commentLineIndex]

  if (!commentLine || !isCommentLine(commentLine)) {
    return { type: 'unknown', isSecurityRelevant: false }
  }

  // PRIORITY 1: Check for explicit disable patterns (always a concern)
  if (EXPLICIT_DISABLE_PATTERNS.some(pattern => pattern.test(commentLine))) {
    return {
      type: 'todo_fixme',
      isSecurityRelevant: true,
      reason: 'Comment explicitly indicates disabled or missing security',
    }
  }

  // Check if this comment mentions auth-related keywords
  if (!hasAuthKeyword(commentLine)) {
    // Comment doesn't mention auth - not relevant to auth detection
    return { type: 'unknown', isSecurityRelevant: false }
  }

  // PRIORITY 2: Check if next non-empty line is also a comment (disabled code block)
  let nextLineIndex = commentLineIndex + 1
  while (nextLineIndex < lines.length && isEmptyLine(lines[nextLineIndex])) {
    nextLineIndex++
  }

  if (nextLineIndex < lines.length) {
    const nextLine = lines[nextLineIndex]

    // If next line is also a comment, this might be a disabled code block
    if (isCommentLine(nextLine)) {
      // Check if the commented-out code looks like auth implementation
      // e.g., "// await verifyAuth()" or "// if (!session) return"
      if (hasAuthImplementation(nextLine) || /\/\/\s*(if|await|return|const|let)\s/.test(nextLine)) {
        return {
          type: 'disabled_code',
          isSecurityRelevant: true,
          reason: 'Comment followed by commented-out code that appears to be auth logic',
        }
      }

      // Multiple consecutive comments without code - could be docs or disabled block
      // Check deeper
      let consecutiveComments = 1
      let foundCodeComment = false
      for (let i = nextLineIndex; i < Math.min(nextLineIndex + 5, lines.length); i++) {
        if (isEmptyLine(lines[i])) continue
        if (isCommentLine(lines[i])) {
          consecutiveComments++
          if (hasAuthImplementation(lines[i]) || /\/\/\s*(if|await|return|const|let)\s/.test(lines[i])) {
            foundCodeComment = true
          }
        } else {
          break
        }
      }

      if (foundCodeComment) {
        return {
          type: 'disabled_code',
          isSecurityRelevant: true,
          reason: 'Block of commented-out code containing auth logic',
        }
      }
    }

    // PRIORITY 3: Check if next line is ACTIVE auth implementation
    // This means the comment is EXPLAINING the auth check, not disabling it
    if (!isCommentLine(nextLine) && hasAuthImplementation(nextLine)) {
      return {
        type: 'explanatory',
        isSecurityRelevant: false,
        reason: 'Comment describes the auth check that follows',
      }
    }

    // Check slightly further - the implementation might be 1-2 lines after
    for (let i = nextLineIndex; i < Math.min(nextLineIndex + 3, lines.length); i++) {
      const line = lines[i]
      if (isEmptyLine(line)) continue
      if (isCommentLine(line)) continue

      if (hasAuthImplementation(line)) {
        return {
          type: 'explanatory',
          isSecurityRelevant: false,
          reason: 'Comment describes nearby auth implementation',
        }
      }
      break // Stop at first non-comment, non-empty line
    }
  }

  // Default: auth-related comment without clear context
  // Be conservative - don't flag unless we're confident it's disabled code
  return {
    type: 'unknown',
    isSecurityRelevant: false,
    reason: 'Auth-related comment but no clear indication of disabled code',
  }
}

/**
 * Check if a comment at a specific line indicates disabled authentication code
 * This is the main function to use for detection
 *
 * @param lines - Array of all lines in the file
 * @param lineIndex - The 0-indexed line number to check
 * @returns true if the comment indicates disabled/missing auth that should be flagged
 */
export function isDisabledAuthComment(
  lines: string[],
  lineIndex: number
): boolean {
  const analysis = analyzeCommentIntention(lines, lineIndex)
  return analysis.isSecurityRelevant && analysis.type !== 'explanatory'
}
