<?php
/**
 * VMPFence Legitimacy Assessment Engine
 * 
 * Distinguish legitimate vs malicious changes using checksums and reputation data
 * 
 * @package VMPFence
 * @since 1.0.0
 */

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

class VMPFence_Legitimacy_Assessment {
    
    /**
     * Analysis statistics
     */
    private $assessment_stats = [
        'files_assessed' => 0,
        'legitimate_files' => 0,
        'suspicious_files' => 0,
        'malicious_files' => 0,
        'unknown_legitimacy' => 0,
        'total_assessment_time' => 0
    ];
    
    /**
     * Debug log for assessment operations
     */
    private $debug_log = [];
    
    /**
     * Legitimacy scoring thresholds
     */
    private $legitimacy_thresholds = [
        'legitimate' => 70,      // Score >= 70: Legitimate
        'suspicious' => 40,      // Score 40-69: Suspicious 
        'malicious' => 0         // Score < 40: Malicious
    ];
    
    /**
     * Constructor
     */
    public function __construct() {
        $this->debug_log[] = '[Legitimacy Assessment] Engine initialized';
    }
    
    /**
     * Assess file legitimacy based on multiple factors
     * 
     * @param string $file_path Full file path
     * @param string $relative_path Relative path from WordPress root
     * @param array $context Additional context (change_type, file_info, etc.)
     * @return array Assessment result
     */
    public function assess_file_legitimacy($file_path, $relative_path, $context = []) {
        $start_time = microtime(true);
        $this->assessment_stats['files_assessed']++;
        
        $assessment = [
            'file_path' => $file_path,
            'relative_path' => $relative_path,
            'legitimacy_score' => 0,
            'legitimacy_level' => 'unknown',
            'assessment_factors' => [],
            'confidence' => 0,
            'recommendation' => 'investigate',
            'assessment_details' => []
        ];
        
        // Factor 1: Repository authenticity (highest weight: 40 points)
        $this->assess_repository_authenticity($assessment, $context);
        
        // Factor 2: File location analysis (weight: 20 points)
        $this->assess_file_location($assessment, $relative_path);
        
        // Factor 3: Change pattern analysis (weight: 15 points)
        $this->assess_change_patterns($assessment, $context);
        
        // Factor 4: File characteristics (weight: 15 points)
        $this->assess_file_characteristics($assessment, $file_path, $context);
        
        // Factor 5: Temporal analysis (weight: 10 points)
        $this->assess_temporal_factors($assessment, $context);
        
        // Calculate final legitimacy assessment
        $this->calculate_legitimacy_assessment($assessment);
        
        // Update statistics
        $this->update_assessment_statistics($assessment);
        
        // Track assessment time
        $assessment_time = microtime(true) - $start_time;
        $this->assessment_stats['total_assessment_time'] += $assessment_time;
        
        $this->debug_log[] = '[Legitimacy Assessment] ' . $relative_path . ' (Score: ' . 
                           $assessment['legitimacy_score'] . ', Level: ' . $assessment['legitimacy_level'] . ')';
        
        return $assessment;
    }
    
    /**
     * Assess repository authenticity factor
     */
    private function assess_repository_authenticity(&$assessment, $context) {
        $score = 0;
        $details = [];
        
        // WordPress core files from official repository
        if (isset($context['repository_verified']) && $context['repository_verified'] === true) {
            $score += 40;
            $details[] = 'File verified against WordPress.org repository';
            $assessment['assessment_factors'][] = 'Repository verified: +40 points';
        }
        
        // Plugin/theme from WordPress.org
        if (isset($context['plugin_verified']) && $context['plugin_verified'] === true) {
            $score += 35;
            $details[] = 'Plugin verified from WordPress.org repository';
            $assessment['assessment_factors'][] = 'Official plugin: +35 points';
        }
        
        if (isset($context['theme_verified']) && $context['theme_verified'] === true) {
            $score += 35;
            $details[] = 'Theme verified from WordPress.org repository';
            $assessment['assessment_factors'][] = 'Official theme: +35 points';
        }
        
        // Known file in database
        if (isset($context['is_known_file']) && $context['is_known_file'] === true) {
            $score += 25;
            $details[] = 'File found in known legitimate files database';
            $assessment['assessment_factors'][] = 'Known legitimate file: +25 points';
        }
        
        // Custom/premium plugins (neutral)
        if (isset($context['is_custom_plugin']) && $context['is_custom_plugin'] === true) {
            $score += 15;
            $details[] = 'Custom/premium plugin - moderate trust';
            $assessment['assessment_factors'][] = 'Custom plugin: +15 points';
        }
        
        $assessment['legitimacy_score'] += $score;
        $assessment['assessment_details'] = array_merge($assessment['assessment_details'], $details);
    }
    
