<?php

namespace WP_Ultimo\Dependencies\Amp\Http\Client\Connection;

use WP_Ultimo\Dependencies\Amp\CancellationToken;
use WP_Ultimo\Dependencies\Amp\Http\Client\Internal\ForbidCloning;
use WP_Ultimo\Dependencies\Amp\Http\Client\Internal\ForbidSerialization;
use WP_Ultimo\Dependencies\Amp\Http\Client\NetworkInterceptor;
use WP_Ultimo\Dependencies\Amp\Http\Client\Request;
use WP_Ultimo\Dependencies\Amp\Promise;
use WP_Ultimo\Dependencies\Amp\Socket\SocketAddress;
use WP_Ultimo\Dependencies\Amp\Socket\TlsInfo;
use function WP_Ultimo\Dependencies\Amp\call;
final class InterceptedStream implements Stream
{
    use ForbidCloning;
    use ForbidSerialization;
    /** @var Stream */
    private $stream;
    /** @var NetworkInterceptor|null */
    private $interceptor;
    public function __construct(Stream $stream, NetworkInterceptor $interceptor)
    {
        $this->stream = $stream;
        $this->interceptor = $interceptor;
    }
    public function request(Request $request, CancellationToken $cancellation) : Promise
    {
        if (!$this->interceptor) {
            throw new \Error(__METHOD__ . ' may only be invoked once per instance. ' . 'If you need to implement retries or otherwise issue multiple requests, register an ApplicationInterceptor to do so.');
        }
        $interceptor = $this->interceptor;
        $this->interceptor = null;
        return call(function () use($interceptor, $request, $cancellation) {
            foreach ($request->getEventListeners() as $eventListener) {
                (yield $eventListener->startRequest($request));
            }
            return $interceptor->requestViaNetwork($request, $cancellation, $this->stream);
        });
    }
    public function getLocalAddress() : SocketAddress
    {
        return $this->stream->getLocalAddress();
    }
    public function getRemoteAddress() : SocketAddress
    {
        return $this->stream->getRemoteAddress();
    }
    public function getTlsInfo() : ?TlsInfo
    {
        return $this->stream->getTlsInfo();
    }
}
