<?php
defined('ABSPATH') || exit;

/**
 * Core Restore API Endpoints
 * 
 * Provides API endpoints for restoring WordPress core files from backups
 */

/**
 * Handle the core restore list endpoint request
 * 
 * @param WP_REST_Request $request The request object
 * @return WP_REST_Response|WP_Error The response
 */
function wpsec_core_restore_list_endpoint($request) {
    // Debug logging
    wpsec_log('Core restore list endpoint called', 'action');
    
    // Validate API key
    if (!wpsec_validate_api_key()) {
        wpsec_log('API key validation failed for core restore list', 'error');
        return new WP_Error(
            'rest_forbidden',
            'Sorry, you are not allowed to do that.',
            array('status' => 401)
        );
    }
    
    // Get available backups
    $backups = wpsec_get_core_backups();
    
    return rest_ensure_response(array(
        'status' => 'success',
        'backups' => $backups,
        'count' => count($backups)
    ));
}

/**
 * Handle the core restore endpoint request
 * 
 * @param WP_REST_Request $request The request object
 * @return WP_REST_Response|WP_Error The response
 */
function wpsec_core_restore_endpoint($request) {
    // Debug logging
    wpsec_log('Core restore endpoint called', 'action');
    
    // Validate API key
    if (!wpsec_validate_api_key()) {
        wpsec_log('API key validation failed for core restore', 'error');
        return new WP_Error(
            'rest_forbidden',
            'Sorry, you are not allowed to do that.',
            array('status' => 401)
        );
    }
    
    // Check if this is a GET request (status check) or a POST request (start restore)
    $method = $request->get_method();
    
    if ($method === 'GET') {
        // Check status of an existing operation
        $operation_id = $request->get_param('operation_id');
        
        if (empty($operation_id)) {
            wpsec_log('Missing operation_id parameter for core restore status check', 'error');
            return new WP_Error(
                'missing_parameter',
                'Missing required parameter: operation_id',
                array('status' => 400)
            );
        }
        
        $status = wpsec_get_core_restore_status($operation_id);
        
        if (is_wp_error($status)) {
            wpsec_log('Failed to get core restore status: ' . $status->get_error_message(), 'error');
            return $status;
        }
        
        return rest_ensure_response(array(
            'status' => 'success',
            'operation_id' => $operation_id,
            'operation_status' => $status['status'],
            'progress' => $status['progress'],
            'message' => isset($status['status_message']) ? $status['status_message'] : '',
            'started_at' => $status['started_at'],
            'completed_at' => isset($status['completed_at']) ? $status['completed_at'] : null,
            'backup_id' => $status['backup_id'],
            'log' => array_slice($status['log'], -10) // Return only the last 10 log entries for brevity
        ));
    } else {
        // Start a new restore operation
        $backup_id = $request->get_param('backup_id');
        $skip_content = $request->get_param('skip_content');
        $skip_config = $request->get_param('skip_config');
        
        if (empty($backup_id)) {
            wpsec_log('Missing backup_id parameter for core restore', 'error');
            return new WP_Error(
                'missing_parameter',
                'Missing required parameter: backup_id',
                array('status' => 400)
            );
        }
        
        // Set defaults
        $skip_content = isset($skip_content) ? (bool)$skip_content : true;
        $skip_config = isset($skip_config) ? (bool)$skip_config : true;
        
        wpsec_log('Starting core restore operation for backup: ' . $backup_id, 'action');
        
        // Validate that WordPress has the necessary permissions
        if (!wpsec_core_reinstall_check_permissions()) {
            wpsec_log('Insufficient filesystem permissions for core restore', 'error');
            return new WP_Error(
                'insufficient_permissions',
                'WordPress does not have sufficient permissions to modify core files. Please check file ownership and permissions.',
                array('status' => 403)
            );
        }
        
        // Prepare options
        $options = array(
            'skip_content' => $skip_content,
            'skip_config' => $skip_config
        );
        
        // Ensure core-restore.php is loaded
        require_once WPSEC_PLUGIN_DIR . 'includes/core-restore.php';
        
        // Start the restore process
        ignore_user_abort(true);
        set_time_limit(0);
        
        // Start the operation in the background if possible
        if (function_exists('fastcgi_finish_request')) {
            // Generate a unique operation ID
            $operation_id = uniqid('wpsec_core_restore_', true);
            
            // Initialize the status data structure now, before we send the response
            $status = array(
                'id' => $operation_id,
                'started_at' => current_time('mysql'),
                'status' => 'preparing',
                'progress' => 0,
                'backup_id' => $backup_id,
                'options' => $options,
                'log' => array('Core restore operation initialized')
            );
            update_option('wpsec_core_restore_' . $operation_id, $status);
            
            // Make sure there's no previous output
            if (ob_get_level()) {
                ob_clean();
            }
            
            // Send response immediately
            $response = array(
                'status' => 'success',
                'message' => 'WordPress core restore started',
                'operation_id' => $operation_id,
                'backup_id' => $backup_id,
                'started_at' => current_time('mysql'),
                'check_status_endpoint' => rest_url('wpsec/v1/core-restore?operation_id=' . $operation_id)
            );
            
            // Use wp_send_json which handles headers and encoding properly
            wp_send_json($response);
            // The above function will exit, but in case it doesn't:
            exit;
            
            @ob_end_flush();
            @flush();
            
            fastcgi_finish_request();
            
            // Now run the restore
            wpsec_restore_core_from_backup($backup_id, $options);
        } else {
            // No FastCGI - have to run in a separate process
            // Schedule a single event to run immediately
            wp_schedule_single_event(time(), 'wpsec_core_restore_cron', array($backup_id, $options));
            
            $operation_id = uniqid('wpsec_core_restore_', true);
            
            // Initialize status data for the scheduled task
            $status = array(
                'id' => $operation_id,
                'started_at' => current_time('mysql'),
                'status' => 'scheduled',
                'progress' => 0,
                'backup_id' => $backup_id,
                'options' => $options,
                'log' => array('Core restore operation scheduled')
            );
            update_option('wpsec_core_restore_' . $operation_id, $status);
            
            return rest_ensure_response(array(
                'status' => 'success',
                'message' => 'WordPress core restore scheduled',
                'operation_id' => $operation_id,
                'backup_id' => $backup_id,
                'started_at' => current_time('mysql'),
                'check_status_endpoint' => rest_url('wpsec/v1/core-restore?operation_id=' . $operation_id)
            ));
        }
    }
}

/**
 * Cron callback to run the core restore
 * 
 * @param string $backup_id The backup ID to restore from
 * @param array $options Options for the restore process
 */
function wpsec_core_restore_cron_callback($backup_id, $options) {
    // Ensure core-restore.php is loaded
    require_once WPSEC_PLUGIN_DIR . 'includes/core-restore.php';
    
    // Run the restore
    wpsec_restore_core_from_backup($backup_id, $options);
}

// Add cron action
add_action('wpsec_core_restore_cron', 'wpsec_core_restore_cron_callback', 10, 2);
