#!/usr/bin/env bash
set -euo pipefail

# ==============================================================================
# COMPREHENSIVE WORDPRESS PLUGIN VALIDATOR (STRICT/PARANOID MODE)
# ==============================================================================
# Validates WP plugins against strict security and coding standards.
# Flags ALL potential vulnerabilities for manual review.
# ==============================================================================

PLUGIN_DIR="${1:-}"

# Color codes
RED='\033[0;31m'
YELLOW='\033[1;33m'
GREEN='\033[0;32m'
BLUE='\033[0;34m'
MAGENTA='\033[0;35m'
NC='\033[0m'

ERROR_COUNT=0
WARN_COUNT=0

if [[ -z "${PLUGIN_DIR}" ]]; then
  echo "Usage: $(basename "$0") /path/to/plugin" >&2
  exit 1
fi

echo -e "${BLUE}========================================================${NC}"
echo -e "${BLUE}    STRICT WORDPRESS PLUGIN SECURITY & CODE AUDIT       ${NC}"
echo -e "${BLUE}========================================================${NC}"
echo "Scanning: ${PLUGIN_DIR}"
echo ""

mapfile -t php_files < <(find "${PLUGIN_DIR}" -type f -name "*.php" ! -path "*/vendor/*" ! -path "*/node_modules/*" 2>/dev/null | sort || true)

