<?php
/*
Plugin Name: WPFort Security Suite
Description: WPFort is your ultimate shield against cyber threats, offering an all-in-one security solution for your WordPress site. With just a single click, activate a suite of powerful tools designed to safeguard your online presence. Transform your site into a fortress against online threats.
Version: 1.3.1
Author: WP Tech Group 🥷
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: wpfortai-security
*/

defined('ABSPATH') || exit;

// Define constants
define('WPSEC_PLUGIN_DIR', plugin_dir_path(__FILE__));
define('WPSEC_API_KEY', get_option('wpsec_api_key', 'sadasda78as78sda78sda78sfa687fajk')); // Store API key securely

// Progress and webhook functionality now working correctly with native implementation

// Enable development mode for testing
define('WPSEC_DEVELOPMENT', true);

// Control log verbosity - set to false to reduce log noise, true for detailed logging
define('WPSEC_VERBOSE_LOGGING', false);

// Enable debug mode for development - set to false in production
define('WPSEC_DEBUG', WPSEC_DEVELOPMENT);

// We no longer need complex WP Cron recovery mechanisms
// The new direct resume approach is much more reliable

// Add custom cron schedule
add_filter('cron_schedules', 'wpsec_add_cron_schedules');

// Near the top of wpfortai-security.php, after defining constants but before other includes
require_once WPSEC_PLUGIN_DIR . 'activation-fix.php';

/**
 * Handler for scan resume events
 * 
 * @param string $scan_id The scan ID to resume
 * @param int $resume_from The position to resume from
 * @return void
 */
function wpsec_resume_scan_handler($scan_id, $resume_from) {
    // Load the recovery module if not already loaded
    if (!function_exists('wpsec_resume_scan')) {
        require_once WPSEC_PLUGIN_DIR . 'includes/scan-recovery.php';
    }
    
    // Call the resume function
    wpsec_resume_scan($scan_id, $resume_from);
}


/**
 * Auto-recovery handler for stalled scans
 * Automatically detects and attempts to recover stalled scans
 * 
 * @return void 
 */
function wpsec_scan_auto_recovery_handler() {
    global $wpdb;
    
    // Load recovery module if not already loaded
    if (!function_exists('wpsec_check_scan_recovery')) {
        require_once WPSEC_PLUGIN_DIR . 'includes/scan-recovery.php';
    }
    
    // Find scan IDs with status 'scanning', 'paused', or 'resuming'
    $option_pattern = $wpdb->esc_like('wpsec_scan_') . '%' . $wpdb->esc_like('_status');
    $options = $wpdb->get_results(
        $wpdb->prepare(
            "SELECT option_name, option_value FROM {$wpdb->options} WHERE option_name LIKE %s",
            $option_pattern
        )
    );
    
    $recovered_count = 0;
    $checked_count = 0;
    
    foreach ($options as $option) {
        // Extract scan ID from option name
        $scan_id = str_replace(['wpsec_scan_', '_status'], '', $option->option_name);
        $status = $option->option_value;
        
        // Only consider active scans (scanning, paused, resuming)
        if (in_array($status, ['scanning', 'paused', 'resuming'])) {
            $checked_count++;
            
            // Attempt recovery
            $recovered = wpsec_check_scan_recovery($scan_id);
            if ($recovered) {
                $recovered_count++;
            }
        }
    }
    
    // Log recovery activity if any scans were checked
    if ($checked_count > 0) {
        wpsec_debug_log("🔍 WPFort Auto-recovery: Checked {$checked_count} scans, recovered {$recovered_count}", 'info');
    }
}

/**
 * Add custom cron schedules for scan operations
 * 
 * @param array $schedules Existing cron schedules
 * @return array Modified cron schedules
 */
function wpsec_add_cron_schedules($schedules) {
    // Add a 5 minute schedule for auto-recovery
    $schedules['five_minutes'] = [
        'interval' => 300,
        'display' => esc_html__('Every 5 minutes', 'wpfortai-security')
    ];
    
    // Add a 15 minute schedule for more intensive operations
    $schedules['fifteen_minutes'] = [
        'interval' => 900,
        'display' => esc_html__('Every 15 minutes', 'wpfortai-security')
    ];
    
    return $schedules;
}

