<?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\DelegateHttpClient;
use GDAVSCOPE\Amp\Http\Client\HttpException;
use GDAVSCOPE\Amp\Http\Client\Request;
use GDAVSCOPE\Amp\Http\Client\Response;
final class RetryRequests implements ApplicationInterceptor
{
    use ForbidCloning;
    use ForbidSerialization;
    public function __construct(private readonly int $retryLimit)
    {
    }
    public function request(Request $request, Cancellation $cancellation, DelegateHttpClient $httpClient): Response
    {
        $attempt = 1;
        do {
            $clonedRequest = clone $request;
            try {
                return $httpClient->request($request, $cancellation);
            } catch (HttpException $exception) {
                if ($request->isIdempotent() || $request->isUnprocessed()) {
                    // Request was deemed retryable by connection, so carry on.
                    $request = $clonedRequest;
                    continue;
                }
                throw $exception;
            }
        } while ($attempt++ <= $this->retryLimit);
        throw $exception;
    }
}
