<?php
declare(strict_types=1);
namespace App\Services;

use App\Security\RequestSecurity;
use RuntimeException;

final class SecureHttpClient
{
    /** @param array<string,string> $headers @return array{status:int,headers:string,body:string} */
    public function request(string $method, string $url, array $headers = [], ?string $body = null, array $allowedHosts = []): array
    {
        if (!extension_loaded('curl')) throw new RuntimeException('Extension cURL requise.');
        $safeUrl = RequestSecurity::assertOutboundUrl($url, $allowedHosts);
        $ch = curl_init($safeUrl);
        if ($ch === false) throw new RuntimeException('Initialisation HTTP impossible.');
        $headerLines = [];
        foreach ($headers as $name => $value) {
            if (!preg_match('/^[A-Za-z0-9-]{1,64}$/', $name) || preg_match('/[\r\n]/', $value)) throw new RuntimeException('En-tête HTTP sortant invalide.');
            $headerLines[] = $name . ': ' . $value;
        }
        curl_setopt_array($ch, [
            CURLOPT_CUSTOMREQUEST => strtoupper($method), CURLOPT_RETURNTRANSFER => true,
            CURLOPT_HEADER => true, CURLOPT_FOLLOWLOCATION => false, CURLOPT_PROTOCOLS => CURLPROTO_HTTPS,
            CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTPS, CURLOPT_CONNECTTIMEOUT => 5, CURLOPT_TIMEOUT => 20,
            CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2, CURLOPT_HTTPHEADER => $headerLines,
            CURLOPT_USERAGENT => 'AXIOM-CDA-SecureClient/1.0',
        ]);
        if ($body !== null) curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
        $response = curl_exec($ch);
        if ($response === false) { $error = curl_error($ch); curl_close($ch); throw new RuntimeException('Communication externe impossible : ' . $error); }
        $status = (int)curl_getinfo($ch, CURLINFO_RESPONSE_CODE);
        $headerSize = (int)curl_getinfo($ch, CURLINFO_HEADER_SIZE);
        curl_close($ch);
        return ['status'=>$status,'headers'=>substr($response,0,$headerSize),'body'=>substr($response,$headerSize)];
    }
}
