<?php

declare (strict_types=1);
namespace GDAVSCOPE\Amp\Http\Client\Interceptor;

use GDAVSCOPE\Amp\Cancellation;
use GDAVSCOPE\Amp\ForbidCloning;
use GDAVSCOPE\Amp\ForbidSerialization;
use GDAVSCOPE\Amp\Http\Client\ApplicationInterceptor;
use GDAVSCOPE\Amp\Http\Client\Connection\Stream;
use GDAVSCOPE\Amp\Http\Client\DelegateHttpClient;
use GDAVSCOPE\Amp\Http\Client\NetworkInterceptor;
use GDAVSCOPE\Amp\Http\Client\Request;
use GDAVSCOPE\Amp\Http\Client\Response;
class ModifyResponse implements NetworkInterceptor, ApplicationInterceptor
{
    use ForbidCloning;
    use ForbidSerialization;
    /**
     * @param \Closure(Response):Response $mapper
     */
    public function __construct(private readonly \Closure $mapper)
    {
    }
    final public function requestViaNetwork(Request $request, Cancellation $cancellation, Stream $stream): Response
    {
        $response = $stream->request($request, $cancellation);
        $mappedResponse = ($this->mapper)($response);
        \assert($mappedResponse instanceof Response || $mappedResponse === null);
        return $mappedResponse ?? $response;
    }
    public function request(Request $request, Cancellation $cancellation, DelegateHttpClient $httpClient): Response
    {
        $request->interceptPush(fn(Request $request, Response $response) => ($this->mapper)($response));
        $response = $httpClient->request($request, $cancellation);
        $mappedResponse = ($this->mapper)($response);
        \assert($mappedResponse instanceof Response || $mappedResponse === null);
        return $mappedResponse ?? $response;
    }
}
