#include "response_stream_utils.h"

#include <util/generic/overloaded.h>

namespace NHttp::NUtils {
void ReadAll(IResponseStream& responseStream, TInstant deadline, TReadAllHandler callback) noexcept {
    class THandler {
      public:
        void operator()(IResponseStream::TReadResult result) {
            if (result.IsError()) {
                return Callback(std::move(result.Error()));
            }

            if (result.Success().Empty()) {
                return Callback(std::move(FullResponse));
            }

            if (!FullResponse.Defined()) {
                FullResponse.ConstructInPlace();
            }

            std::visit(TOverloaded{
                    [&](TResponseHeadFrame& head) { FullResponse->Head = std::move(head); },
                    [&](TDataFrame& data) { FullResponse->Body.Append(std::move(data)); },
                    [&](THeadersFrame& trailer) { FullResponse->Trailer = std::move(trailer); },
            }, result.Success().GetRef());

            return Stream.Read(0, false, Deadline, THandler{
                    .Callback = std::move(Callback),
                    .Stream = Stream,
                    .Deadline = Deadline,
                    .FullResponse = std::move(FullResponse)
            });
        }

        TReadAllHandler Callback;
        IResponseStream& Stream;
        TInstant Deadline;
        TMaybe<TFullResponse> FullResponse;
    };
    responseStream.Read(0, false, deadline, THandler{
            .Callback = std::move(callback),
            .Stream = responseStream,
            .Deadline = deadline
    });
}
}