    /**
     * Assess file location factor
     */
    private function assess_file_location(&$assessment, $relative_path) {
        $score = 0;
        $details = [];
        
        // Core WordPress directories (high trust)
        if (preg_match('/^(wp-admin|wp-includes)\//', $relative_path)) {
            $score += 20;
            $details[] = 'File in core WordPress directory';
            $assessment['assessment_factors'][] = 'Core directory: +20 points';
        }
        
        // Official themes directory
        elseif (preg_match('/^wp-content\/themes\/(twenty\w+)\//', $relative_path)) {
            $score += 18;
            $details[] = 'File in official WordPress theme';
            $assessment['assessment_factors'][] = 'Official theme directory: +18 points';
        }
        
        // Standard plugins directory
        elseif (preg_match('/^wp-content\/plugins\//', $relative_path)) {
            $score += 15;
            $details[] = 'File in plugins directory';
            $assessment['assessment_factors'][] = 'Plugins directory: +15 points';
        }
        
        // Themes directory
        elseif (preg_match('/^wp-content\/themes\//', $relative_path)) {
            $score += 12;
            $details[] = 'File in themes directory';
            $assessment['assessment_factors'][] = 'Themes directory: +12 points';
        }
        
        // Uploads directory (lower trust)
        elseif (preg_match('/^wp-content\/uploads\//', $relative_path)) {
            $score += 5;
            $details[] = 'File in uploads directory - needs verification';
            $assessment['assessment_factors'][] = 'Uploads directory: +5 points';
        }
        
        // Root directory files (moderate trust)
        elseif (!strpos($relative_path, '/')) {
            $score += 10;
            $details[] = 'File in WordPress root directory';
            $assessment['assessment_factors'][] = 'Root directory: +10 points';
        }
        
        // Suspicious locations (penalty)
        if (preg_match('/\.(tmp|temp|bak|old)$/i', $relative_path)) {
            $score -= 10;
            $details[] = 'Suspicious file extension detected';
            $assessment['assessment_factors'][] = 'Suspicious extension: -10 points';
        }
        
        $assessment['legitimacy_score'] += $score;
        $assessment['assessment_details'] = array_merge($assessment['assessment_details'], $details);
    }
    
    /**
     * Assess change patterns factor
     */
    private function assess_change_patterns(&$assessment, $context) {
        $score = 0;
        $details = [];
        
        // WordPress update context
        if (isset($context['wordpress_update']) && $context['wordpress_update'] === true) {
            $score += 15;
            $details[] = 'Change occurred during WordPress update';
            $assessment['assessment_factors'][] = 'WordPress update: +15 points';
        }
        
        // Plugin/theme update context
        if (isset($context['plugin_update']) && $context['plugin_update'] === true) {
            $score += 12;
            $details[] = 'Change occurred during plugin update';
            $assessment['assessment_factors'][] = 'Plugin update: +12 points';
        }
        
        // Expected file modification patterns
        if (isset($context['change_type'])) {
            switch ($context['change_type']) {
                case 'version_update':
                    $score += 10;
                    $details[] = 'Version update modification pattern';
                    $assessment['assessment_factors'][] = 'Version update: +10 points';
                    break;
                case 'configuration':
                    $score += 8;
                    $details[] = 'Configuration file modification';
                    $assessment['assessment_factors'][] = 'Configuration change: +8 points';
                    break;
                case 'new_feature':
                    $score += 6;
                    $details[] = 'New feature addition';
                    $assessment['assessment_factors'][] = 'Feature addition: +6 points';
                    break;
                case 'security_patch':
                    $score += 12;
                    $details[] = 'Security patch modification';
                    $assessment['assessment_factors'][] = 'Security patch: +12 points';
                    break;
            }
        }
        
        $assessment['legitimacy_score'] += $score;
        $assessment['assessment_details'] = array_merge($assessment['assessment_details'], $details);
    }
    
    /**
     * Assess file characteristics factor
     */
    private function assess_file_characteristics(&$assessment, $file_path, $context) {
        $score = 0;
        $details = [];
        
        if (!file_exists($file_path)) {
            return;
        }
        
        // File size analysis
        $file_size = filesize($file_path);
        if ($file_size > 0 && $file_size < 10485760) { // Less than 10MB
            $score += 5;
            $details[] = 'Normal file size detected';
            $assessment['assessment_factors'][] = 'Normal file size: +5 points';
        }
        
        // File extension legitimacy
        $extension = strtolower(pathinfo($file_path, PATHINFO_EXTENSION));
        $legitimate_extensions = ['php', 'css', 'js', 'html', 'htm', 'txt', 'md', 'json', 'xml', 'png', 'jpg', 'jpeg', 'gif', 'svg'];
        
        if (in_array($extension, $legitimate_extensions)) {
            $score += 5;
            $details[] = 'Legitimate file extension: .' . $extension;
            $assessment['assessment_factors'][] = 'Legitimate extension: +5 points';
        }
        
        // Content analysis integration
        if (isset($context['content_analysis'])) {
            $content_score = $context['content_analysis']['risk_score'] ?? 0;
            if ($content_score < 20) {
                $score += 5;
                $details[] = 'Low content risk score detected';
                $assessment['assessment_factors'][] = 'Safe content: +5 points';
            } elseif ($content_score >= 50) {
                $score -= 10;
                $details[] = 'High content risk score detected';
                $assessment['assessment_factors'][] = 'Risky content: -10 points';
            }
        }
        
        $assessment['legitimacy_score'] += $score;
        $assessment['assessment_details'] = array_merge($assessment['assessment_details'], $details);
    }
    