# Fallback to glob if mapfile fails or array is empty
if [[ ${#php_files[@]} -eq 0 ]] || [[ -z "${php_files[*]:-}" ]]; then
    IFS=$'\n' read -d '' -r -a php_files < <(find "${PLUGIN_DIR}" -type f -name "*.php" ! -path "*/vendor/*" ! -path "*/node_modules/*" 2>/dev/null | sort || true) || true
fi

if [[ "${#php_files[@]}" -eq 0 ]] || [[ -z "${php_files[*]:-}" ]]; then
  echo -e "${RED}✗ FATAL: No PHP files found.${NC}"
  exit 1
fi

# ============================================
# 1. FORBIDDEN FUNCTIONS (SECURITY)
# ============================================
echo -e "${MAGENTA}[1/11] Checking for Dangerous/Forbidden Functions...${NC}"

# List of dangerous functions that should rarely/never be used in WP plugins
FORBIDDEN_FUNCS=(
  "eval" "exec" "passthru" "shell_exec" "system" "proc_open" "popen"
  "curl_exec:Use wp_remote_get()" "file_get_contents:Use wp_remote_get()"
  "base64_decode:Suspicious obfuscation risk"
  "create_function:Deprecated and dangerous"
  "extract:Variable pollution risk"
  "assert:Deprecated in PHP 8"
  "preg_replace with /e:Use callback instead"
)

for file in "${php_files[@]}"; do
  for rule in "${FORBIDDEN_FUNCS[@]}"; do
    func="${rule%%:*}"
    reason="${rule##*:}"
    
    # We use a regex that looks for the function name followed by (
    if grep -nE "\b${func}\s*\(" "${file}" > /dev/null; then
       # Ignore benign usages if needed (e.g. file_get_contents on local file)
       # But for strict mode, we flag all.
       echo -e "${RED}  ✗ SECURITY RISK in ${file}:${NC}"
       echo "    Found forbidden function: '${func}'"
       if [[ "$reason" != "$func" ]]; then echo "    Reason: $reason"; fi
       grep -nE "\b${func}\s*\(" "${file}" | head -1
       ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
  done
done
echo ""

# ============================================
# 2. SQL INJECTION (STRICT)
# ============================================
echo -e "${MAGENTA}[2/11] Checking for SQL Injection Patterns...${NC}"

for file in "${php_files[@]}"; do
  # 2.1 Direct variable interpolation in query
  # Matches: $wpdb->query( "SELECT ... $var" ) or similar
  # This is a high-confidence SQLi pattern
  if grep -nE "\$wpdb->(query|get_results|get_row|get_var|get_col)\s*\(\s*[\"'].*\\$[a-zA-Z].*[\"']" "${file}"; then
     echo -e "${RED}  ✗ SQL INJECTION RISK in ${file}:${NC}"
     echo "    Variable directly interpolated into SQL string."
     echo "    MUST use \$wpdb->prepare()."
     ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  # 2.2 Missing prepare
  # Matches queries that look dynamic but lack 'prepare'
  if grep -q "\$wpdb->" "${file}"; then
    # If file has wpdb usage but NO prepare() call, and isn't just checking errors
    if ! grep -q "prepare" "${file}" && grep -qE "SELECT|INSERT|UPDATE|DELETE" "${file}"; then
       echo -e "${YELLOW}  ⚠ WARNING: SQL usage detected without \$wpdb->prepare() in ${file}.${NC}"
       echo "    Verify manual escaping is robust."
       WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi
done
echo ""

# ============================================
# 3. XSS & SANITIZATION (STRICT)
# ============================================
echo -e "${MAGENTA}[3/11] Checking for XSS & Input Sanitization...${NC}"

for file in "${php_files[@]}"; do
  # 3.1 Echoing superglobals directly
  if grep -nE "echo\s+.*(\\\$_GET|\\\$_POST|\\\$_REQUEST|\\\$_SERVER)" "${file}"; then
    echo -e "${RED}  ✗ XSS VULNERABILITY in ${file}:${NC}"
    echo "    Direct echo of superglobal detected. Must use esc_html / esc_attr."
    ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  # 3.2 Setting variables from input without sanitization (Paranoid Check)
  # Looks for $var = $_POST[...] without a sanitize_ function on the same line
  if grep -nE "\\\$[a-zA-Z0-9_]+\s*=\s*(\\\$_POST|\\\$_GET|\\\$_REQUEST)" "${file}" | grep -vE "sanitize_|absint|intval|esc_"; then
    echo -e "${YELLOW}  ⚠ UNSANITIZED INPUT in ${file}:${NC}"
    echo "    Raw input assigned to variable without immediate sanitization."
    grep -nE "\\\$[a-zA-Z0-9_]+\s*=\s*(\\\$_POST|\\\$_GET|\\\$_REQUEST)" "${file}" | head -1
    WARN_COUNT=$((WARN_COUNT + 1))
  fi

  # 3.3 Print/Echo without escaping functions (General Heuristic)
  # Flags lines like `echo $variable;` if $variable isn't obviously an object method
  # This produces noise, but ensures strictness.
  if grep -nE "(echo|print)\s+\\\$[a-zA-Z0-9_]+;" "${file}"; then
     # Simple variable echo - likely unsafe unless variable source is known trusted
     echo -e "${YELLOW}  ⚠ UNESCAPED OUTPUT in ${file}:${NC}"
     echo "    Printing variable without escaping function (esc_html, etc)."
     WARN_COUNT=$((WARN_COUNT + 1))
  fi
done
echo ""

# ============================================
# 4. NONCES & CAPABILITIES (CSRF/Auth)
# ============================================
echo -e "${MAGENTA}[4/11] Checking Nonces and Permissions...${NC}"

for file in "${php_files[@]}"; do
  # 4.1 Processing Form Data
  if grep -q "\$_POST" "${file}"; then
    # If file processes POST, it MUST have nonce verification
    if ! grep -qE "wp_verify_nonce|check_admin_referer|check_ajax_referer" "${file}"; then
       echo -e "${RED}  ✗ CSRF VULNERABILITY in ${file}:${NC}"
       echo "    File processes \$_POST but no nonce check found."
       ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
    
    # It SHOULD also have capability checks
    if ! grep -qE "current_user_can" "${file}"; then
       echo -e "${YELLOW}  ⚠ MISSING CAPABILITY CHECK in ${file}:${NC}"
       echo "    File processes \$_POST but 'current_user_can' not found."
       WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi
done
echo ""

# ============================================
# 5. PHP CODING STANDARDS (LINTING)
# ============================================
echo -e "${MAGENTA}[5/11] PHP Syntax & Standards...${NC}"

# 5.4 UNDEFINED ARRAY KEY DETECTION
echo -e "${MAGENTA}[5.4/11] Checking for Undefined Array Keys...${NC}"

for file in "${php_files[@]}"; do
  # 5.4.1 Direct array access without isset check on superglobals
  # Matches patterns like: $_POST['key'] or $_GET['key'] without preceding isset()
  UNSAFE_KEYS=$(grep -nE '\$_POST\[|\$_GET\[|\$_REQUEST\[|\$_COOKIE\[' "${file}" | grep -vB1 "isset\|array_key_exists" | grep -E '\$_POST\[|\$_GET\[|\$_REQUEST\[|\$_COOKIE\[' || true)
  if [ -n "$UNSAFE_KEYS" ]; then
     echo -e "${RED}  ✗ UNDEFINED ARRAY KEY RISK in ${file}:${NC}"
     echo "    Superglobal array access without isset()/array_key_exists() check."
     echo "    Lines with potential undefined key access:"
     echo "$UNSAFE_KEYS" | head -3
     ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  # 5.4.2 Array key access in expressions without isset check
  # Matches: $array['key'] or $array[$var] where key might not exist
  if grep -nE '\$[a-zA-Z_][a-zA-Z0-9_]*\[' "${file}" | grep -vB1 "isset\|array_key_exists\|foreach.*as.*=>" | grep -E '\$[a-zA-Z_][a-zA-Z0-9_]*\[' > /dev/null 2>&1; then
     echo -e "${YELLOW}  ⚠ POTENTIAL UNDEFINED ARRAY KEY in ${file}:${NC}"
     echo "    Array key access without isset() or array_key_exists() check."
     echo "    Consider using isset() or the null coalescing operator (??)"
     grep -nE '\$[a-zA-Z_][a-zA-Z0-9_]*\[' "${file}" | grep -vB1 "isset\|array_key_exists\|foreach.*as.*=>" | grep -E '\$[a-zA-Z_][a-zA-Z0-9_]*\[' | head -3
     WARN_COUNT=$((WARN_COUNT + 1))
  fi

  # 5.4.3 Multi-dimensional array access without validation
  # Matches: $array['key1']['key2'] which is risky without validation
  if grep -nE '\$[a-zA-Z_][a-zA-Z0-9_]*\[.*\]\[' "${file}" | grep -vB1 "isset\|array_key_exists" | head -1 > /dev/null 2>&1; then
     echo -e "${YELLOW}  ⚠ MULTI-DIMENSIONAL ARRAY ACCESS in ${file}:${NC}"
     echo "    Multi-dimensional array access without validation."
     grep -nE '\$[a-zA-Z_][a-zA-Z0-9_]*\[.*\]\[' "${file}" | grep -vB1 "isset\|array_key_exists" | head -1
     WARN_COUNT=$((WARN_COUNT + 1))
  fi

  # 5.4.4 Array access in assignment without check
  # Matches: $var = $_POST['key'] without isset
  if grep -nE '\$[a-zA-Z_]+\s*=\s*\$_(POST\[|GET\[|REQUEST\[|COOKIE\[)' "${file}" | grep -vB1 "isset\|array_key_exists" | head -1 > /dev/null 2>&1; then
     echo -e "${RED}  ✗ UNSAFE ARRAY KEY ASSIGNMENT in ${file}:${NC}"
     echo "    Assignment from array key without isset() check."
     grep -nE '\$[a-zA-Z_]+\s*=\s*\$_(POST\[|GET\[|REQUEST\[|COOKIE\[)' "${file}" | grep -vB1 "isset\|array_key_exists" | head -1
     ERROR_COUNT=$((ERROR_COUNT + 1))
  fi
done
echo ""

# 5.1 Syntax
if command -v php >/dev/null 2>&1; then
  for file in "${php_files[@]}"; do
    if ! php -l "${file}" > /dev/null 2>&1; then
      echo -e "${RED}  ✗ PHP SYNTAX ERROR in ${file}${NC}"
      ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
  done

  # 5.5 Duplicate Class Declaration Check (Runtime Error Detection)
  echo -e "${MAGENTA}[5.5/11] Checking for Duplicate Class/Function Declarations...${NC}"
  php "${BASH_SOURCE[0]%/*}/check-duplicate-classes.php" "${PLUGIN_DIR}" 2>&1 | while IFS= read -r line; do
    if [[ "$line" == *DUPLICATE* ]]; then
      echo -e "${RED}  ✗ RUNTIME ERROR: ${line}${NC}"
      ERROR_COUNT=$((ERROR_COUNT + 1))
    elif [[ "$line" == *MISSING* ]]; then
      echo -e "${RED}  ✗ RUNTIME ERROR: ${line}${NC}"
      ERROR_COUNT=$((ERROR_COUNT + 1))
    elif [[ "$line" == *WARNING* ]]; then
      echo -e "${YELLOW}  ⚠ ${line}${NC}"
      WARN_COUNT=$((WARN_COUNT + 1))
    elif [[ "$line" != *"No duplicate"* ]] && [[ "$line" != *"No runtime"* ]] && [[ "$line" != *"Scanned"* ]]; then
      echo "    ${line}"
    fi
  done
fi

  # 5.6 Direct file access check
  # Every PHP file should start with strict denial of direct access
  for file in "${php_files[@]}"; do
    # Skip templates usually, but plugin core files must have it
    first_lines=$(head -n 20 "${file}")
    if ! echo "$first_lines" | grep -qE "defined\s*\(\s*['\"]ABSPATH['\"]\s*\)|defined\s*\(\s*['\"]WPINC['\"]\s*\)"; then
       echo -e "${YELLOW}  ⚠ DIRECT ACCESS PROTECTION MISSING in ${file}${NC}"
       echo "    Add 'defined(ABSPATH) || exit;' at top of file."
       WARN_COUNT=$((WARN_COUNT + 1))
    fi
  done
echo ""

# ============================================
# 6. ACTIVATION HOOK VALIDATION
# ============================================
echo -e "${MAGENTA}[6/11] Checking Activation Hook Setup...${NC}"

for file in "${php_files[@]}"; do
  # Check for register_activation_hook usage
  if grep -q "register_activation_hook" "${file}"; then
    # Extract the callback being used
    callbacks=$(grep -oE "register_activation_hook\s*\([^,]+,\s*[^)]+\)" "${file}" || true)
    
    while IFS= read -r callback; do
      # Check if callback references a class method like array($obj, 'method') or [new Class(), 'method']
      if echo "$callback" | grep -qE "\[\s*(\$[a-zA-Z_]+|new\s+[A-Z][a-zA-Z0-9_]+\(\))\s*,\s*['\"]install['\"]"; then
        # Check if the class is instantiated after the register_activation_hook call
        if grep -A5 "register_activation_hook" "${file}" | grep -q "install"; then
          # Look for require/include statements that load the class
          if ! grep -B10 "register_activation_hook" "${file}" | grep -qE "(require|include|autoload)"; then
            echo -e "${RED}  ✗ ACTIVATION HOOK - INSTALL CLASS NOT LOADED in ${file}:${NC}"
            echo "    register_activation_hook references install class but class may not be loaded."
            grep -n "register_activation_hook" "${file}" | head -1
            ERROR_COUNT=$((ERROR_COUNT + 1))
          fi
        fi
      fi
      
      # Check for callback using class array syntax: ['ClassName', 'method']
      if echo "$callback" | grep -qE "\[\s*['\"][A-Z][a-zA-Z0-9_]*['\"]\s*,\s*['\"]install['\"]"; then
        class_name=$(echo "$callback" | grep -oE "['\"][A-Z][a-zA-Z0-9_]*['\"]\s*," | sed "s/['\"]//g" | sed "s/[, ]//g" | head -1)
        # Check if this class file is loaded before the hook registration
        if ! grep -B20 "register_activation_hook" "${file}" | grep -qi "class ${class_name}"; then
          if ! grep -B20 "register_activation_hook" "${file}" | grep -qiE "require.*${class_name}|include.*${class_name}|autoload.*${class_name}"; then
            echo -e "${RED}  ✗ ACTIVATION HOOK - CLASS NOT LOADED in ${file}:${NC}"
            echo "    register_activation_hook references class '${class_name}' but class file may not be loaded."
            grep -n "register_activation_hook" "${file}" | head -1
            ERROR_COUNT=$((ERROR_COUNT + 1))
          fi
        fi
      fi
      
      # Check for callback like ClassName::install_method
      if echo "$callback" | grep -qE "[A-Z][a-zA-Z0-9_]*::install"; then
        class_name=$(echo "$callback" | grep -oE "[A-Z][a-zA-Z0-9_]*::install" | sed 's/::install//' | head -1)
        if ! grep -B20 "register_activation_hook" "${file}" | grep -qiE "class ${class_name}|require.*${class_name}|include.*${class_name}"; then
          echo -e "${RED}  ✗ ACTIVATION HOOK - STATIC CLASS NOT LOADED in ${file}:${NC}"
          echo "    register_activation_hook references static class '${class_name}' but class may not be loaded."
          grep -n "register_activation_hook" "${file}" | head -1
          ERROR_COUNT=$((ERROR_COUNT + 1))
        fi
      fi
    done <<< "$callbacks"
  fi
  
  # Check for activation hook in a separate file that references external classes
  if grep -q "register_activation_hook" "${file}" && grep -q "use.*;" "${file}"; then
    use_classes=$(grep "^use " "${file}" | grep -oE "use [A-Z][a-zA-Z0-9_\\]+;" | sed 's/use //;s/;//' || true)
    if [ -n "$use_classes" ]; then
      echo -e "${YELLOW}  ⚠ ACTIVATION HOOK - EXTERNAL CLASS USAGE in ${file}:${NC}"
      echo "    Activation hook uses external classes via 'use' statements. Verify they are autoloaded."
      grep -n "register_activation_hook" "${file}" | head -1
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi

  # Check if activation hook is inside a class (common anti-pattern)
  if grep -q "register_activation_hook" "${file}" && grep -qE "^\s*(public|protected|private)\s+static\s+function\s+.*install" "${file}"; then
    echo -e "${YELLOW}  ⚠ ACTIVATION HOOK - INSIDE CLASS in ${file}:${NC}"
    echo "    Activation hook inside class. Consider using separate activation file."
    grep -n "register_activation_hook" "${file}" | head -1
    WARN_COUNT=$((WARN_COUNT + 1))
  fi
done
echo ""

# ============================================
# 7. CLASS LOADING VALIDATION (INSTALL/ADMIN/FRONTEND)
# ============================================
echo -e "${MAGENTA}[7/11] Comprehensive Class Loading Validation...${NC}"

# Define common WordPress hook patterns for different component types
ADMIN_HOOKS_PATTERN="admin_menu|admin_init|admin_head|admin_footer|admin_enqueue_scripts|wp_ajax_|load-(tools|plugins|themes)-page"
FRONTEND_HOOKS_PATTERN="wp_enqueue_scripts|wp_head|wp_footer|template_redirect|wp_ajax_nopriv_"
INSTALL_HOOKS_PATTERN="register_activation_hook|register_deactivation_hook|register_uninstall_hook"

# Find all PHP files and analyze class loading patterns
for file in "${php_files[@]}"; do
  
  # Check for admin hooks without admin class loading
  if grep -qE "add_action\s*\(\s*['\"](${ADMIN_HOOKS_PATTERN})" "${file}"; then
    # Look for admin class references
    if grep -qE "(Admin|admin|Admin_[A-Z])" "${file}"; then
      # Check if admin class is loaded before hooks
      if ! grep -B10 "add_action.*(${ADMIN_HOOKS_PATTERN})" "${file}" | grep -qE "(require|include|autoload).*(Admin|admin|Admin_[A-Z])"; then
        # Also check for class instantiation before hooks
        if ! grep -B10 "add_action.*(${ADMIN_HOOKS_PATTERN})" "${file}" | grep -qE "(new\s+.*Admin|new\s+.*admin|\$admin\s*=)"; then
          echo -e "${RED}  ✗ ADMIN CLASS NOT LOADED in ${file}:${NC}"
          echo "    Admin hooks found but admin class may not be loaded before hook registration."
          grep -nE "add_action\s*\(\s*['\"](${ADMIN_HOOKS_PATTERN})" "${file}" | head -1
          ERROR_COUNT=$((ERROR_COUNT + 1))
        fi
      fi
    fi
  fi
  
  # Check for frontend hooks without frontend class loading
  if grep -qE "add_action\s*\(\s*['\"](${FRONTEND_HOOKS_PATTERN})" "${file}"; then
    # Look for frontend class references
    if grep -qE "(Frontend|frontend|Frontend_[A-Z])" "${file}"; then
      # Check if frontend class is loaded before hooks
      if ! grep -B10 "add_action.*(${FRONTEND_HOOKS_PATTERN})" "${file}" | grep -qE "(require|include|autoload).*(Frontend|frontend|Frontend_[A-Z])"; then
        # Also check for class instantiation before hooks
        if ! grep -B10 "add_action.*(${FRONTEND_HOOKS_PATTERN})" "${file}" | grep -qE "(new\s+.*Frontend|new\s+.*frontend|\$frontend\s*=)"; then
          echo -e "${RED}  ✗ FRONTEND CLASS NOT LOADED in ${file}:${NC}"
          echo "    Frontend hooks found but frontend class may not be loaded before hook registration."
          grep -nE "add_action\s*\(\s*['\"](${FRONTEND_HOOKS_PATTERN})" "${file}" | head -1
          ERROR_COUNT=$((ERROR_COUNT + 1))
        fi
      fi
    fi
  fi
  
  # Check for install/uninstall hooks without proper class loading
  if grep -qE "add_action\s*\(\s*['\"](activate_|deactivate_|uninstall_)" "${file}"; then
    # Look for install/uninstall class references
    if grep -qE "(Install|install|Install_[A-Z]|Uninstall|uninstall|Uninstall_[A-Z])" "${file}"; then
      # Check if install/uninstall class is loaded before hooks
      if ! grep -B10 "add_action.*(activate_|deactivate_|uninstall_)" "${file}" | grep -qE "(require|include|autoload).*(Install|install|Install_[A-Z]|Uninstall|uninstall|Uninstall_[A-Z])"; then
        echo -e "${RED}  ✗ INSTALL/UNINSTALL CLASS NOT LOADED in ${file}:${NC}"
        echo "    Activation/deactivation/uninstall hooks found but install/uninstall class may not be loaded."
        grep -nE "add_action\s*\(\s*['\"](activate_|deactivate_|uninstall_)" "${file}" | head -1
        ERROR_COUNT=$((ERROR_COUNT + 1))
      fi
    fi
  fi
  
  # Check for class instantiations that are used but may not be defined
  if grep -qE "(new\s+(Admin|Frontend|Install|Uninstall)[A-Za-z0-9_]*\s*\()" "${file}"; then
    class_name=$(grep -oE "(new\s+(Admin|Frontend|Install|Uninstall)[A-Za-z0-9_]*\s*\()" "${file}" | grep -oE "(Admin|Frontend|Install|Uninstall)[A-Za-z0-9_]*" | head -1)
    # Check if class file exists or is included
    class_file=$(find "${PLUGIN_DIR}" -name "class-${class_name,,}.php" -o -name "*${class_name}*.php" 2>/dev/null | head -1)
    if [[ -z "$class_file" ]]; then
      # Check if class is loaded via require/include
      if ! grep -qE "(require|include).*${class_name}" "${file}"; then
        echo -e "${RED}  ✗ CLASS DEFINITION MISSING in ${file}:${NC}"
        echo "    Class '${class_name}' instantiated but class file may not be included."
        grep -nE "(new\s+(Admin|Frontend|Install|Uninstall)[A-Za-z0-9_]*\s*\()" "${file}" | head -1
        ERROR_COUNT=$((ERROR_COUNT + 1))
      fi
    fi
  fi
  
  # Check for static method calls on classes that may not be loaded
  if grep -qE "(Admin|Frontend|Install|Uninstall)::[a-zA-Z_]+\s*\(" "${file}"; then
    class_name=$(echo "${file}" | grep -oE "(Admin|Frontend|Install|Uninstall)::" | sed 's/:://' | head -1)
    # Check if class is loaded or defined
    if ! grep -qE "(class\s+${class_name}|require.*${class_name}|include.*${class_name})" "${file}"; then
      echo -e "${YELLOW}  ⚠ STATIC CLASS CALL WITHOUT LOAD in ${file}:${NC}"
      echo "    Static method call on '${class_name}' but class may not be loaded."
      grep -nE "(Admin|Frontend|Install|Uninstall)::[a-zA-Z_]+\s*\(" "${file}" | head -1
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi
  
  # Check for proper dependency ordering in include statements
  # Look for common patterns where install/admin/frontend classes might be missing
  if grep -qE "(admin|frontend|install)" "${file}" | grep -qE "(add_action|new\s+|::)"; then
    # Extract potential class names from includes
    includes=$(grep -oE "(require|include).*(admin|frontend|install)" "${file}" | grep -oE "[a-zA-Z0-9_-]+\.(php|inc)" || true)
    
    # Check if required files exist
    for include_file in $includes; do
      if [[ -n "$include_file" ]]; then
        include_path=$(find "${PLUGIN_DIR}" -name "${include_file}" -type f 2>/dev/null | head -1)
        if [[ -z "$include_path" ]]; then
          echo -e "${RED}  ✗ MISSING INCLUDE FILE in ${file}:${NC}"
          echo "    Required file '${include_file}' not found."
          echo "    Referenced in: ${file}"
          ERROR_COUNT=$((ERROR_COUNT + 1))
        fi
      fi
    done
  fi
  
  # Check for class method calls that might fail due to missing dependencies
  if grep -qE "->(install|activate|deactivate|uninstall|init|run|load)" "${file}"; then
    # Look for potential missing method definitions
    method_call=$(grep -oE "->(install|activate|deactivate|uninstall|init|run|load)\s*\(" "${file}" | head -1)
    if [[ -n "$method_call" ]]; then
      echo -e "${YELLOW}  ⚠ POTENTIAL MISSING METHOD in ${file}:${NC}"
      echo "    Method call ${method_call} found - ensure corresponding class method is defined."
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi
done

# Additional comprehensive check: Scan for common class loading patterns
echo -e "${MAGENTA}[7.1/11] Scanning for Class Loading Patterns...${NC}"

# Define class name patterns to look for
CLASS_PATTERNS=("Admin" "Frontend" "Install" "Uninstall" "Loader" "Controller" "Handler")

for file in "${php_files[@]}"; do
  for class_pattern in "${CLASS_PATTERNS[@]}"; do
    # Check if class is referenced but not defined in file
    if grep -q "${class_pattern}" "${file}"; then
      # Check if class is actually defined in this file
      if ! grep -qE "class\s+${class_pattern}" "${file}"; then
        # Check if class is properly loaded via require/include
        if ! grep -qE "(require|include|require_once|include_once).*${class_pattern}" "${file}"; then
          # Count how many times it's referenced
          ref_count=$(grep -c "${class_pattern}" "${file}" || true)
          if [[ "$ref_count" -gt 2 ]]; then
            echo -e "${YELLOW}  ⚠ CLASS REFERENCE WITHOUT LOAD in ${file}:${NC}"
            echo "    Class '${class_pattern}' referenced ${ref_count} times but may not be loaded."
            WARN_COUNT=$((WARN_COUNT + 1))
          fi
        fi
      fi
    fi
  done
done

echo ""

# 5.7 RUNTIME ERROR DETECTION (Enhanced)
# ============================================
echo -e "${MAGENTA}[5.7/11] Runtime Error Detection...${NC}"

if command -v php >/dev/null 2>&1; then
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
  ANALYZER_OUTPUT=$(php "${SCRIPT_DIR}/check-duplicate-classes.php" "${PLUGIN_DIR}" 2>&1 || true)

  # Parse and report issues
  if echo "$ANALYZER_OUTPUT" | grep -q "UNDEFINED FUNCTION"; then
    echo -e "${RED}  ✗ UNDEFINED FUNCTIONS DETECTED${NC}"
    echo "$ANALYZER_OUTPUT" | grep "UNDEFINED FUNCTION" | head -5
    ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  if echo "$ANALYZER_OUTPUT" | grep -q "EARLY FUNCTION CALL"; then
    echo -e "${RED}  ✗ EARLY FUNCTION CALLS DETECTED${NC}"
    echo "$ANALYZER_OUTPUT" | grep "EARLY FUNCTION CALL" | head -5
    ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  if echo "$ANALYZER_OUTPUT" | grep -q "POTENTIAL UNDEFINED ARRAY"; then
    echo -e "${YELLOW}  ⚠ POTENTIAL UNDEFINED ARRAYS${NC}"
    echo "$ANALYZER_OUTPUT" | grep "POTENTIAL UNDEFINED ARRAY" | head -3
    WARN_COUNT=$((WARN_COUNT + 1))
  fi

  if echo "$ANALYZER_OUTPUT" | grep -q "POTENTIAL CSS OVERLAP"; then
    echo -e "${YELLOW}  ⚠ POTENTIAL CSS OVERLAPS${NC}"
    echo "$ANALYZER_OUTPUT" | grep "POTENTIAL CSS OVERLAP" | head -3
    WARN_COUNT=$((WARN_COUNT + 1))
  fi

  if ! echo "$ANALYZER_OUTPUT" | grep -qE "(UNDEFINED|EARLY|OVERLAP|FAIL)"; then
    echo -e "${GREEN}  ✓ No runtime issues detected${NC}"
  fi
fi
echo ""

# ============================================
# 8. FILE PERMISSIONS
# ============================================
echo -e "${MAGENTA}[8/11] Checking File Permissions...${NC}"

# Find any file that is world-writable or executable (excluding scripts)
find "${PLUGIN_DIR}" -type f -perm -002 -print0 | while IFS= read -r -d '' file; do
    echo -e "${RED}  ✗ INSECURE PERMISSION (World Writable): ${file}${NC}"
    ERROR_COUNT=$((ERROR_COUNT + 1))
done

find "${PLUGIN_DIR}" -type f -name "*.php" -perm -100 -print0 | while IFS= read -r -d '' file; do
    echo -e "${YELLOW}  ⚠ EXECUTABLE PHP FILE: ${file}${NC}"
    echo "    PHP files should generally not have +x permission."
    WARN_COUNT=$((WARN_COUNT + 1))
done
echo ""

# ============================================
# 9. FILE PATH VALIDATION
# ============================================
echo -e "${MAGENTA}[9/11] Checking File Path Construction...${NC}"

for file in "${php_files[@]}"; do
  # 6.1 Hardcoded absolute paths (excluding WordPress constants)
  if grep -nE "(include|require|fopen|file_get_contents|file_put_contents|is_file|is_dir|file_exists)\s*\(\s*['\"](/|[A-Za-z]:)" "${file}" | grep -vE "(ABSPATH|WPINC|WP_CONTENT_DIR|WP_PLUGIN_DIR|WPMU_PLUGIN_DIR|WP_CONTENT_URL|WP_PLUGIN_URL|WPMU_PLUGIN_URL)"; then
    echo -e "${RED}  ✗ HARDCODED ABSOLUTE PATH in ${file}:${NC}"
    echo "    Hardcoded absolute path detected. Use WordPress path functions."
    grep -nE "(include|require|fopen|file_get_contents|file_put_contents|is_file|is_dir|file_exists)\s*\(\s*['\"](/|[A-Za-z]:)" "${file}" | grep -vE "(ABSPATH|WPINC|WP_CONTENT_DIR|WP_PLUGIN_DIR|WPMU_PLUGIN_DIR|WP_CONTENT_URL|WP_PLUGIN_URL|WPMU_PLUGIN_URL)" | head -2
    ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  # 6.2 Missing directory separators in path concatenation
  if grep -nE '\$[a-zA-Z_]+\s*\.\s*["'"'"']' "${file}" | grep -vE "DIRECTORY_SEPARATOR|DS|plugin_dir_path|template_directory|get_template_directory"; then
    echo -e "${YELLOW}  ⚠ POTENTIAL PATH CONCATENATION ERROR in ${file}:${NC}"
    echo "    Path concatenation without proper directory separator."
    grep -nE '\$[a-zA-Z_]+\s*\.\s*["'"'"']' "${file}" | grep -vE "DIRECTORY_SEPARATOR|DS|plugin_dir_path|template_directory|get_template_directory" | head -1
    WARN_COUNT=$((WARN_COUNT + 1))
  fi

  # 6.3 Direct usage of __FILE__ without dirname() for directory paths
  if grep -nE "(plugin_dir_path|plugin_dir_url|template_directory|get_template_directory)" "${file}" | grep -q "__FILE__" && ! grep -q "__FILE__.*dirname" "${file}"; then
    echo -e "${YELLOW}  ⚠ INCORRECT __FILE__ USAGE in ${file}:${NC}"
    echo "    __FILE__ returns the file path. Use dirname(__FILE__) for directory paths."
    grep -n "__FILE__" "${file}" | head -1
    WARN_COUNT=$((WARN_COUNT + 1))
  fi

  # 6.4 User input in file operations (path traversal risk)
  if grep -nE "(include|require|fopen|file_get_contents|file_put_contents|unlink|mkdir|rmdir)\s*\(\s*(\\\$_GET|\\\$_POST|\\\$_REQUEST|\\\$_COOKIE)" "${file}"; then
    echo -e "${RED}  ✗ PATH TRAVERSAL RISK in ${file}:${NC}"
    echo "    Direct user input used in file operation. Must validate and sanitize."
    grep -nE "(include|require|fopen|file_get_contents|file_put_contents|unlink|mkdir|rmdir)\s*\(\s*(\\\$_GET|\\\$_POST|\\\$_REQUEST|\\\$_COOKIE)" "${file}" | head -1
    ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  # 6.5 Not using WordPress path functions for plugin paths
  if grep -nE "(include|require)\s*\(\s*['\"][^'\"]*\.(php|inc)" "${file}" | grep -vE "plugin_dir_path|plugin_dir_url|locate_template|get_template_directory|get_stylesheet_directory"; then
    if ! grep -qE "defined\s*\(\s*['\"]ABSPATH['\"]" "${file}" | head -1; then
      echo -e "${YELLOW}  ⚠ MISSING WORDPRESS PATH FUNCTION in ${file}:${NC}"
      echo "    Use plugin_dir_path(), template_directory(), or similar WP functions."
      grep -nE "(include|require)\s*\(\s*['\"][^'\"]*\.(php|inc)" "${file}" | grep -vE "plugin_dir_path|plugin_dir_url|locate_template|get_template_directory|get_stylesheet_directory" | head -1
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi

  # 6.6 Windows backslashes in paths (should use forward slashes or DIRECTORY_SEPARATOR)
  if grep -nE "[A-Za-z]:\\\\" "${file}" | grep -vE "(DIRECTORY_SEPARATOR|DS|dirname|realpath)"; then
    echo -e "${YELLOW}  ⚠ WINDOWS BACKSLASH DETECTED in ${file}:${NC}"
    echo "    Use forward slashes or DIRECTORY_SEPARATOR constant for cross-platform compatibility."
    grep -nE "[A-Za-z]:\\\\" "${file}" | head -1
    WARN_COUNT=$((WARN_COUNT + 1))
  fi
done
echo ""

# ============================================
# 10. DEPENDENCIES & ENQUEUES
# ============================================
echo -e "${MAGENTA}[10/11] Checking Dependencies & Enqueues...${NC}"

for file in "${php_files[@]}"; do
  # Check for direct wp-load.php inclusion (Major sin)
  if grep -q "wp-load.php" "${file}"; then
    echo -e "${RED}  ✗ ARCHITECTURE FAIL: Direct load of wp-load.php in ${file}${NC}"
    echo "    Plugins must hook into WP, not load it manually."
    ERROR_COUNT=$((ERROR_COUNT + 1))
  fi

  # Check for enqueuing scripts outside hooks
  # We look for wp_enqueue_script NOT inside a function definition
  # (This is a rough heuristic)
  if grep -E "^wp_enqueue_script" "${file}"; then
    echo -e "${YELLOW}  ⚠ DOING IT WRONG: wp_enqueue_script called at root level in ${file}${NC}"
    echo "    Must be inside 'wp_enqueue_scripts' or 'admin_enqueue_scripts' hook."
    WARN_COUNT=$((WARN_COUNT + 1))
  fi

  # Check for direct admin notice output
  if grep -q "add_action.*admin_notices" "${file}" && ! grep -q "is_admin()" "${file}"; then
    echo -e "${YELLOW}  ⚠ Missing is_admin() check in ${file}${NC}"
    echo "    admin_notices hook should verify is_admin()"
    WARN_COUNT=$((WARN_COUNT + 1))
  fi
done
echo ""

# ============================================
# 11. WORDPRESS COMPATIBILITY & DEPRECATED FUNCTIONS
# ============================================
echo -e "${MAGENTA}[11/11] Checking WordPress Compatibility & Deprecated Code...${NC}"

DEPRECATED_WP_PATTERNS=(
  "wp_get_http:Use wp_remote_get()"
  "make_url_footnote:Deprecated"
  "wp_specialchars:Use esc_html()"
  "translate_with_context:Deprecated"
  "get_the_author_email:Use get_the_author_meta('email')"
  "get_the_author_icq:Removed"
  "get_the_author_yim:Removed"
  "get_the_author_msn:Removed"
  "get_the_author_aim:Removed"
  "wp_dashboard_plugins:Removed"
  "the_editor:Use wp_editor()"
)

for file in "${php_files[@]}"; do
  for pattern_set in "${DEPRECATED_WP_PATTERNS[@]}"; do
    pattern="${pattern_set%%:*}"
    advice="${pattern_set##*:}"

    if grep -qE "\b${pattern}\b" "${file}"; then
      echo -e "${RED}  ✗ DEPRECATED WORDPRESS FUNCTION in ${file}:${NC}"
      echo "    Found: '${pattern}'"
      echo "    Fix: $advice"
      grep -nE "\b${pattern}\b" "${file}" | head -1
      ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
  done

  # Check for proper text domain usage
  if grep -qE "__|_e|_x|_n|_ex|_nx|esc_html__|esc_html_e|esc_html_x|esc_attr__|esc_attr_e|esc_attr_x" "${file}"; then
    # Check if text domain matches plugin slug pattern
    text_domain=$(grep -oE "(__|_e|_x)\(['\"][^'\"]*['\"],\s*['\"][^'\"]*['\"]" "${file}" | head -1 | grep -oE "[^',\"]*$" | tr -d ')' | sed 's/^\s*//' | sed 's/\s*$//')
    if [[ -n "$text_domain" ]] && [[ ! "$text_domain" =~ ^pc-[a-z0-9-]+$ ]]; then
      echo -e "${YELLOW}  ⚠ Text domain may not follow naming convention in ${file}${NC}"
      echo "    Expected: pc-{{slug}}-{{id}}"
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi

  # Check for hardcoded URLs
  if grep -qE "http://example\.com|http://your-site\.com|http://localhost" "${file}"; then
    echo -e "${YELLOW}  ⚠ Hardcoded URLs found in ${file}${NC}"
    echo "    Replace with site_url() or home_url()"
    WARN_COUNT=$((WARN_COUNT + 1))
  fi

  # Check for AJAX implementation
  if grep -qE "add_action.*wp_ajax_" "${file}"; then
    if ! grep -qE "check_ajax_referer|wp_verify_nonce" "${file}"; then
      echo -e "${RED}  ✗ AJAX SECURITY RISK in ${file}${NC}"
      echo "    AJAX handler missing nonce verification"
      ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
  fi

  # Check for proper REST API permissions
  if grep -qE "register_rest_route" "${file}"; then
    if ! grep -qE "permission_callback" "${file}"; then
      echo -e "${RED}  ✗ REST API SECURITY RISK in ${file}${NC}"
      echo "    REST route missing permission_callback"
      ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
  fi
done
echo ""

# ============================================
# 10. CSS & UI OVERLAP DETECTION
# ============================================
echo -e "${MAGENTA}[11/11] Checking CSS & UI for Overlap Issues...${NC}"

mapfile -t css_files < <(find "${PLUGIN_DIR}" -type f -name "*.css" ! -path "*/vendor/*" ! -path "*/node_modules/*" 2>/dev/null || true)

if [[ "${#css_files[@]}" -gt 0 ]]; then
  CSS_ISSUE_COUNT=0

  for file in "${css_files[@]}"; do
    # Check for negative margins (common overlap cause)
    if grep -nE "margin-(top|bottom|left|right)\s*:\s*-[0-9]" "${file}" >/dev/null 2>&1; then
      if [[ $CSS_ISSUE_COUNT -lt 5 ]]; then
        echo -e "${YELLOW}  ⚠ CSS ISSUE in ${file}:${NC}"
        echo "    Negative margins detected (may cause overlap)"
        grep -nE "margin-(top|bottom|left|right)\s*:\s*-[0-9]" "${file}" | head -1
      fi
      CSS_ISSUE_COUNT=$((CSS_ISSUE_COUNT + 1))
      WARN_COUNT=$((WARN_COUNT + 1))
    fi

    # Check for absolute positioning without z-index
    if grep -E "position\s*:\s*absolute" "${file}" >/dev/null 2>&1; then
      if ! grep -E "z-index\s*:\s*[1-9]" "${file}" >/dev/null 2>&1; then
        if [[ $CSS_ISSUE_COUNT -lt 5 ]]; then
          echo -e "${YELLOW}  ⚠ CSS ISSUE in ${file}:${NC}"
          echo "    Absolute positioning without z-index (may cause overlap)"
          grep -nE "position\s*:\s*absolute" "${file}" | head -1
        fi
        CSS_ISSUE_COUNT=$((CSS_ISSUE_COUNT + 1))
        WARN_COUNT=$((WARN_COUNT + 1))
      fi
    fi

    # Check for fixed positioning at z-index 0
    if grep -E "position\s*:\s*fixed" "${file}" >/dev/null 2>&1; then
      if grep -E "position\s*:\s*fixed" "${file}" | grep -q "z-index\s*:\s*0"; then
        if [[ $CSS_ISSUE_COUNT -lt 5 ]]; then
          echo -e "${YELLOW}  ⚠ CSS ISSUE in ${file}:${NC}"
          echo "    Fixed positioning at z-index 0 (may overlap other elements)"
          grep -nE "position\s*:\s*fixed.*z-index\s*:\s*0" "${file}" | head -1
        fi
        CSS_ISSUE_COUNT=$((CSS_ISSUE_COUNT + 1))
        WARN_COUNT=$((WARN_COUNT + 1))
      fi
    fi
  done

  if [[ $CSS_ISSUE_COUNT -eq 0 ]]; then
    echo -e "${GREEN}  ✓ No CSS overlap issues detected${NC}"
  else
    echo -e "${YELLOW}  (Additional CSS issues may exist - showing first 5)${NC}"
  fi
else
  echo -e "${GREEN}  ✓ No CSS files found${NC}"
fi
echo ""

# ============================================
# 12. CLASS LOADING ERRORS & MISSING CLASSES
# ============================================
echo -e "${MAGENTA}[12/12] Detecting Class Loading Errors and Missing Classes...${NC}"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CLASS_ERRORS=0
CLASS_WARNINGS=0

if command -v php >/dev/null 2>&1; then
    php "${SCRIPT_DIR}/check-duplicate-classes.php" "${PLUGIN_DIR}" 2>&1 | while IFS= read -r line; do
        if [[ "$line" == *"MISSING CLASS"* ]]; then
            echo -e "${RED}  ✗ CLASS LOADING ERROR: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"MISSING CLASS/TYPE"* ]]; then
            echo -e "${RED}  ✗ CLASS LOADING ERROR: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"DUPLICATE CLASS"* ]]; then
            echo -e "${RED}  ✗ CLASS LOADING ERROR: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"DUPLICATE INTERFACE"* ]]; then
            echo -e "${RED}  ✗ CLASS LOADING ERROR: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"DUPLICATE TRAIT"* ]]; then
            echo -e "${RED}  ✗ CLASS LOADING ERROR: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"install_class_not_loaded"* ]] || [[ "$line" == *"class_not_loaded"* ]]; then
            echo -e "${RED}  ✗ CLASS LOADING ERROR: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"MISSING INCLUDE"* ]]; then
            echo -e "${RED}  ✗ MISSING INCLUDE: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"ACTIVATION HOOK ISSUE"* ]]; then
            echo -e "${RED}  ✗ ACTIVATION HOOK CLASS ERROR: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"UNDEFINED FUNCTION"* ]]; then
            echo -e "${RED}  ✗ UNDEFINED FUNCTION: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"EARLY FUNCTION CALL"* ]]; then
            echo -e "${YELLOW}  ⚠ CLASS LOADING WARNING: ${line}${NC}"
            CLASS_WARNINGS=$((CLASS_WARNINGS + 1))
            WARN_COUNT=$((WARN_COUNT + 1))
        elif [[ "$line" == *"static_class_not_loaded"* ]]; then
            echo -e "${RED}  ✗ STATIC CLASS NOT LOADED: ${line}${NC}"
            CLASS_ERRORS=$((CLASS_ERRORS + 1))
            ERROR_COUNT=$((ERROR_COUNT + 1))
        elif [[ "$line" == *"Checking for"* ]] || [[ "$line" == *"No"* ]] || [[ "$line" == *"✓"* ]] || [[ "$line" == *"PASS"* ]] || [[ "$line" == *"FAIL"* ]] || [[ "$line" == *"Scanned"* ]] || [[ "$line" == *"found"* ]]; then
            :
        else
            echo "    ${line}"
        fi
    done

    echo ""
    echo -e "${MAGENTA}[12.1/12] Static Class Loading Pattern Analysis...${NC}"

    for file in "${php_files[@]}"; do
        if grep -qE "(class_exists|interface_exists|trait_exists)\s*\(" "${file}"; then
            if ! grep -qE "(class_exists|interface_exists|trait_exists)\s*\([^)]+\)\s*;" "${file}"; then
                echo -e "${YELLOW}  ⚠ DYNAMIC CLASS CHECK in ${file}:${NC}"
                echo "    Dynamic class loading detected - ensure autoload is configured."
                CLASS_WARNINGS=$((CLASS_WARNINGS + 1))
                WARN_COUNT=$((WARN_COUNT + 1))
            fi
        fi

        if grep -qE "spl_autoload_register|autoload\s*\(" "${file}"; then
            echo -e "${GREEN}  ✓ Custom autoloader registered in ${file}${NC}"
        fi

        if grep -qE "new\s+[A-Z][a-zA-Z0-9_]*\s*\(" "${file}"; then
            class_refs=$(grep -oE "new\s+[A-Z][a-zA-Z0-9_]*\s*\(" "${file}" | grep -oE "[A-Z][a-zA-Z0-9_]*" | sort -u)
            for class_ref in $class_refs; do
                if ! grep -qE "(class|interface|trait)\s+${class_ref}" "${file}"; then
                    include_check=$(grep -nE "(require|include).*${class_ref}" "${file}" | head -1 || true)
                    if [[ -z "$include_check" ]]; then
                        echo -e "${RED}  ✗ POTENTIAL MISSING CLASS in ${file}:${NC}"
                        echo "    Class '${class_ref}' instantiated but may not be loaded."
                        CLASS_ERRORS=$((CLASS_ERRORS + 1))
                        ERROR_COUNT=$((ERROR_COUNT + 1))
                    fi
                fi
            done
        fi

        if grep -qE "[A-Z][a-zA-Z0-9_]*::[a-z]" "${file}"; then
            static_refs=$(grep -oE "[A-Z][a-zA-Z0-9_]*::[a-z][a-zA-Z0-9_]*" "${file}" | cut -d':' -f1 | sort -u)
            for static_ref in $static_refs; do
                if ! grep -qE "(class|interface|trait)\s+${static_ref}" "${file}"; then
                    include_check=$(grep -nE "(require|include|use).*${static_ref}" "${file}" | head -1 || true)
                    if [[ -z "$include_check" ]]; then
                        echo -e "${YELLOW}  ⚠ POTENTIAL MISSING STATIC CLASS in ${file}:${NC}"
                        echo "    Static class '${static_ref}' referenced but may not be loaded."
                        CLASS_WARNINGS=$((CLASS_WARNINGS + 1))
                        WARN_COUNT=$((WARN_COUNT + 1))
                    fi
                fi
            done
        fi
    done

    if [[ $CLASS_ERRORS -eq 0 ]] && [[ $CLASS_WARNINGS -eq 0 ]]; then
        echo -e "${GREEN}  ✓ No class loading errors detected${NC}"
    elif [[ $CLASS_ERRORS -gt 0 ]]; then
        echo -e "${RED}  ✗ ${CLASS_ERRORS} class loading error(s) found${NC}"
    else
        echo -e "${YELLOW}  ⚠ ${CLASS_WARNINGS} class loading warning(s) found${NC}"
    fi
else
    echo -e "${YELLOW}  ⚠ PHP not available - skipping class loading validation${NC}"
fi
echo ""

# ============================================
# 13. TOO FEW ARGUMENTS ERROR DETECTION
# ============================================
echo -e "${MAGENTA}[13/13] Checking for Too Few Arguments Errors...${NC}"

ARG_ERRORS=0

for file in "${php_files[@]}"; do
  # Check for array_key_exists with single argument (requires 2)
  if grep -nE "array_key_exists\s*\(\s*['\"][^'\"]+['\"]\s*\)" "${file}" >/dev/null 2>&1; then
    if ! grep -nE "array_key_exists\s*\(\s*['\"][^'\"]+['\"]\s*,\s*\\$" "${file}" >/dev/null 2>&1; then
      matches=$(grep -nE "array_key_exists\s*\(\s*['\"][^'\"]+['\"]\s*\)" "${file}" | head -1)
      if [[ -n "$matches" ]] && ! grep -E "array_key_exists\s*\(\s*['\"][^'\"]+['\"]\s*,\s*[a-zA-Z_]" "${file}" >/dev/null 2>&1; then
        echo -e "${RED}  ✗ TOO FEW ARGUMENTS in ${file}:${NC}"
        echo "    array_key_exists() called with only 1 argument (requires 2)"
        echo "$matches"
        ARG_ERRORS=$((ARG_ERRORS + 1))
        ERROR_COUNT=$((ERROR_COUNT + 1))
      fi
    fi
  fi

  # Check for function calls with missing required arguments
  # str_replace requires 3 arguments
  if grep -nE "str_replace\s*\(\s*[^)]+,\s*[^)]+\s*\)" "${file}" >/dev/null 2>&1; then
    if ! grep -E "str_replace\s*\(\s*[^)]+,\s*[^)]+,\s*[^)]+\s*\)" "${file}" >/dev/null 2>&1; then
      matches=$(grep -nE "str_replace\s*\(\s*[^)]+,\s*[^)]+\s*\)" "${file}" | head -1)
      if [[ -n "$matches" ]]; then
        echo -e "${RED}  ✗ TOO FEW ARGUMENTS in ${file}:${NC}"
        echo "    str_replace() called with only 2 arguments (requires 3: search, replace, subject)"
        echo "$matches"
        ARG_ERRORS=$((ARG_ERRORS + 1))
        ERROR_COUNT=$((ERROR_COUNT + 1))
      fi
    fi
  fi

  # Check for sprintf/printf with format but no arguments
  if grep -nE "(sprintf|printf)\s*\(\s*['\"][%].*['\"]\s*\)" "${file}" >/dev/null 2>&1; then
    matches=$(grep -nE "(sprintf|printf)\s*\(\s*['\"][%].*['\"]\s*\)" "${file}" | head -1)
    if [[ -n "$matches" ]]; then
      echo -e "${YELLOW}  ⚠ POSSIBLE TOO FEW ARGUMENTS in ${file}:${NC}"
      echo "    sprintf/printf has format specifiers but may be missing arguments"
      echo "$matches"
      ARG_ERRORS=$((ARG_ERRORS + 1))
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi

  # Check for array_slice with only array argument (requires at least 2)
  if grep -nE "array_slice\s*\(\s*\\\$[a-zA-Z_]+\s*\)" "${file}" >/dev/null 2>&1; then
    matches=$(grep -nE "array_slice\s*\(\s*\\\$[a-zA-Z_]+\s*\)" "${file}" | head -1)
    if [[ -n "$matches" ]]; then
      echo -e "${RED}  ✗ TOO FEW ARGUMENTS in ${file}:${NC}"
      echo "    array_slice() called with only 1 argument (requires at least 2: array, offset)"
      echo "$matches"
      ARG_ERRORS=$((ARG_ERRORS + 1))
      ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
  fi

  # Check for in_array with only haystack argument (requires 2)
  if grep -nE "in_array\s*\(\s*\\\$[a-zA-Z_]+\s*\)" "${file}" >/dev/null 2>&1; then
    matches=$(grep -nE "in_array\s*\(\s*\\\$[a-zA-Z_]+\s*\)" "${file}" | head -1)
    if [[ -n "$matches" ]]; then
      echo -e "${RED}  ✗ TOO FEW ARGUMENTS in ${file}:${NC}"
      echo "    in_array() called with only 1 argument (requires 2: needle, haystack)"
      echo "$matches"
      ARG_ERRORS=$((ARG_ERRORS + 1))
      ERROR_COUNT=$((ERROR_COUNT + 1))
    fi
  fi

  # Check for explode with only delimiter argument (requires 2)
  if grep -nE "explode\s*\(\s*['\"][^'\"]+['\"]\s*\)" "${file}" >/dev/null 2>&1; then
    if ! grep -E "explode\s*\(\s*['\"][^'\"]+['\"]\s*,\s*\\$" "${file}" >/dev/null 2>&1; then
      matches=$(grep -nE "explode\s*\(\s*['\"][^'\"]+['\"]\s*\)" "${file}" | head -1)
      if [[ -n "$matches" ]] && ! grep -E "explode\s*\(\s*['\"][^'\"]+['\"]\s*,\s*[^)]+\)" "${file}" >/dev/null 2>&1; then
        echo -e "${RED}  ✗ TOO FEW ARGUMENTS in ${file}:${NC}"
        echo "    explode() called with only 1 argument (requires 2: delimiter, string)"
        echo "$matches"
        ARG_ERRORS=$((ARG_ERRORS + 1))
        ERROR_COUNT=$((ERROR_COUNT + 1))
      fi
    fi
  fi

  # Check for implode with only array argument (requires 1, but checking for wrong order)
  if grep -nE "implode\s*\(\s*\\\$[a-zA-Z_]+\s*,\s*['\"][^'\"]+['\"]\s*\)" "${file}" >/dev/null 2>&1; then
    matches=$(grep -nE "implode\s*\(\s*\\\$[a-zA-Z_]+\s*,\s*['\"][^'\"]+['\"]\s*\)" "${file}" | head -1)
    if [[ -n "$matches" ]]; then
      echo -e "${YELLOW}  ⚠ POSSIBLE ARGUMENT ORDER ERROR in ${file}:${NC}"
      echo "    implode() arguments may be in wrong order (expected glue, array)"
      echo "$matches"
      ARG_ERRORS=$((ARG_ERRORS + 1))
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi

  # Check for array_merge with single argument (unusual pattern)
  if grep -nE "array_merge\s*\(\s*\\\$[a-zA-Z_]+\s*\)" "${file}" >/dev/null 2>&1; then
    matches=$(grep -nE "array_merge\s*\(\s*\\\$[a-zA-Z_]+\s*\)" "${file}" | head -1)
    if [[ -n "$matches" ]]; then
      echo -e "${YELLOW}  ⚠ POSSIBLE TOO FEW ARGUMENTS in ${file}:${NC}"
      echo "    array_merge() with single argument may indicate missing array parameter"
      echo "$matches"
      ARG_ERRORS=$((ARG_ERRORS + 1))
      WARN_COUNT=$((WARN_COUNT + 1))
    fi
  fi
done

if [[ $ARG_ERRORS -eq 0 ]]; then
  echo -e "${GREEN}  ✓ No too few arguments errors detected${NC}"
fi
echo ""

# ============================================
# 14. FINAL REPORT
# ============================================
echo -e "${BLUE}========================================================${NC}"
echo -e "${BLUE}    AUDIT RESULTS                                       ${NC}"
echo -e "${BLUE}========================================================${NC}"

if [[ "${ERROR_COUNT}" -gt 0 ]]; then
  echo -e "${RED}FAIL: ${ERROR_COUNT} Critical Security/Stability Issues Found.${NC}"
  echo -e "${RED}This plugin is DANGEROUS or BROKEN. Do not deploy.${NC}"
  if [[ "${WARN_COUNT}" -gt 0 ]]; then
    echo -e "${YELLOW}(Plus ${WARN_COUNT} warnings requiring review)${NC}"
  fi
  exit 1
elif [[ "${WARN_COUNT}" -gt 0 ]]; then
  echo -e "${YELLOW}WARNING: ${WARN_COUNT} Potential issues found.${NC}"
  echo "Manual review required to verify false positives."
  echo "Strict mode does not allow clean pass with warnings."
  exit 1
else
  echo -e "${GREEN}SUCCESS: Plugin passed all strict checks.${NC}"
  exit 0
fi