/**
 * Universal REST API Compatibility Layer
 * This approach ensures ALL endpoints work on ALL WordPress installations
 * regardless of permalink settings or server configuration
 */

// Debug logging for REST API configuration
add_action('rest_api_init', function() {
    wpsec_debug_log('WPFort Debug: REST API init hook running', 'debug');
    
    // Log the permalink structure and REST API URL format
    $permalink_structure = get_option('permalink_structure');
    $rest_url_format = rest_url('wp/v2/posts');
    wpsec_debug_log('WPFort Debug: REST API URL format: ' . $rest_url_format, 'debug');
    wpsec_debug_log('WPFort Debug: Permalink structure: ' . (empty($permalink_structure) ? 'Plain/Default' : $permalink_structure), 'debug');
});

/**
 * Universal REST API Handler for Plain Permalinks
 * 
 * This function provides a fallback mechanism for ALL endpoints when a site
 * is using plain permalinks. It works by intercepting requests with the
 * wpsec_endpoint parameter and routing them through the WordPress REST API.
 */
add_action('parse_request', function($wp) {
    // Only process our custom endpoint requests
    if (!isset($_GET['wpsec_endpoint'])) {
        return;
    }
    
    $endpoint = sanitize_text_field($_GET['wpsec_endpoint']);
    wpsec_debug_log('WPFort Debug: Processing API request via fallback parameter: ' . $endpoint, 'debug');
    
    // Handle URL-encoded forward slashes in the endpoint
    $endpoint = str_replace('%2F', '/', urldecode($endpoint));
    wpsec_debug_log('WPFort Debug: Normalized endpoint: ' . $endpoint, 'debug');
    
    // Create a proper REST request
    $request_method = $_SERVER['REQUEST_METHOD'];
    $request = new WP_REST_Request($request_method, '/wpsec/v1/' . $endpoint);
    
    // Add query parameters
    foreach ($_GET as $param => $value) {
        if ($param !== 'wpsec_endpoint') {
            $request->set_param($param, $value);
        }
    }
    
    // Copy all HTTP headers to the request
    $headers = getallheaders();
    if (!empty($headers)) {
        foreach ($headers as $header => $value) {
            // Convert header name to uppercase with HTTP_ prefix as expected by WordPress
            $header_key = 'HTTP_' . str_replace('-', '_', strtoupper($header));
            $_SERVER[$header_key] = $value;
            
            // Also add the header directly to the request
            $request->add_header($header, $value);
            
            // Debug the headers
            wpsec_debug_log('WPFort Debug: Adding header ' . $header . ': ' . $value, 'debug');
        }
    }
    
    // Special handling for the x-api-key header which is critical for authentication
    if (isset($headers['x-api-key'])) {
        wpsec_debug_log('WPFort Debug: Found x-api-key header: ' . $headers['x-api-key'], 'debug');
        $request->set_param('api_key', $headers['x-api-key']);
    } elseif (isset($headers['X-Api-Key'])) {
        wpsec_debug_log('WPFort Debug: Found X-Api-Key header: ' . $headers['X-Api-Key'], 'debug');
        $request->set_param('api_key', $headers['X-Api-Key']);
    }
    
    // Handle POST/PUT data
    if ($request_method === 'POST' || $request_method === 'PUT') {
        $json_data = file_get_contents('php://input');
        if (!empty($json_data)) {
            $data = json_decode($json_data, true);
            if (is_array($data)) {
                foreach ($data as $param => $value) {
                    $request->set_param($param, $value);
                }
            }
        } else {
            // Handle form data
            foreach ($_POST as $param => $value) {
                $request->set_param($param, $value);
            }
        }
    }
    
    // Make sure our endpoints are registered
    // Add error handling to prevent crashes from other plugins
    try {
        wpsec_log('Initializing REST API for custom endpoint: ' . $endpoint, 'debug');
        do_action('rest_api_init');
    } catch (Throwable $e) {
        // Log the error but continue processing
        wpsec_log('Error during REST API initialization: ' . $e->getMessage(), 'error');
        wpsec_debug_log('WPFort Security: Error during REST API initialization: ' . $e->getMessage(), 'error');
    }
    
    // Dispatch the request through the REST API
    try {
        $response = rest_do_request($request);
    } catch (Throwable $e) {
        // Log the error and return a formatted error response
        wpsec_log('Error processing REST request: ' . $e->getMessage(), 'error');
        wpsec_debug_log('WPFort Security: Error processing REST request: ' . $e->getMessage(), 'error');
        
        // Create a proper error response
        $response = new WP_REST_Response([
            'status' => 'error',
            'message' => 'An error occurred while processing your request.',
            'code' => 'request_processing_error'
        ], 500);
    }
    
    // Set appropriate headers for the response
    status_header($response->get_status());
    foreach ($response->get_headers() as $header => $value) {
        header($header . ': ' . $value);
    }
    
    // Output the response in JSON format
    header('Content-Type: application/json');
    
    // Check if it's a WP_Error object (different from is_error() method)
    if (is_wp_error($response)) {
        // Handle WP_Error response
        echo json_encode([
            'code' => $response->get_error_code(),
            'message' => $response->get_error_message(),
            'data' => $response->get_error_data()
        ]);
    } else {
        // Output successful response
        // Important: Maintain the exact same API response structure for compatibility
        echo json_encode($response->get_data());
    }
    
    // Stop WordPress from continuing
    exit;
});

