<?php
/**
 * VMPFence cURL Interceptor Class
 * 
 * Hooks into WordPress HTTP API to force IPv4-only connections for scan operations
 *
 * @package VMPFence
 * @since 1.0.0
 */

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

/**
 * Exception thrown when cURL interception fails
 */
class VMPFence_Curl_Interception_Failed_Exception extends RuntimeException {
}

/**
 * VMPFence cURL Interceptor
 * 
 * Intercepts WordPress HTTP API cURL requests to apply IPv4-only resolution
 */
class VMPFence_Curl_Interceptor {

    /**
     * WordPress HTTP API cURL hook name
     */
    const HOOK_NAME = 'http_api_curl';

    /**
     * Current cURL handle
     *
     * @var resource|null
     */
    private $handle = null;

    /**
     * cURL options to apply
     *
     * @var array
     */
    private $options = array();

    /**
     * Whether interception is required
     *
     * @var bool
     */
    private $require_interception;

    /**
     * Constructor
     *
     * @param bool $require_interception Whether to require successful interception
     */
    public function __construct($require_interception = true) {
        $this->require_interception = $require_interception;
    }

    /**
     * Reset interceptor state
     */
    private function reset() {
        $this->handle = null;
    }

    /**
     * Set cURL option to apply during interception
     *
     * @param int $option cURL option constant
     * @param mixed $value Option value
     */
    public function setOption($option, $value) {
        $this->options[$option] = $value;
    }

    /**
     * Get the current cURL handle
     *
     * @return resource|null
     */
    public function getHandle() {
        return $this->handle;
    }

    /**
     * Handle WordPress HTTP API cURL hook
     *
     * @param resource $handle cURL handle
     */
    public function handleHook($handle) {
        $this->handle = $handle;
        // phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt_array -- Modifying WordPress-created cURL handle via http_api_curl hook
        curl_setopt_array($handle, $this->options);
    }

    /**
     * Intercept WordPress HTTP API calls and apply cURL options
     *
     * @param callable $callable Function to execute with interception
     * @return mixed Result of the callable
     * @throws VMPFence_Curl_Interception_Failed_Exception
     */
    public function intercept($callable) {
        $this->reset();
        $action = array($this, 'handleHook');
        
        // Add hook to intercept cURL handle
        add_action(self::HOOK_NAME, $action);
        
        // Execute the HTTP request
        $result = $callable();
        
        // Check if interception was successful when required
        if ($this->handle === null && $this->require_interception) {
            remove_action(self::HOOK_NAME, $action);
            throw new VMPFence_Curl_Interception_Failed_Exception('Hook was not invoked with a valid cURL handle');
        }
        
        // Clean up hook
        remove_action(self::HOOK_NAME, $action);
        
        return $result;
    }
}