<?php
/**
 * HVAC Safari Request Debugger
 * 
 * Investigates Safari-specific server crashes by logging request details
 * and monitoring PHP execution for segfaults
 *
 * @package HVAC_Community_Events
 * @since 1.0.8
 */

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

/**
 * HVAC Safari Request Debugger Class
 */
class HVAC_Safari_Request_Debugger {
    
    /**
     * Instance
     *
     * @var HVAC_Safari_Request_Debugger
     */
    private static $instance = null;
    
    /**
     * Debug log file
     *
     * @var string
     */
    private $debug_log_file;
    
    /**
     * Get instance
     */
    public static function instance() {
        if (null === self::$instance) {
            self::$instance = new self();
        }
        return self::$instance;
    }
    
    /**
     * Constructor
     */
    private function __construct() {
        $this->debug_log_file = WP_CONTENT_DIR . '/safari-debug.log';
        $this->init_hooks();
    }
    
    /**
     * Initialize hooks
     */
    private function init_hooks() {
        // Hook very early to catch all requests
        add_action('init', [$this, 'debug_safari_request'], 1);
        
        // Log memory usage during page load
        add_action('wp_loaded', [$this, 'log_memory_usage']);
        
        // Monitor plugin loading for Safari requests
        add_action('plugins_loaded', [$this, 'log_plugins_loaded']);
        
        // Catch fatal errors
        register_shutdown_function([$this, 'catch_fatal_errors']);
    }
    
    /**
     * Check if current request is from Safari
     *
     * @return bool
     */
    private function is_safari_request() {
        if (!isset($_SERVER['HTTP_USER_AGENT'])) {
            return false;
        }
        
        $user_agent = $_SERVER['HTTP_USER_AGENT'];
        
        // Check for Safari but not Chrome (Chrome also contains Safari in UA)
        return (strpos($user_agent, 'Safari') !== false && 
                strpos($user_agent, 'Chrome') === false &&
                strpos($user_agent, 'Chromium') === false);
    }
    
    /**
     * Debug Safari request details
     */
    public function debug_safari_request() {
        if (!$this->is_safari_request()) {
            return;
        }
        
        $request_data = [
            'timestamp' => current_time('Y-m-d H:i:s'),
            'url' => $_SERVER['REQUEST_URI'] ?? '',
            'method' => $_SERVER['REQUEST_METHOD'] ?? '',
            'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
            'accept' => $_SERVER['HTTP_ACCEPT'] ?? '',
            'accept_encoding' => $_SERVER['HTTP_ACCEPT_ENCODING'] ?? '',
            'accept_language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '',
            'connection' => $_SERVER['HTTP_CONNECTION'] ?? '',
            'host' => $_SERVER['HTTP_HOST'] ?? '',
            'referer' => $_SERVER['HTTP_REFERER'] ?? '',
            'remote_addr' => $_SERVER['REMOTE_ADDR'] ?? '',
            'server_name' => $_SERVER['SERVER_NAME'] ?? '',
            'memory_limit' => ini_get('memory_limit'),
            'max_execution_time' => ini_get('max_execution_time'),
            'memory_usage' => $this->format_bytes(memory_get_usage()),
            'memory_peak' => $this->format_bytes(memory_get_peak_usage()),
            'php_version' => PHP_VERSION
        ];
        
        $this->log_debug('SAFARI REQUEST START', $request_data);
        
        // Check if this is the find-a-trainer page specifically
        if (strpos($_SERVER['REQUEST_URI'], 'find-a-trainer') !== false) {
            $this->log_debug('FIND-A-TRAINER PAGE REQUEST', [
                'page' => 'find-a-trainer',
                'plugins_loaded' => did_action('plugins_loaded'),
                'wp_loaded' => did_action('wp_loaded'),
                'theme_setup' => did_action('after_setup_theme')
            ]);
        }
    }
    
    /**
     * Log memory usage at key points
     */
    public function log_memory_usage() {
        if (!$this->is_safari_request()) {
            return;
        }
        
        $memory_data = [
            'current_usage' => $this->format_bytes(memory_get_usage()),
            'peak_usage' => $this->format_bytes(memory_get_peak_usage()),
            'real_usage' => $this->format_bytes(memory_get_usage(true)),
            'real_peak' => $this->format_bytes(memory_get_peak_usage(true)),
            'limit' => ini_get('memory_limit'),
            'available' => $this->calculate_available_memory()
        ];
        
        $this->log_debug('MEMORY USAGE AT WP_LOADED', $memory_data);
    }
    
    /**
     * Log plugins loaded status
     */
    public function log_plugins_loaded() {
        if (!$this->is_safari_request()) {
            return;
        }
        
        // Get list of active plugins
        $active_plugins = get_option('active_plugins', []);
        $problematic_plugins = [
            'interactive-geo-maps/interactive-geo-maps.php',
            'formidable/formidable.php',
            'the-events-calendar/the-events-calendar.php',
            'events-calendar-pro/events-calendar-pro.php'
        ];
        
        $plugin_data = [
            'total_active_plugins' => count($active_plugins),
            'problematic_plugins_active' => array_intersect($active_plugins, $problematic_plugins),
            'hvac_plugin_active' => in_array('hvac-community-events/hvac-community-events.php', $active_plugins),
            'memory_after_plugins' => $this->format_bytes(memory_get_usage())
        ];
        
        $this->log_debug('PLUGINS LOADED', $plugin_data);
        
        // Test specific plugin interactions
        $this->test_plugin_interactions();
    }
    
