<?php
/**
 * VMPFence Unknown File Detection Engine
 * 
 * 
 * 
 * 
 * 
 * @package VMPFence
 * @version 1.0.0
 */

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

class VMPFence_Unknown_File_Detection {
    
    /**
     * Known Files instance
     */
    private $known_files;
    
    /**
     * Threat Intelligence instance
     */
    private $threat_intelligence;
    
    /**
     * Debug log
     */
    private $debug_log = [];
    
    /**
     * Detection statistics
     */
    private $detection_stats = [
        'files_analyzed' => 0,
        'unknown_files_found' => 0,
        'suspicious_files' => 0,
        'threat_files' => 0,
        'whitelisted_files' => 0,
        'legitimate_unknown' => 0
    ];
    
    /**
     * Constructor
     */
    public function __construct() {
        // Initialize dependencies
        if (!class_exists('VMPFence_Known_Files')) {
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-known-files.php';
        }
        $this->known_files = new VMPFence_Known_Files();
        
        if (!class_exists('VMPFence_Threat_Intelligence')) {
            require_once VMPFENCE_PLUGIN_DIR . 'includes/class-threat-intelligence.php';
        }
        $this->threat_intelligence = new VMPFence_Threat_Intelligence();
        
        $this->debug_log[] = '[Unknown File Detection] Engine initialized';
    }
    
    /**
     * Analyze file for unknown/unauthorized status
     * 
     * @param string $file_path Full file path
     * @param string $relative_path Relative path from WordPress root
     * @return array Analysis result
     */
    public function analyze_unknown_file($file_path, $relative_path) {
        $this->detection_stats['files_analyzed']++;
        
        $analysis = [
            'file_path' => $file_path,
            'relative_path' => $relative_path,
            'is_unknown' => false,
            'threat_level' => 'none',
            'classification' => 'legitimate',
            'reasons' => [],
            'should_create_issue' => false,
            'issue_description' => null
        ];
        
        // Step 1: Check if file is in Known Files database
        if ($this->known_files->is_known_file_enhanced($file_path, $relative_path)) {
            $analysis['classification'] = 'known_legitimate';
            $analysis['reasons'][] = 'File found in Known Files database';
            return $analysis;
        }
        
        // Step 2: Check whitelist patterns (legitimate unknown files)
        if ($this->is_legitimate_unknown_file($relative_path)) {
            $this->detection_stats['legitimate_unknown']++;
            $analysis['classification'] = 'legitimate_unknown';
            $analysis['reasons'][] = 'Legitimate file pattern (development, config, etc.)';
            return $analysis;
        }
        
        // Step 3: File is unknown - analyze threat level
        $this->detection_stats['unknown_files_found']++;
        $analysis['is_unknown'] = true;
        
        // Step 4: Assess threat level
        $threat_assessment = $this->assess_unknown_file_threat($file_path, $relative_path);
        $analysis = array_merge($analysis, $threat_assessment);
        
        // Step 5: Determine if this should create a database issue
        $analysis['should_create_issue'] = $this->should_create_issue($analysis);
        
        if ($analysis['should_create_issue']) {
            $this->detection_stats['threat_files']++;
            $this->debug_log[] = '[Unknown File Detection] THREAT: ' . $relative_path . ' (Level: ' . $analysis['threat_level'] . ')';
        } else {
            $this->debug_log[] = '[Unknown File Detection] UNKNOWN: ' . $relative_path . ' (Classification: ' . $analysis['classification'] . ')';
        }
        
        return $analysis;
    }
    
