<?php
/**
 * VMPFence Secure HTTP Client
 * 
 * Wrapper around WordPress HTTP API (wp_remote_get/post) with automatic
 * URL and response sanitization before logging. Prevents API keys and
 * sensitive data from appearing in debug logs.
 *
 * @package VMPFence
 * @since 1.0.0
 */

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

class VMPFence_Secure_HTTP_Client {
    
    /**
     * Make a GET request with automatic sanitization
     *
     * @param string $url Request URL
     * @param array $args Optional. Request arguments (same as wp_remote_get)
     * @return array|WP_Error Response array or WP_Error on failure
     */
    public static function get($url, $args = array()) {
        return self::request($url, array_merge($args, array('method' => 'GET')));
    }
    
    /**
     * Make a POST request with automatic sanitization
     *
     * @param string $url Request URL
     * @param array $args Optional. Request arguments (same as wp_remote_post)
     * @return array|WP_Error Response array or WP_Error on failure
     */
    public static function post($url, $args = array()) {
        return self::request($url, array_merge($args, array('method' => 'POST')));
    }
    
    /**
     * Make HTTP request with automatic sanitization
     *
     * @param string $url Request URL
     * @param array $args Request arguments
     * @return array|WP_Error Response array or WP_Error on failure
     */
    public static function request($url, $args = array()) {
        $method = isset($args['method']) ? strtoupper($args['method']) : 'GET';
        
        // Log request with sanitized URL (if Secure Logger available)
        if (class_exists('VMPFence_Secure_Logger')) {
            VMPFence_Secure_Logger::debug("HTTP {$method} request", array(
                'url' => $url,  // Secure Logger will auto-sanitize
                'timeout' => isset($args['timeout']) ? $args['timeout'] : 5
            ));
        }
        
        // Make the actual request
        $response = wp_remote_request($url, $args);
        
        // Handle errors with sanitized logging
        if (is_wp_error($response)) {
            self::log_error($url, $response);
            return $response;
        }
        
        // Check HTTP status code
        $status_code = wp_remote_retrieve_response_code($response);
        if ($status_code >= 400) {
            self::log_http_error($url, $status_code, $response);
        }
        
        return $response;
    }
    
    /**
     * Log WP_Error with sanitized URL
     *
     * @param string $url Original URL
     * @param WP_Error $error WordPress error object
     */
    private static function log_error($url, $error) {
        if (class_exists('VMPFence_Secure_Logger')) {
            VMPFence_Secure_Logger::error('HTTP request failed', array(
                'url' => $url,  // Auto-sanitized by Secure Logger
                'error' => $error->get_error_message(),
                'code' => $error->get_error_code()
            ));
        }
    }
    
    /**
     * Log HTTP error response with sanitized data
     *
     * @param string $url Original URL
     * @param int $status_code HTTP status code
     * @param array $response Response array
     */
    private static function log_http_error($url, $status_code, $response) {
        if (class_exists('VMPFence_Secure_Logger')) {
            $body = wp_remote_retrieve_body($response);
            $body_preview = strlen($body) > 200 ? substr($body, 0, 200) . '...' : $body;
            
            VMPFence_Secure_Logger::warning('HTTP request returned error status', array(
                'url' => $url,  // Auto-sanitized by Secure Logger
                'status' => $status_code,
                'response_preview' => $body_preview
            ));
        }
    }
    
    /**
     * Sanitize URL for logging (strip sensitive parameters)
     * 
     * This is a backup method in case Secure Logger is not available.
     * Normally, Secure Logger handles all sanitization automatically.
     *
     * @param string $url URL to sanitize
     * @return string Sanitized URL
     */
    public static function sanitize_url_for_logging($url) {
        // If Secure Logger available, use its sanitization
        if (class_exists('VMPFence_Secure_Logger')) {
            return VMPFence_Secure_Logger::sanitize_value($url);
        }
        
        // Fallback: manual sanitization
        $sensitive_params = array('api_key', 'apikey', 'key', 'token', 'auth', 'password', 'secret');
        
        foreach ($sensitive_params as $param) {
            // Match both ?param= and &param= patterns
            $url = preg_replace(
                '/([?&])' . preg_quote($param, '/') . '=[^&]*/i',
                '$1' . $param . '=[REDACTED]',
                $url
            );
        }
        
        return $url;
    }
    
    /**
     * Check if response is successful (2xx status code)
     *
     * @param array|WP_Error $response Response from wp_remote_request
     * @return bool True if successful, false otherwise
     */
    public static function is_success($response) {
        if (is_wp_error($response)) {
            return false;
        }
        
        $status_code = wp_remote_retrieve_response_code($response);
        return $status_code >= 200 && $status_code < 300;
    }
    
    /**
     * Get response body from HTTP response
     *
     * @param array|WP_Error $response Response from wp_remote_request
     * @return string|false Response body or false on error
     */
    public static function get_body($response) {
        if (is_wp_error($response)) {
            return false;
        }
        
        return wp_remote_retrieve_body($response);
    }
    
    /**
     * Get JSON response body
     *
     * @param array|WP_Error $response Response from wp_remote_request
     * @param bool $assoc Return as associative array (default: true)
     * @return array|object|false Decoded JSON or false on error
     */
    public static function get_json($response, $assoc = true) {
        $body = self::get_body($response);
        
        if ($body === false) {
            return false;
        }
        
        $data = json_decode($body, $assoc);
        
        if (json_last_error() !== JSON_ERROR_NONE) {
            if (class_exists('VMPFence_Secure_Logger')) {
                VMPFence_Secure_Logger::error('Failed to decode JSON response', array(
                    'error' => json_last_error_msg()
                ));
            }
            return false;
        }
        
        return $data;
    }
}
