<?php
/**
 * VMPFence Scan Percentage Calculator
 * 
 * Calculates scan configuration completeness percentage based on enabled scan options
 * 
 * @package VMPFence
 * @since 1.0.0
 */

if (!defined('ABSPATH')) {
    exit;
}

class VMPFence_Scan_Percentage {
    
    /**
     * Weight values for each scan option (totaling 1.0 for 100%)
     * Higher weights = more important security features
     */
    private static function getScanOptionWeights() {
        return array(
            // HIGH IMPORTANCE - Core Security (0.15 each = 0.30 total)
            'scansEnabled_malware' => 0.15,           // Malware detection
            'scansEnabled_fileContents' => 0.15,     // File content scanning
            
            // MEDIUM-HIGH IMPORTANCE - File Integrity (0.08 each = 0.32 total)
            'scansEnabled_core' => 0.08,             // WordPress core files
            'scansEnabled_plugins' => 0.08,          // Plugin file integrity
            'scansEnabled_themes' => 0.08,           // Theme file integrity
            'scansEnabled_coreUnknown' => 0.08,      // Unknown core files
            
            // MEDIUM IMPORTANCE - Security Checks (0.05 each = 0.25 total)
            'scansEnabled_suspiciousAdminUsers' => 0.05,  // Admin user audit
            'scansEnabled_passwds' => 0.05,               // Password strength
            'scansEnabled_oldVersions' => 0.05,           // Outdated versions
            'scansEnabled_checkReadableConfig' => 0.05,   // Config file security
            'scansEnabled_suspectedFiles' => 0.05,        // Suspicious files
            
            // LOW-MEDIUM IMPORTANCE - Reputation & Content (0.03 each = 0.09 total)
            'spamvertizeCheck' => 0.03,              // Spam reputation
            'checkSpamIP' => 0.03,                   // IP reputation
            'scansEnabled_posts' => 0.03,            // Post content scanning
            
            // LOW IMPORTANCE - Additional Checks (0.01-0.02 each = 0.04 total)
            'scansEnabled_comments' => 0.02,         // Comment scanning
            'scansEnabled_diskSpace' => 0.01,        // Disk space check
            'scansEnabled_wafStatus' => 0.01,        // WAF status check
            
            // ZERO WEIGHT - Configuration/Optional features
            'scansEnabled_checkGSB' => 0,            // Google Safe Browsing (optional)
            'scansEnabled_checkHowGetIPs' => 0,      // IP detection method
            'scansEnabled_fileContentsGSB' => 0,     // GSB file content check
            'scansEnabled_suspiciousOptions' => 0,   // WP options check
            'scansEnabled_geoipSupport' => 0,        // GeoIP support
            'scansEnabled_scanImages' => 0,          // Image scanning
            'other_scanOutside' => 0,                // Scan outside WordPress
            'scan_include_extra' => 0,               // Extra directories
            'scan_exclude' => 0,                     // Exclusions
            'lowResourceScansEnabled' => 0,          // Performance setting
            
            // User Security Features (VMPFence specific)
            'scansEnabled_risky_usernames' => 0.02,  // Risky username detection
            'scansEnabled_admin_users' => 0.01,      // Admin user enumeration
            'scansEnabled_user_enumeration' => 0.01, // User enumeration check
        );
    }
    
    /**
     * Calculate scan percentage based on enabled options
     * 
     * @return float Percentage between 0.0 and 1.0
     */
    public static function calculateScanPercentage() {
        // Get current scan options
        $scan_options = VMPFence_Scan_Config::getScanOptions();
        $weights = self::getScanOptionWeights();
        
        $score = 0.0;
        
        // Calculate score based on enabled options
        foreach ($weights as $option => $weight) {
            if (isset($scan_options[$option]) && $scan_options[$option]) {
                $score += $weight;
            }
        }
        
        // Round to 2 decimal places and ensure it doesn't exceed 1.0
        return min(round($score, 2), 1.0);
    }
    
    /**
     * Get scan percentage as a formatted percentage string
     * 
     * @return string Percentage like "65%"
     */
    public static function getScanPercentageDisplay() {
        $percentage = self::calculateScanPercentage();
        return round($percentage * 100) . '%';
    }
    
    /**
     * Get detailed breakdown of scan status
     * 
     * @return array Array with percentage and status details
     */
    public static function getScanStatusDetails() {
        $scan_options = VMPFence_Scan_Config::getScanOptions();
        $weights = self::getScanOptionWeights();
        $current_scan_type = VMPFence_Config::get('scanType', 'standard');
        
        $enabled_features = 0;
        $total_weighted_features = 0;
        $missing_critical = array();
        $enabled_score = 0.0;
        
        foreach ($weights as $option => $weight) {
            if ($weight > 0) {
                $total_weighted_features++;
                
                if (isset($scan_options[$option]) && $scan_options[$option]) {
                    $enabled_features++;
                    $enabled_score += $weight;
                } else {
                    // Track missing critical features (weight >= 0.05)
                    if ($weight >= 0.05) {
                        $missing_critical[] = self::getOptionDisplayName($option);
                    }
                }
            }
        }
        
        $percentage = min(round($enabled_score, 2), 1.0);
        
        return array(
            'percentage' => $percentage,
            'display_percentage' => round($percentage * 100) . '%',
            'enabled_features' => $enabled_features,
            'total_features' => $total_weighted_features,
            'scan_type' => $current_scan_type,
            'scan_type_display' => self::getScanTypeDisplay($current_scan_type),
            'missing_critical' => $missing_critical,
            'status_class' => self::getStatusClass($percentage),
            'status_message' => self::getStatusMessage($percentage, count($missing_critical))
        );
    }
    