/**
 * Admin Notice for Plain Permalinks
 * 
 * Displays a notice to administrators when the site is using plain permalinks,
 * recommending they switch to pretty permalinks for optimal functionality.
 */
add_action('admin_notices', function() {
    // Only show if permalinks are not set
    $permalink_structure = get_option('permalink_structure');
    if (empty($permalink_structure) && current_user_can('manage_options')) {
        ?>
        <div class="notice notice-warning">
            <p><strong>WPFort Security Suite:</strong> Your site is using plain permalinks. For optimal performance, we recommend <a href="<?php echo esc_url(admin_url('options-permalink.php')); ?>">changing your permalink settings</a> to use a pretty permalink structure.</p>
            <p>All plugin features will continue to work with plain permalinks using the alternative URL format: <code><?php echo esc_url(site_url()); ?>/?wpsec_endpoint=ENDPOINT_NAME</code></p>
        </div>
        <?php
    }
});

/**
 * Get the correct API URL format based on permalink settings
 * 
 * This helper function returns the appropriate URL format for any endpoint
 * based on the site's permalink structure. It ensures all API calls work
 * consistently across different WordPress configurations.
 * 
 * @param string $endpoint The endpoint name (without leading slash)
 * @param array $query_args Optional query arguments to append to the URL
 * @return string The formatted URL
 */
function wpsec_get_api_url($endpoint, $query_args = []) {
    $permalink_structure = get_option('permalink_structure');
    
    if (empty($permalink_structure)) {
        // Plain permalinks - use our fallback parameter
        $url = site_url();
        $url = add_query_arg('wpsec_endpoint', $endpoint, $url);
    } else {
        // Pretty permalinks - use standard format
        $url = site_url('wp-json/wpsec/v1/' . $endpoint);
    }
    
    // Add any additional query arguments
    if (!empty($query_args)) {
        $url = add_query_arg($query_args, $url);
    }
    
    return $url;
}

// Load core dependencies first
require_once WPSEC_PLUGIN_DIR . 'includes/api.php';    // Include API first
// Filesystem helper now loaded from backup plugin if available
require_once WPSEC_PLUGIN_DIR . 'includes/logger.php';
require_once WPSEC_PLUGIN_DIR . 'includes/auth.php';
require_once WPSEC_PLUGIN_DIR . 'includes/uptime.php'; // Uptime monitoring
require_once WPSEC_PLUGIN_DIR . 'includes/live-feed.php'; // Live feed event system

// Core scan functionality
require_once WPSEC_PLUGIN_DIR . 'includes/scan-environment.php';