    /**
     * Check if unknown file is legitimate (development, config, etc.)
     * 
     * @param string $relative_path Relative file path
     * @return bool True if legitimate unknown file
     */
    private function is_legitimate_unknown_file($relative_path) {
        // Normalize path
        $normalized_path = str_replace('\\', '/', strtolower($relative_path));
        
        // Legitimate unknown file patterns
        $legitimate_patterns = [
            // Development and Version Control
            '/^\.git\//i',                           // Git repository files
            '/^\.svn\//i',                           // SVN repository files
            '/^\.hg\//i',                            // Mercurial repository files
            '/node_modules\//i',                     // Node.js dependencies
            '/vendor\//i',                           // Composer dependencies
            '/^\.env/i',                             // Environment files
            '/^\.htaccess$/i',                       // Apache configuration
            '/^web\.config$/i',                      // IIS configuration
            '/^robots\.txt$/i',                      // SEO robots file
            '/^sitemap.*\.xml$/i',                   // SEO sitemap files
            
            // WordPress uploads (NON-EXECUTABLE FILES ONLY)
            '/^wp-content\/uploads\/.*\.(jpg|jpeg|png|gif|webp|svg|pdf|doc|docx|xls|xlsx|ppt|pptx|zip|tar|gz|mp3|mp4|avi|mov|txt|csv)$/i', // Safe file types only
            '/^wp-content\/cache\//i',               // Cache directories
            '/^wp-content\/backup(s)?\//i',          // Backup directories
            '/^wp-content\/upgrade\//i',             // WordPress upgrade temp
            '/^wp-content\/languages\//i',           // Translation files
            
            // Common CMS additions
            '/^wp-content\/mu-plugins\//i',          // Must-use plugins
            '/^wp-content\/object-cache\.php$/i',    // Object cache drop-in
            '/^wp-content\/advanced-cache\.php$/i',  // Advanced cache drop-in
            '/^wp-content\/db\.php$/i',              // Database drop-in
            
            // Common legitimate files
            '/^favicon\.(ico|png)$/i',               // Favicon files
            '/^apple-touch-icon.*\.png$/i',          // Apple touch icons
            '/^google.*\.html$/i',                   // Google verification
            '/^bing.*\.xml$/i',                      // Bing verification
            '/^yandex_.*\.html$/i',                  // Yandex verification
            '/^\.well-known\//i',                    // Well-known directory (SSL, etc.)
            
            // Log files (NON-EXECUTABLE)
            '/\.log$/i',                             // Log files
            '/error_log$/i',                         // Error logs
            '/access_log$/i',                        // Access logs
            
            // Documentation
            '/^readme\./i',                          // Readme files
            '/^changelog\./i',                       // Changelog files
            '/^license\./i',                         // License files
        ];
        
        foreach ($legitimate_patterns as $pattern) {
            if (preg_match($pattern, $normalized_path)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Assess threat level of unknown file
     * 
     * @param string $file_path Full file path
     * @param string $relative_path Relative path
     * @return array Threat assessment
     */
    private function assess_unknown_file_threat($file_path, $relative_path) {
        $assessment = [
            'threat_level' => 'low',
            'classification' => 'unknown_benign',
            'reasons' => [],
            'risk_factors' => []
        ];
        
        $normalized_path = str_replace('\\', '/', strtolower($relative_path));
        $file_extension = strtolower(pathinfo($relative_path, PATHINFO_EXTENSION));
        $filename = basename($relative_path);
        
        // Critical threat indicators
        if ($this->is_critical_threat($normalized_path, $filename, $file_extension)) {
            $assessment['threat_level'] = 'critical';
            $assessment['classification'] = 'unauthorized_executable';
            $this->detection_stats['suspicious_files']++;
            return $assessment;
        }
        
        // High threat indicators
        if ($this->is_high_threat($normalized_path, $filename, $file_extension)) {
            $assessment['threat_level'] = 'high';
            $assessment['classification'] = 'suspicious_file';
            $this->detection_stats['suspicious_files']++;
            return $assessment;
        }
        
        // Medium threat indicators
        if ($this->is_medium_threat($normalized_path, $filename, $file_extension)) {
            $assessment['threat_level'] = 'medium';
            $assessment['classification'] = 'unknown_suspicious';
            return $assessment;
        }
        
        // Default: Low threat unknown file
        $assessment['reasons'][] = 'Unknown file with no immediate threat indicators';
        return $assessment;
    }
    
    /**
     * Check for critical threat indicators
     * 
     * @param string $normalized_path Normalized file path
     * @param string $filename File name
     * @param string $file_extension File extension
     * @return bool True if critical threat
     */
    private function is_critical_threat($normalized_path, $filename, $file_extension) {
        // PHP files in uploads directory (CRITICAL)
        if (in_array($file_extension, ['php', 'php5', 'php7', 'phtml']) && 
            strpos($normalized_path, 'wp-content/uploads/') === 0) {
            return true;
        }
        
        // Known backdoor filenames in uploads or public areas (CRITICAL)
        $backdoor_names = [
            'shell.php', 'c99.php', 'r57.php', 'webshell.php', 'backdoor.php',
            'bypass.php', 'hack.php', 'eval.php', 'base64.php', 'uploader.php'
        ];
        
        if (in_array(strtolower($filename), $backdoor_names)) {
            // Only critical if in uploads or public areas, not wp-admin/wp-includes
            if (strpos($normalized_path, 'wp-content/uploads/') === 0 ||
                (strpos($normalized_path, 'wp-admin/') !== 0 && 
                 strpos($normalized_path, 'wp-includes/') !== 0 &&
                 strpos($normalized_path, 'wp-content/plugins/') !== 0 &&
                 strpos($normalized_path, 'wp-content/themes/') !== 0)) {
                return true;
            }
        }
        
        // Executable files in content directories
        $executable_extensions = ['exe', 'bat', 'cmd', 'scr', 'com', 'pif'];
        if (in_array($file_extension, $executable_extensions) && 
            strpos($normalized_path, 'wp-content/') === 0) {
            return true;
        }
        
        return false;
    }
    
    /**
     * Check for high threat indicators
     * 
     * @param string $normalized_path Normalized file path
     * @param string $filename File name
     * @param string $file_extension File extension
     * @return bool True if high threat
     */
    private function is_high_threat($normalized_path, $filename, $file_extension) {
        // PHP files in wp-admin or wp-includes (not in checksums)
        if (in_array($file_extension, ['php', 'php5', 'php7', 'phtml'])) {
            if (strpos($normalized_path, 'wp-admin/') === 0 || 
                strpos($normalized_path, 'wp-includes/') === 0) {
                return true;
            }
        }
        
        // Files with suspicious naming patterns
        $suspicious_patterns = [
            '/^[0-9a-f]{8,}\.php$/i',               // Random hex names
            '/^[0-9]+\.php$/i',                     // Numeric names
            '/^[a-z]{1,3}\.php$/i',                 // Very short names
            '/\.(php|js|html?)\.suspected$/i',      // .suspected files
            '/\.(php|js|html?)\.(bak|backup|old|orig)$/i', // Backup of executable files
        ];
        
        foreach ($suspicious_patterns as $pattern) {
            if (preg_match($pattern, $filename)) {
                return true;
            }
        }
        
        return false;
    }
    
    /**
     * Check for medium threat indicators
     * 
     * @param string $normalized_path Normalized file path
     * @param string $filename File name
     * @param string $file_extension File extension
     * @return bool True if medium threat
     */
    private function is_medium_threat($normalized_path, $filename, $file_extension) {
        // Executable files in non-standard locations
        $script_extensions = ['php', 'js', 'pl', 'py', 'cgi'];
        if (in_array($file_extension, $script_extensions)) {
            // Root directory PHP files (not wp-config.php, etc.)
            if (strpos($normalized_path, '/') === false && 
                !in_array($filename, ['wp-config.php', 'index.php', 'wp-load.php'])) {
                return true;
            }
        }
        
        // Files with directory traversal patterns
        if (strpos($normalized_path, '..') !== false) {
            return true;
        }
        
        return false;
    }
    
    /**
     * Determine if analysis should create a database issue
     * 
     * @param array $analysis File analysis result
     * @return bool True if should create issue
     */
    private function should_create_issue($analysis) {
        // Only create issues for actual security threats
        return in_array($analysis['threat_level'], ['critical', 'high']) &&
               in_array($analysis['classification'], [
                   'unauthorized_executable',
                   'suspicious_file'
               ]);
    }
    
    /**
     * Generate issue description for database
     * 
     * @param array $analysis File analysis result
     * @return string Issue description
     */
    public function generate_issue_description($analysis) {
        $descriptions = [
            'unauthorized_executable' => 'Unauthorized executable file detected in restricted location',
            'suspicious_file' => 'Suspicious file with potential security risk detected'
        ];
        
        $base_description = $descriptions[$analysis['classification']] ?? 'Unknown file detected';
        
        // Add specific details
        $details = [];
        if (!empty($analysis['reasons'])) {
            $details[] = implode(', ', $analysis['reasons']);
        }
        
        if (!empty($analysis['risk_factors'])) {
            $details[] = 'Risk factors: ' . implode(', ', $analysis['risk_factors']);
        }
        
        if (!empty($details)) {
            $base_description .= ' | ' . implode(' | ', $details);
        }
        
        return $base_description;
    }
    
    /**
     * Get detection statistics
     * 
     * @return array Detection statistics
     */
    public function get_detection_stats() {
        return $this->detection_stats;
    }
    
    /**
     * Get debug log
     * 
     * @return array Debug log entries
     */
    public function get_debug_log() {
        return $this->debug_log;
    }
    
    /**
     * Reset statistics (for new scan)
     */
    public function reset_stats() {
        $this->detection_stats = [
            'files_analyzed' => 0,
            'unknown_files_found' => 0,
            'suspicious_files' => 0,
            'threat_files' => 0,
            'whitelisted_files' => 0,
            'legitimate_unknown' => 0
        ];
        $this->debug_log = [];
    }
}
?>