    /**
     * Assess temporal factors
     */
    private function assess_temporal_factors(&$assessment, $context) {
        $score = 0;
        $details = [];
        
        // Recent WordPress release correlation
        if (isset($context['wordpress_release_proximity'])) {
            if ($context['wordpress_release_proximity'] < 7) { // Within 7 days
                $score += 10;
                $details[] = 'Change occurred near WordPress release date';
                $assessment['assessment_factors'][] = 'Recent WP release: +10 points';
            }
        }
        
        // Update frequency patterns
        if (isset($context['update_frequency']) && $context['update_frequency'] === 'regular') {
            $score += 5;
            $details[] = 'Regular update pattern detected';
            $assessment['assessment_factors'][] = 'Regular updates: +5 points';
        }
        
        $assessment['legitimacy_score'] += $score;
        $assessment['assessment_details'] = array_merge($assessment['assessment_details'], $details);
    }
    
    /**
     * Calculate final legitimacy assessment
     */
    private function calculate_legitimacy_assessment(&$assessment) {
        $score = $assessment['legitimacy_score'];
        
        // Normalize score to 0-100 range
        $assessment['legitimacy_score'] = min(100, max(0, $score));
        
        // Determine legitimacy level
        if ($score >= $this->legitimacy_thresholds['legitimate']) {
            $assessment['legitimacy_level'] = 'legitimate';
            $assessment['recommendation'] = 'allow';
            $assessment['confidence'] = min(95, 60 + ($score - 70) * 2);
        } elseif ($score >= $this->legitimacy_thresholds['suspicious']) {
            $assessment['legitimacy_level'] = 'suspicious';
            $assessment['recommendation'] = 'investigate';
            $assessment['confidence'] = 50 + ($score - 40);
        } else {
            $assessment['legitimacy_level'] = 'malicious';
            $assessment['recommendation'] = 'block';
            $assessment['confidence'] = 80 - $score;
        }
    }
    
    /**
     * Update assessment statistics
     */
    private function update_assessment_statistics($assessment) {
        switch ($assessment['legitimacy_level']) {
            case 'legitimate':
                $this->assessment_stats['legitimate_files']++;
                break;
            case 'suspicious':
                $this->assessment_stats['suspicious_files']++;
                break;
            case 'malicious':
                $this->assessment_stats['malicious_files']++;
                break;
            default:
                $this->assessment_stats['unknown_legitimacy']++;
                break;
        }
    }
    
    /**
     * Generate legitimacy issue description for database
     */
    public function generate_legitimacy_issue_description($assessment) {
        $level = strtoupper($assessment['legitimacy_level']);
        $score = $assessment['legitimacy_score'];
        $confidence = $assessment['confidence'];
        
        $description = "Legitimacy assessment: {$level} (Score: {$score}, Confidence: {$confidence}%)";
        
        if (!empty($assessment['assessment_factors'])) {
            $description .= " | Factors: " . implode(', ', $assessment['assessment_factors']);
        }
        
        if (!empty($assessment['assessment_details'])) {
            $description .= " | Details: " . implode(', ', $assessment['assessment_details']);
        }
        
        return $description;
    }
    
    /**
     * Check if assessment warrants creating a database issue
     */
    public function should_create_legitimacy_issue($assessment) {
        // Create issues for suspicious and malicious files only
        return in_array($assessment['legitimacy_level'], ['suspicious', 'malicious']) && 
               $assessment['confidence'] >= 60;
    }
    
    /**
     * Get assessment statistics
     */
    public function get_assessment_stats() {
        $stats = $this->assessment_stats;
        
        // Calculate average assessment time
        if ($stats['files_assessed'] > 0) {
            $stats['avg_assessment_time'] = round(($stats['total_assessment_time'] / $stats['files_assessed']) * 1000, 2) . 'ms';
        } else {
            $stats['avg_assessment_time'] = '0ms';
        }
        
        return $stats;
    }
    
    /**
     * Get debug log
     */
    public function get_debug_log() {
        return $this->debug_log;
    }
    
    /**
     * Reset statistics for new scan
     */
    public function reset_stats() {
        $this->assessment_stats = [
            'files_assessed' => 0,
            'legitimate_files' => 0,
            'suspicious_files' => 0,
            'malicious_files' => 0,
            'unknown_legitimacy' => 0,
            'total_assessment_time' => 0
        ];
        $this->debug_log = ['[Legitimacy Assessment] Statistics reset for new scan'];
    }
}