    /**
     * Get display name for scan option
     * 
     * @param string $option Option key
     * @return string Human readable name
     */
    private static function getOptionDisplayName($option) {
        $names = array(
            'scansEnabled_malware' => 'Malware Detection',
            'scansEnabled_fileContents' => 'File Content Scanning',
            'scansEnabled_core' => 'WordPress Core Files',
            'scansEnabled_plugins' => 'Plugin File Integrity',
            'scansEnabled_themes' => 'Theme File Integrity',
            'scansEnabled_coreUnknown' => 'Unknown Core Files',
            'scansEnabled_suspiciousAdminUsers' => 'Admin User Audit',
            'scansEnabled_passwds' => 'Password Security',
            'scansEnabled_oldVersions' => 'Version Updates',
            'scansEnabled_checkReadableConfig' => 'Config Security',
            'scansEnabled_suspectedFiles' => 'Suspicious Files',
            'spamvertizeCheck' => 'Spam Reputation',
            'checkSpamIP' => 'IP Reputation',
            'scansEnabled_posts' => 'Post Content',
        );
        
        return isset($names[$option]) ? $names[$option] : str_replace('scansEnabled_', '', $option);
    }
    
    /**
     * Get scan type display name
     * 
     * @param string $scan_type Scan type key
     * @return string Display name
     */
    private static function getScanTypeDisplay($scan_type) {
        $types = array(
            'limited' => 'Limited Scan',
            'standard' => 'Standard Scan',
            'high_sensitivity' => 'High Sensitivity Scan',
            'custom' => 'Custom Scan'
        );
        
        return isset($types[$scan_type]) ? $types[$scan_type] : 'Unknown Scan';
    }
    
    /**
     * Get status CSS class based on percentage
     * 
     * @param float $percentage Percentage between 0.0 and 1.0
     * @return string CSS class
     */
    private static function getStatusClass($percentage) {
        if ($percentage >= 0.8) return 'excellent';
        if ($percentage >= 0.6) return 'good';
        if ($percentage >= 0.4) return 'fair';
        return 'poor';
    }
    
    /**
     * Get status message based on percentage and missing features
     * 
     * @param float $percentage Percentage between 0.0 and 1.0
     * @param int $missing_critical_count Number of missing critical features
     * @return string Status message
     */
    private static function getStatusMessage($percentage, $missing_critical_count) {
        if ($percentage >= 0.9) {
            return 'Excellent security coverage';
        } elseif ($percentage >= 0.7) {
            return 'Good security coverage';
        } elseif ($percentage >= 0.5) {
            $msg = 'Fair security coverage';
            if ($missing_critical_count > 0) {
                $msg .= " - {$missing_critical_count} critical feature" . ($missing_critical_count > 1 ? 's' : '') . ' disabled';
            }
            return $msg;
        } else {
            return 'Poor security coverage - enable more scan features';
        }
    }
    
    /**
     * Calculate scan percentage breakdown for SIEM server push.
     *
     * Returns 3 separate ring values for the portal findings page.
     * This is a NEW method — does NOT modify calculateScanPercentage().
     *
     * @since 2.2.5
     * @return array{scan_type: int, malware_sigs: int, reputation: int} 0-100 each
     */
    public static function calculateScanPercentageBreakdown(): array {
        $overall      = self::calculateScanPercentage(); // existing float 0.0-1.0
        $scan_type_pct = (int) round($overall * 100);

        // Malware sigs: derive from enabled malware scan options
        $scan_options = VMPFence_Scan_Config::getScanOptions();
        $malware_sigs = 100;
        if (empty($scan_options['scansEnabled_malware']) && empty($scan_options['scansEnabled_fileContents'])) {
            $malware_sigs = 0;
        } elseif (empty($scan_options['scansEnabled_malware']) || empty($scan_options['scansEnabled_fileContents'])) {
            $malware_sigs = 50;
        }

        // Reputation: based on spam/reputation checks enabled
        $reputation = 100;
        if (empty($scan_options['spamvertizeCheck']) && empty($scan_options['checkSpamIP'])) {
            $reputation = 0;
        } elseif (empty($scan_options['spamvertizeCheck']) || empty($scan_options['checkSpamIP'])) {
            $reputation = 50;
        }

        return array(
            'scan_type'    => $scan_type_pct,
            'malware_sigs' => (int) $malware_sigs,
            'reputation'   => (int) $reputation,
        );
    }

    /**
     * Get recommendations for improving scan percentage
     * 
     * @return array Array of recommendations
     */
    public static function getRecommendations() {
        $scan_options = VMPFence_Scan_Config::getScanOptions();
        $weights = self::getScanOptionWeights();
        $recommendations = array();
        
        // Check for disabled critical features (weight >= 0.1)
        $critical_disabled = array();
        foreach ($weights as $option => $weight) {
            if ($weight >= 0.1 && (!isset($scan_options[$option]) || !$scan_options[$option])) {
                $critical_disabled[] = array(
                    'option' => $option,
                    'name' => self::getOptionDisplayName($option),
                    'weight' => $weight,
                    'impact' => round($weight * 100) . '%'
                );
            }
        }
        
        if (!empty($critical_disabled)) {
            $recommendations[] = array(
                'type' => 'critical',
                'title' => 'Enable Critical Security Features',
                'features' => $critical_disabled,
                'message' => 'These high-impact security features are currently disabled.'
            );
        }
        
        // Check scan type optimization
        $current_type = VMPFence_Config::get('scanType', 'standard');
        if ($current_type === 'limited') {
            $recommendations[] = array(
                'type' => 'upgrade',
                'title' => 'Upgrade Scan Type',
                'message' => 'Consider upgrading to Standard or High Sensitivity scan for better protection.',
                'action' => 'Change scan type in scan options'
            );
        }
        
        return $recommendations;
    }
}