// Load the direct resume handler FIRST (contains shared functions)
require_once WPSEC_PLUGIN_DIR . 'includes/direct-resume.php';  // New streamlined recovery

// Load scan recovery mechanisms AFTER direct-resume.php
require_once WPSEC_PLUGIN_DIR . 'includes/scan-recovery.php';
require_once WPSEC_PLUGIN_DIR . 'includes/api-recovery.php';

// Load admin debug panel
require_once WPSEC_PLUGIN_DIR . 'admin/scan-debug.php';
require_once WPSEC_PLUGIN_DIR . 'admin/debug-logs.php';
require_once WPSEC_PLUGIN_DIR . 'includes/scan-resume.php';
require_once WPSEC_PLUGIN_DIR . 'includes/file-actions.php';
require_once WPSEC_PLUGIN_DIR . 'includes/file-inspector.php';
require_once WPSEC_PLUGIN_DIR . 'includes/file-whitelist.php';
require_once WPSEC_PLUGIN_DIR . 'includes/webhooks.php';    // Include webhooks system
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-uptime.php';  // Uptime monitoring endpoint
require_once WPSEC_PLUGIN_DIR . 'includes/core-reinstall.php';  // Include core reinstall system
require_once WPSEC_PLUGIN_DIR . 'includes/core-restore.php';    // Include core restore system
require_once WPSEC_PLUGIN_DIR . 'includes/activity-log.php';    // Include activity log system
require_once WPSEC_PLUGIN_DIR . 'includes/activity-hooks.php';    // Include activity log hooks
// require_once WPSEC_PLUGIN_DIR . 'includes/admin-tools.php';    // Include admin tools - DISABLED

// Load firewall components
require_once WPSEC_PLUGIN_DIR . 'includes/firewall/class-wpsec-firewall.php';
require_once WPSEC_PLUGIN_DIR . 'includes/firewall/class-wpsec-firewall-installer.php';

// Initialize the firewall after WordPress core is loaded
add_action('plugins_loaded', function() {
    $firewall = WPSEC_Firewall::get_instance();
    $firewall->init();
}, 1);

// Include all endpoint handlers
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-scan.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-scan-status.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-scan-errors.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-scan-reset.php'; // New scan reset endpoint
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-scan-diagnostics.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-scan-resume.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-results.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-status.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-vulnerabilities.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-site-info.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-updates.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-firewall.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-firewall-debug.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-core-check.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-health.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-fix-permissions.php';

// Backup functionality now handled by separate backup plugin addon
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-file-actions.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-file-inspector.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-file-whitelist.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-core-reinstall.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-core-restore.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-activity-log.php';
require_once WPSEC_PLUGIN_DIR . 'endpoints/endpoint-backup-status.php';

// Initialize backup system
add_action('plugins_loaded', function() {
    // Ensure temp directory exists
    $temp_dir = WP_CONTENT_DIR . '/wpsec-temp';
    if (!file_exists($temp_dir)) {
        wp_mkdir_p($temp_dir);
    }
    
    // Initialize activity log tables if they don't exist
    if (function_exists('wpsec_activity_log_init')) {
        wpsec_activity_log_init();
    }
}, 1);

// Add API key validation function
function wpsec_validate_api_key() {
    $api_key = 'sadasda78as78sda78sda78sfa687fajk';
    update_option('wpsec_api_key', $api_key);
    
    // Try apache_request_headers first
    if (function_exists('apache_request_headers')) {
        $headers = apache_request_headers();
        if (isset($headers['X-Api-Key']) || isset($headers['x-api-key'])) {
            $api_key = isset($headers['X-Api-Key']) ? $headers['X-Api-Key'] : $headers['x-api-key'];
        }
    }
    
    // If not found, try $_SERVER variables
    if (empty($api_key)) {
        $api_key = isset($_SERVER['HTTP_X_API_KEY']) ? $_SERVER['HTTP_X_API_KEY'] : '';
    }

    // Add error logging for debugging
    wpsec_debug_log('WPSEC Debug - Received API Key: ' . $api_key, 'debug');
    wpsec_debug_log('WPSEC Debug - Expected API Key: sadasda78as78sda78sda78sfa687fajk', 'debug');
    wpsec_debug_log('WPSEC Debug - Headers: ' . print_r($_SERVER, true), 'debug');
    
    return $api_key === 'sadasda78as78sda78sda78sfa687fajk';
}

