<?php
/**
 * Diagnostic Special Functions Controller
 * 
 * Handles special diagnostic functions like sysinfo and testmem
 * that need to run early and output directly
 *
 * @package VMPFence
 * @subpackage Tools
 * @since 2.2.0
 * @since 2.2.2 Updated to reflect VMP Security branding
 */

// Prevent direct access
if (!defined('ABSPATH')) {
    exit;
}

class VMPFence_Diagnostic_Special_Functions {
    
    /**
     * Initialize hooks
     */
    public static function init() {
        add_action('template_redirect', array(__CLASS__, 'handle_special_functions'), 1001);
    }
    
    /**
     * Handle special diagnostic functions (sysinfo, testmem)
     */
    public static function handle_special_functions() {
        if (!isset($_GET['_vmpfsf']) || !is_string($_GET['_vmpfsf'])) {
            return;
        }
        
        $vmpFunc = $_GET['_vmpfsf'];
        
        // Only allow sysinfo and testmem functions
        if (!in_array($vmpFunc, array('sysinfo', 'testmem'))) {
            return;
        }
        
        // Must be admin
        if (!current_user_can('manage_options')) {
            return;
        }
        
        // Verify nonce
        $nonce = isset($_GET['nonce']) ? $_GET['nonce'] : '';
        if (!wp_verify_nonce($nonce, 'wp-ajax')) {
            wp_die(__('Bad security token. Please try again.', 'vmpfence-security'));
        }
        
        if ($vmpFunc === 'sysinfo') {
            self::sysinfo();
        } elseif ($vmpFunc === 'testmem') {
            self::testmem();
        }
        
        exit();
    }
    
    /**
     * Display system information (phpinfo)
     */
    private static function sysinfo() {
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title><?php echo esc_html__('VMPFence System Info', 'vmpfence-security'); ?></title>
            <style>
                body { font-family: sans-serif; margin: 20px; }
                .footer { text-align: center; margin-top: 40px; padding: 20px; border-top: 1px solid #ccc; color: #666; }
            </style>
        </head>
        <body>
        <?php
        ob_start();
        if (function_exists('phpinfo')) {
            phpinfo(INFO_ALL);
        } else {
            echo '<center><strong>' . esc_html__('Unable to output phpinfo content because it is disabled', 'vmpfence-security') . '</strong></center>';
        }
        $out = ob_get_clean();
        $out = str_replace('width="600"', 'width="900"', $out);
        $out = preg_replace('/<a [^>]+>/', '', $out);
        $out = preg_replace('/<\/a>/', '', $out);
        $out = preg_replace('/<title>[^<]*<\/title>/', '', $out);
        $out = str_replace('border="0"', 'border="0" style="margin-top: 10px"', $out);
        $out = preg_replace_callback(
            '/<h1 class="p">PHP Version ([^<]*)<\/h1>/',
            function($matches) {
                $phpVersion = $matches[1];
                $logoUrl = VMPFENCE_PLUGIN_URL . 'admin/assets/images/VMP-logo.svg';
                return '<h1 class="p" style="background: url(' . esc_url($logoUrl) . '); background-position: 0 0; background-repeat: no-repeat; height: 48px; vertical-align: middle; padding: 10px 0 0 70px; margin: 20px 0 20px 0; font-family: Arial; font-weight: normal; font-size: 26px;">VMP Security System Info for PHP Version ' . esc_html($phpVersion) . '</h1>';
            },
            $out
        );
        echo $out;
        ?>
        <div class="footer">
            &copy; 2025 - <?php echo date('Y'); ?> VMP Security
        </div>
        </body>
        </html>
        <?php
    }
    
    /**
     * Test available memory
     */
    private static function testmem() {
        header('Content-Type: text/plain; charset=UTF-8');
        @error_reporting(E_ALL);
        @ini_set('display_errors', 'On');
        
        $memoryLimit = wp_convert_hr_to_bytes(ini_get('memory_limit'));
        $configuredMax = 256 * 1024 * 1024; // 256 MB
        $stepSize = 5242880; // 5 MB
        
        echo "VMPFence Memory Benchmarking Utility Version " . VMPFENCE_VERSION . ".\n";
        echo "This utility tests if your WordPress host respects the maximum memory configured\n";
        echo "in their php.ini file, or if they are using other methods to limit your access to memory.\n\n";
        echo "--Starting test--\n";
        echo "Current maximum memory configured in php.ini: " . ini_get('memory_limit') . "\n";
        echo "Current memory usage: " . sprintf('%.2f', memory_get_usage(true) / (1024 * 1024)) . "M\n";
        
        // Set memory limit to configuredMax + stepSize (allows testing beyond 256 MB)
        @ini_set('memory_limit', ($configuredMax + $stepSize));
        echo sprintf("Attempting to set max memory to %d MB.\n", $configuredMax / (1024 * 1024));
        echo sprintf("Starting memory benchmark. Seeing an error after this line is not unusual. Read the error carefully\n");
        echo sprintf("to determine how much memory your host allows. We have requested %d MB.\n", $configuredMax / (1024 * 1024));
        
        if (memory_get_usage(true) < 1) {
            echo "Exiting test because memory_get_usage() returned a negative number\n";
            exit();
        }
        
        if (memory_get_usage(true) > (1024 * 1024 * 1024)) {
            echo "Exiting because current memory usage is greater than a gigabyte.\n";
            exit();
        }
        
        $accumulatedMemory = array_fill(0, ceil($configuredMax / $stepSize), '');
        $currentUsage = memory_get_usage(true);
        $tenMB = 10 * 1024 * 1024;
        $start = ceil($currentUsage / $tenMB) * $tenMB - $currentUsage; // Start at the closest 10 MB increment
        $testLimit = $configuredMax - memory_get_usage(true);
        $finalUsage = '0';
        $previous = 0;
        $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678900000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111222222222222222222233333333333333334444444444444444444444444555555555555666666666666666666";
        $index = 0;
        
        while ($start <= $testLimit) {
            $accumulatedMemory[$index] = str_repeat($chars, ($start - $previous) / 256);
            
            $finalUsage = sprintf('%.2f', (memory_get_usage(true) / 1024 / 1024));
            echo "Tested up to " . $finalUsage . " megabytes.\n";
            flush();
            
            if ($start == $testLimit) { 
                break; 
            }
            
            $previous = $start;
            $start = min($start + $stepSize, $testLimit);
            
            if (memory_get_usage(true) > $configuredMax) { 
                break; 
            }
            
            $index++;
        }
        
        echo "--Test complete.--\n\n";
        echo "Your web host allows you to use at least {$finalUsage} megabytes of memory for each PHP process hosting your WordPress site.\n";
    }
}

// Initialize the controller
VMPFence_Diagnostic_Special_Functions::init();