    /**
     * Test specific plugin interactions that might cause Safari issues
     */
    private function test_plugin_interactions() {
        try {
            // Test MapGeo plugin if active
            if (class_exists('Interactive_Geo_Maps')) {
                $this->log_debug('MAPGEO PLUGIN DETECTED', [
                    'class_exists' => true,
                    'memory_usage' => $this->format_bytes(memory_get_usage())
                ]);
            }
            
            // Test Events Calendar integration
            if (function_exists('tribe_get_events')) {
                $this->log_debug('EVENTS CALENDAR INTEGRATION', [
                    'tribe_functions_available' => true,
                    'memory_usage' => $this->format_bytes(memory_get_usage())
                ]);
            }
            
            // Test HVAC plugin classes
            if (class_exists('HVAC_Community_Events')) {
                $this->log_debug('HVAC PLUGIN CLASSES', [
                    'main_class_loaded' => true,
                    'scripts_styles_class' => class_exists('HVAC_Scripts_Styles'),
                    'template_loader_class' => class_exists('HVAC_Template_Loader'),
                    'memory_usage' => $this->format_bytes(memory_get_usage())
                ]);
            }
            
        } catch (Exception $e) {
            $this->log_debug('PLUGIN INTERACTION ERROR', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
        } catch (Error $e) {
            $this->log_debug('PLUGIN INTERACTION FATAL', [
                'error' => $e->getMessage(),
                'trace' => $e->getTraceAsString()
            ]);
        }
    }
    
    /**
     * Catch fatal errors and log them
     */
    public function catch_fatal_errors() {
        if (!$this->is_safari_request()) {
            return;
        }
        
        $error = error_get_last();
        
        if ($error && in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE])) {
            $this->log_debug('FATAL ERROR DETECTED', [
                'type' => $error['type'],
                'message' => $error['message'],
                'file' => $error['file'],
                'line' => $error['line'],
                'memory_usage' => $this->format_bytes(memory_get_usage()),
                'memory_peak' => $this->format_bytes(memory_get_peak_usage())
            ]);
        }
        
        // Log successful completion if no fatal error
        if (!$error || !in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE])) {
            $this->log_debug('REQUEST COMPLETED SUCCESSFULLY', [
                'final_memory_usage' => $this->format_bytes(memory_get_usage()),
                'final_memory_peak' => $this->format_bytes(memory_get_peak_usage())
            ]);
        }
    }
    
    /**
     * Log debug information
     *
     * @param string $message
     * @param array $data
     */
    private function log_debug($message, $data = []) {
        $log_entry = [
            'timestamp' => current_time('c'),
            'message' => $message,
            'data' => $data,
            'request_id' => $this->get_request_id()
        ];
        
        $log_line = '[' . date('Y-m-d H:i:s') . '] ' . $message . ' | ' . wp_json_encode($data) . PHP_EOL;
        
        // Write to custom log file
        if (is_writable(dirname($this->debug_log_file))) {
            error_log($log_line, 3, $this->debug_log_file);
        }
        
        // Also write to WordPress debug log if enabled
        if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
            error_log('[SAFARI-REQUEST-DEBUG] ' . $log_line);
        }
    }
    
    /**
     * Generate unique request ID
     *
     * @return string
     */
    private function get_request_id() {
        static $request_id = null;
        
        if ($request_id === null) {
            $request_id = uniqid('safari_', true);
        }
        
        return $request_id;
    }
    
    /**
     * Format bytes for readable output
     *
     * @param int $bytes
     * @return string
     */
    private function format_bytes($bytes) {
        $units = ['B', 'KB', 'MB', 'GB'];
        $bytes = max($bytes, 0);
        $pow = floor(($bytes ? log($bytes) : 0) / log(1024));
        $pow = min($pow, count($units) - 1);
        
        $bytes /= pow(1024, $pow);
        
        return round($bytes, 2) . ' ' . $units[$pow];
    }
    
    /**
     * Calculate available memory
     *
     * @return string
     */
    private function calculate_available_memory() {
        $limit = ini_get('memory_limit');
        
        if ($limit === '-1') {
            return 'unlimited';
        }
        
        $limit_bytes = $this->parse_memory_limit($limit);
        $used_bytes = memory_get_usage();
        $available_bytes = $limit_bytes - $used_bytes;
        
        return $this->format_bytes($available_bytes);
    }
    
    /**
     * Parse memory limit string to bytes
     *
     * @param string $limit
     * @return int
     */
    private function parse_memory_limit($limit) {
        $limit = trim($limit);
        $last = strtolower($limit[strlen($limit) - 1]);
        $limit = (int)$limit;
        
        switch ($last) {
            case 'g':
                $limit *= 1024;
            case 'm':
                $limit *= 1024;
            case 'k':
                $limit *= 1024;
        }
        
        return $limit;
    }
}

// Initialize only if this is a Safari request
if (isset($_SERVER['HTTP_USER_AGENT']) && 
    strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== false && 
    strpos($_SERVER['HTTP_USER_AGENT'], 'Chrome') === false) {
    
    HVAC_Safari_Request_Debugger::instance();
}