// Register REST API endpoints
add_action('rest_api_init', function () {
    // Scan endpoints
    register_rest_route('wpsec/v1', '/scan', [
        'methods' => 'POST',
        'callback' => 'wpsec_scan_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/scan-status/(?P<scan_id>[\w\.]+)', [
        'methods' => 'GET',
        'callback' => 'wpsec_get_scan_status_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/resume-scan', [
        'methods' => 'POST',
        'callback' => 'wpsec_resume_scan_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/results', [
        'methods' => 'GET',
        'callback' => 'wpsec_results_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // Backup endpoints
    // List backups endpoint
    register_rest_route('wpsec/v1', '/backup/list', [
        'methods' => ['GET', 'POST'],
        'callback' => function(WP_REST_Request $request) {
            $backup_endpoint = new WPSEC_Backup_Endpoint();
            return $backup_endpoint->list_backups($request);
        },
        'permission_callback' => function(WP_REST_Request $request) {
            $backup_endpoint = new WPSEC_Backup_Endpoint();
            return $backup_endpoint->verify_api_key($request);
        }
    ]);
    
    // Start backup endpoint
    register_rest_route('wpsec/v1', '/backup/start', [
        'methods' => 'POST',
        'callback' => function(WP_REST_Request $request) {
            $backup_endpoint = new WPSEC_Backup_Endpoint();
            return $backup_endpoint->start_backup($request);
        },
        'permission_callback' => function(WP_REST_Request $request) {
            $backup_endpoint = new WPSEC_Backup_Endpoint();
            return $backup_endpoint->verify_api_key($request);
        }
    ]);
    
    // Get backup status endpoint
    register_rest_route('wpsec/v1', '/backup/status/(?P<backup_id>[0-9a-zA-Z_.]+)', [
        'methods' => ['GET', 'POST'],
        'callback' => function(WP_REST_Request $request) {
            $backup_endpoint = new WPSEC_Backup_Endpoint();
            return $backup_endpoint->get_backup_status($request);
        },
        'permission_callback' => function(WP_REST_Request $request) {
            $backup_endpoint = new WPSEC_Backup_Endpoint();
            return $backup_endpoint->verify_api_key($request);
        }
    ]);
    
    // Backup routes are now handled by the modular backup plugin
    // End of backup endpoints

    register_rest_route('wpsec/v1', '/scan/(?P<id>[a-zA-Z0-9-]+)/results', [
        'methods' => 'GET',
        'callback' => 'wpsec_scan_results_endpoint',
        'permission_callback' => '__return_true'
    ]);

    // Vulnerability endpoints
    register_rest_route('wpsec/v1', '/vulnerabilities', [
        'methods' => 'GET',
        'callback' => 'wpsec_vulnerabilities_endpoint',
        'permission_callback' => '__return_true'
    ]);

    // Update endpoints
    register_rest_route('wpsec/v1', '/update-items', [
        'methods' => 'POST',
        'callback' => 'wpsec_update_items_endpoint',
        'permission_callback' => '__return_true',
        'args' => [
            'items' => ['required' => true],
            'type' => ['required' => true]
        ]
    ]);

    register_rest_route('wpsec/v1', '/update-all', [
        'methods' => 'POST',
        'callback' => 'wpsec_update_all_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // File action endpoints
    register_rest_route('wpsec/v1', '/batch-actions', [
        'methods' => 'POST',
        'callback' => 'wpsec_batch_file_actions_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/quarantine', [
        'methods' => 'POST',
        'callback' => 'wpsec_quarantine_file_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/delete', [
        'methods' => 'POST',
        'callback' => 'wpsec_delete_file_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/restore', [
        'methods' => 'POST',
        'callback' => 'wpsec_restore_file_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/quarantine-list', [
        'methods' => 'GET',
        'callback' => 'wpsec_list_quarantine_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // File inspection endpoints
    // New smart endpoint that only requires file_path
    register_rest_route('wpsec/v1', '/inspect-file', [
        'methods' => 'POST',
        'callback' => 'wpsec_smart_inspect_file_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // Keep original endpoint for backward compatibility
    register_rest_route('wpsec/v1', '/inspect-file-with-details', [
        'methods' => 'POST',
        'callback' => 'wpsec_inspect_file_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/inspect-scan-results', [
        'methods' => 'POST',
        'callback' => 'wpsec_inspect_scan_results_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // File whitelist endpoints
    register_rest_route('wpsec/v1', '/whitelist', [
        'methods' => 'POST',
        'callback' => 'wpsec_whitelist_file_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/whitelist/remove', [
        'methods' => 'POST',
        'callback' => 'wpsec_remove_from_whitelist_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/whitelist/list', [
        'methods' => 'GET',
        'callback' => 'wpsec_get_whitelisted_files_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/whitelist/verify', [
        'methods' => 'GET',
        'callback' => 'wpsec_verify_whitelist_integrity_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/whitelist/cleanup', [
        'methods' => 'POST',
        'callback' => 'wpsec_cleanup_whitelist_endpoint',
        'permission_callback' => '__return_true'
    ]);

    // Firewall endpoints
    register_rest_route('wpsec/v1', '/firewall/status', [
        'methods' => 'GET',
        'callback' => 'wpsec_firewall_status_endpoint',
        'permission_callback' => '__return_true'
    ]);

    register_rest_route('wpsec/v1', '/firewall/toggle', [
        'methods' => 'POST',
        'callback' => 'wpsec_firewall_toggle_endpoint',
        'permission_callback' => '__return_true'
    ]);

    register_rest_route('wpsec/v1', '/firewall/logs', [
        'methods' => 'GET',
        'callback' => 'wpsec_firewall_logs_endpoint',
        'permission_callback' => '__return_true'
    ]);

    register_rest_route('wpsec/v1', '/firewall/whitelist', [
        'methods' => array('GET', 'POST', 'DELETE'),
        'callback' => 'wpsec_firewall_whitelist_endpoint',
        'permission_callback' => '__return_true'
    ]);

    register_rest_route('wpsec/v1', '/firewall/test-results', [
        'methods' => 'GET',
        'callback' => 'wpsec_firewall_test_results_endpoint',
        'permission_callback' => '__return_true'
    ]);

    // Site info endpoints
    register_rest_route('wpsec/v1', '/site-info', [
        'methods' => 'GET',
        'callback' => 'wpsec_site_info_endpoint',
        'permission_callback' => '__return_true'
    ]);

    // Update endpoints
    register_rest_route('wpsec/v1', '/updates', [
        'methods' => 'GET',
        'callback' => 'wpsec_updates_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // Core reinstall endpoint
    register_rest_route('wpsec/v1', '/core-reinstall', [
        'methods' => ['GET', 'POST'],
        'callback' => 'wpsec_core_reinstall_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // Core restore endpoints
    register_rest_route('wpsec/v1', '/core-restore/list', [
        'methods' => 'GET',
        'callback' => 'wpsec_core_restore_list_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    // Activity Log endpoints
    register_rest_route('wpsec/v1', '/activity-log', [
        'methods' => 'GET',
        'callback' => 'wpsec_activity_log_get_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/activity-log/settings', [
        'methods' => ['GET', 'POST'],
        'callback' => 'wpsec_activity_log_settings_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/activity-log/clear', [
        'methods' => 'POST',
        'callback' => 'wpsec_activity_log_clear_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/activity-log/summary', [
        'methods' => 'GET',
        'callback' => 'wpsec_activity_log_summary_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/activity-log/export', [
        'methods' => 'GET',
        'callback' => 'wpsec_activity_log_export_endpoint',
        'permission_callback' => '__return_true'
    ]);
    
    register_rest_route('wpsec/v1', '/core-restore', [
        'methods' => ['GET', 'POST'],
        'callback' => 'wpsec_core_restore_endpoint',
        'permission_callback' => '__return_true'
    ]);
});

// Create directories for engines if needed
if (!file_exists(WPSEC_PLUGIN_DIR . 'includes/engines')) {
    // Initialize WordPress Filesystem
    global $wp_filesystem;
    if (empty($wp_filesystem)) {
        require_once(ABSPATH . 'wp-admin/includes/file.php');
        WP_Filesystem();
    }
    
    // Create directory using WordPress Filesystem API
    $wp_filesystem->mkdir(WPSEC_PLUGIN_DIR . 'includes/engines', FS_CHMOD_DIR);
}

// Load engine files
require_once WPSEC_PLUGIN_DIR . 'includes/engines/signature.php';
require_once WPSEC_PLUGIN_DIR . 'includes/engines/pattern.php';
require_once WPSEC_PLUGIN_DIR . 'includes/engines/anomaly.php';
require_once WPSEC_PLUGIN_DIR . 'includes/engines/heuristic.php';

// Load whitelist and scan file last (since they depend on the engines)
require_once WPSEC_PLUGIN_DIR . 'includes/whitelist.php';
require_once WPSEC_PLUGIN_DIR . 'includes/scan.php';
// Scan checkpoints have been removed in favor of a simpler scanning mechanism
require_once WPSEC_PLUGIN_DIR . 'includes/scan-reset.php'; // New scan reset functionality
require_once WPSEC_PLUGIN_DIR . 'includes/scan-monitor.php';
require_once WPSEC_PLUGIN_DIR . 'includes/file-whitelist.php';
require_once WPSEC_PLUGIN_DIR . 'includes/scan-zombie-detector.php'; // Automatic zombie scan detection and recovery

// Initialize the rest of the plugin normally
add_action('init', function() {
    if (!defined('SIMULATE_ATTACKS')) {
        // Load other plugin components
        require_once plugin_dir_path(__FILE__) . 'includes/class-wpsec-plugin.php';
        WPSEC_Plugin::get_instance();
    }
});

// Register backup processing hook
add_action('wpsec_process_backup', function($backup_id, $type) {
    $backup_manager = new WPSEC_Backup_Manager();
    $backup_manager->process_backup($backup_id, $type);
}, 10, 2);

// Ensure backup cron tasks run frequently
add_filter('cron_schedules', function($schedules) {
    $schedules['wpsec_backup_interval'] = array(
        'interval' => 60, // Run every minute
        'display' => 'Every Minute'
    );
    return $schedules;
});

// Add backup processing schedule
add_action('init', function() {
    if (!wp_next_scheduled('wpsec_process_pending_backups')) {
        wp_schedule_event(time(), 'wpsec_backup_interval', 'wpsec_process_pending_backups');
    }
});

// Process pending backups
add_action('wpsec_process_pending_backups', function() {
    global $wpdb;
    
    // Get pending backups
    $pending_backups = $wpdb->get_results(
        "SELECT option_name, option_value FROM $wpdb->options 
         WHERE option_name LIKE 'wpsec_backup_%'
         AND option_value LIKE '%\"status\":\"processing\"%'",
        ARRAY_A
    );

    if (!empty($pending_backups)) {
        foreach ($pending_backups as $backup) {
            $data = maybe_unserialize($backup['option_value']);
            if (isset($data['id']) && isset($data['type']) && $data['status'] === 'processing') {
                do_action('wpsec_process_backup', $data['id'], $data['type']);
            }
        }
    }
});

// Backup cron jobs are registered earlier in the file

// REMOVED: Activation hook moved to activation-fix.php
// register_activation_hook(__FILE__, function() {
//     WPSEC_Firewall_Installer::install();
// });

// REMOVED: Activation hook moved to activation-fix.php
// register_activation_hook(__FILE__, function () {
//     if (!get_option('wpsec_api_key')) {
//         add_option('wpsec_api_key', 'sadasda78as78sda78sda78sfa687fajk');
//     }
//     
//     
//     // Initial download of signature databases
//     wpsec_get_signature_database();
//     wpsec_get_pattern_database();
// });

// Schedule daily scans
if (!wp_next_scheduled('wpsec_run_background_scan')) {
    wp_schedule_event(time(), 'daily', 'wpsec_run_background_scan');
}

add_action('wpsec_run_background_scan', 'wpsec_run_scan');

// Register backup cron hook
add_action('wpsec_process_backup', array('WPSEC_Backup_Manager', 'process_backup'), 10, 2);

// Add a "Scan Now" admin bar button
add_action('admin_bar_menu', function($admin_bar) {
    if (current_user_can('administrator')) {
        $admin_bar->add_menu([
            'id'    => 'wpsec-scan',
            'title' => 'Scan for Malware',
            'href'  => wp_nonce_url(admin_url('admin-ajax.php?action=wpsec_manual_scan'), 'wpsec_manual_scan'),
            'meta'  => [
                'title' => 'Run a security scan'
            ]
        ]);
    }
}, 100);

// Handle the AJAX request for manual scanning
add_action('wp_ajax_wpsec_manual_scan', function() {
    check_admin_referer('wpsec_manual_scan');
    
    if (!current_user_can('administrator')) {
        wp_die('Unauthorized access');
    }
    
    // Redirect to admin page and show a notice
    update_option('wpsec_manual_scan_triggered', 1);
    
    // Run scan in the background
    wp_schedule_single_event(time(), 'wpsec_run_background_scan');
    
    wp_redirect(admin_url());
    exit;
});

// Show notices
add_action('admin_notices', function() {
    if (get_option('wpsec_manual_scan_triggered')) {
        delete_option('wpsec_manual_scan_triggered');
        echo '<div class="notice notice-info is-dismissible"><p>Malware scan has been started in the background. Results will be available when the scan completes.</p></div>';
    }
});

// Backup cron jobs are registered earlier in the file

// REMOVED: Activation hook moved to activation-fix.php
// register_activation_hook(__FILE__, function() {
//     WPSEC_Firewall_Installer::install();
// });

// REMOVED: Activation hook moved to activation-fix.php
// register_activation_hook(__FILE__, function () {
//     if (!get_option('wpsec_api_key')) {
//         add_option('wpsec_api_key', 'sadasda78as78sda78sda78sfa687fajk');
//     }
//     
//     
//     // Initial download of signature databases
//     wpsec_get_signature_database();
//     wpsec_get_pattern_database();
// });

// Schedule daily scans
if (!wp_next_scheduled('wpsec_run_background_scan')) {
    wp_schedule_event(time(), 'daily', 'wpsec_run_background_scan');
}

add_action('wpsec_run_background_scan', 'wpsec_run_scan');

// Register backup cron hook
add_action('wpsec_process_backup', array('WPSEC_Backup_Manager', 'process_backup'), 10, 2);

// Add a "Scan Now" admin bar button
add_action('admin_bar_menu', function($admin_bar) {
    if (current_user_can('administrator')) {
        $admin_bar->add_menu([
            'id'    => 'wpsec-scan',
            'title' => 'Scan for Malware',
            'href'  => wp_nonce_url(admin_url('admin-ajax.php?action=wpsec_manual_scan'), 'wpsec_manual_scan'),
            'meta'  => [
                'title' => 'Run a security scan'
            ]
        ]);
    }
}, 100);

// Handle the AJAX request for manual scanning
add_action('wp_ajax_wpsec_manual_scan', function() {
    check_admin_referer('wpsec_manual_scan');
    
    if (!current_user_can('administrator')) {
        wp_die('Unauthorized access');
    }
    
    // Redirect to admin page and show a notice
    update_option('wpsec_manual_scan_triggered', 1);
    
    // Run scan in the background
    wp_schedule_single_event(time(), 'wpsec_run_background_scan');
    
    wp_redirect(admin_url());
    exit;
});

// Show notices
add_action('admin_notices', function() {
    if (get_option('wpsec_manual_scan_triggered')) {
        delete_option('wpsec_manual_scan_triggered');
        echo '<div class="notice notice-info is-dismissible"><p>Malware scan has been started in the background. Results will be available when the scan completes.</p></div>';
    }
});