#include "quiche/http2/adapter/test_frame_sequence.h"

#include <memory>
#include <optional>
#include <string>
#include <utility>
#include <vector>

#include "quiche/http2/adapter/http2_util.h"
#include "quiche/http2/adapter/oghttp2_util.h"
#include "quiche/http2/core/spdy_framer.h"
#include "quiche/http2/hpack/hpack_encoder.h"

namespace http2 {
namespace adapter {
namespace test {

std::vector<Header> ToHeaders(
    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers) {
  std::vector<Header> out;
  for (auto [name, value] : headers) {
    out.push_back(std::make_pair(HeaderRep(name), HeaderRep(value)));
  }
  return out;
}

TestFrameSequence& TestFrameSequence::ClientPreface(
    absl::Span<const Http2Setting> settings) {
  preface_ = spdy::kHttp2ConnectionHeaderPrefix;
  return Settings(settings);
}

TestFrameSequence& TestFrameSequence::ServerPreface(
    absl::Span<const Http2Setting> settings) {
  return Settings(settings);
}

TestFrameSequence& TestFrameSequence::Data(Http2StreamId stream_id,
                                           absl::string_view payload, bool fin,
                                           std::optional<int> padding_length) {
  auto data = std::make_unique<spdy::SpdyDataIR>(stream_id, payload);
  data->set_fin(fin);
  if (padding_length) {
    data->set_padding_len(padding_length.value());
  }
  frames_.push_back(std::move(data));
  return *this;
}

TestFrameSequence& TestFrameSequence::RstStream(Http2StreamId stream_id,
                                                Http2ErrorCode error) {
  frames_.push_back(std::make_unique<spdy::SpdyRstStreamIR>(
      stream_id, TranslateErrorCode(error)));
  return *this;
}

TestFrameSequence& TestFrameSequence::Settings(
    absl::Span<const Http2Setting> settings) {
  auto settings_frame = std::make_unique<spdy::SpdySettingsIR>();
  for (const Http2Setting& setting : settings) {
    settings_frame->AddSetting(setting.id, setting.value);
  }
  frames_.push_back(std::move(settings_frame));
  return *this;
}

TestFrameSequence& TestFrameSequence::SettingsAck() {
  auto settings = std::make_unique<spdy::SpdySettingsIR>();
  settings->set_is_ack(true);
  frames_.push_back(std::move(settings));
  return *this;
}

TestFrameSequence& TestFrameSequence::PushPromise(
    Http2StreamId stream_id, Http2StreamId promised_stream_id,
    absl::Span<const Header> headers) {
  frames_.push_back(std::make_unique<spdy::SpdyPushPromiseIR>(
      stream_id, promised_stream_id, ToHeaderBlock(headers)));
  return *this;
}

TestFrameSequence& TestFrameSequence::Ping(Http2PingId id) {
  frames_.push_back(std::make_unique<spdy::SpdyPingIR>(id));
  return *this;
}

TestFrameSequence& TestFrameSequence::PingAck(Http2PingId id) {
  auto ping = std::make_unique<spdy::SpdyPingIR>(id);
  ping->set_is_ack(true);
  frames_.push_back(std::move(ping));
  return *this;
}

TestFrameSequence& TestFrameSequence::GoAway(Http2StreamId last_good_stream_id,
                                             Http2ErrorCode error,
                                             absl::string_view payload) {
  frames_.push_back(std::make_unique<spdy::SpdyGoAwayIR>(
      last_good_stream_id, TranslateErrorCode(error), std::string(payload)));
  return *this;
}

TestFrameSequence& TestFrameSequence::Headers(
    Http2StreamId stream_id,
    absl::Span<const std::pair<absl::string_view, absl::string_view>> headers,
    bool fin, bool add_continuation) {
  return Headers(stream_id, ToHeaders(headers), fin, add_continuation);
}

TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
                                              quiche::HttpHeaderBlock block,
                                              bool fin, bool add_continuation) {
  if (add_continuation) {
    // The normal intermediate representations don't allow you to represent a
    // nonterminal HEADERS frame explicitly, so we'll need to use
    // SpdyUnknownIRs. For simplicity, and in order not to mess up HPACK state,
    // the payload will be uncompressed.
    spdy::HpackEncoder encoder;
    encoder.DisableCompression();
    std::string encoded_block = encoder.EncodeHeaderBlock(block);
    const size_t pos = encoded_block.size() / 2;
    const uint8_t flags = fin ? END_STREAM_FLAG : 0x0;
    frames_.push_back(std::make_unique<spdy::SpdyUnknownIR>(
        stream_id, static_cast<uint8_t>(spdy::SpdyFrameType::HEADERS), flags,
        encoded_block.substr(0, pos)));

    auto continuation = std::make_unique<spdy::SpdyContinuationIR>(stream_id);
    continuation->set_end_headers(true);
    continuation->take_encoding(encoded_block.substr(pos));
    frames_.push_back(std::move(continuation));
  } else {
    auto headers =
        std::make_unique<spdy::SpdyHeadersIR>(stream_id, std::move(block));
    headers->set_fin(fin);
    frames_.push_back(std::move(headers));
  }
  return *this;
}

TestFrameSequence& TestFrameSequence::Headers(Http2StreamId stream_id,
                                              absl::Span<const Header> headers,
                                              bool fin, bool add_continuation) {
  return Headers(stream_id, ToHeaderBlock(headers), fin, add_continuation);
}

TestFrameSequence& TestFrameSequence::WindowUpdate(Http2StreamId stream_id,
                                                   int32_t delta) {
  frames_.push_back(
      std::make_unique<spdy::SpdyWindowUpdateIR>(stream_id, delta));
  return *this;
}

TestFrameSequence& TestFrameSequence::Priority(Http2StreamId stream_id,
                                               Http2StreamId parent_stream_id,
                                               int weight, bool exclusive) {
  frames_.push_back(std::make_unique<spdy::SpdyPriorityIR>(
      stream_id, parent_stream_id, weight, exclusive));
  return *this;
}

TestFrameSequence& TestFrameSequence::Metadata(Http2StreamId stream_id,
                                               absl::string_view payload,
                                               bool multiple_frames) {
  if (multiple_frames) {
    const size_t pos = payload.size() / 2;
    frames_.push_back(std::make_unique<spdy::SpdyUnknownIR>(
        stream_id, kMetadataFrameType, 0, std::string(payload.substr(0, pos))));
    frames_.push_back(std::make_unique<spdy::SpdyUnknownIR>(
        stream_id, kMetadataFrameType, kMetadataEndFlag,
        std::string(payload.substr(pos))));
  } else {
    frames_.push_back(std::make_unique<spdy::SpdyUnknownIR>(
        stream_id, kMetadataFrameType, kMetadataEndFlag, std::string(payload)));
  }
  return *this;
}

std::string TestFrameSequence::Serialize() {
  std::string result;
  if (!preface_.empty()) {
    result = preface_;
  }
  spdy::SpdyFramer framer(spdy::SpdyFramer::ENABLE_COMPRESSION);
  for (const auto& frame : frames_) {
    spdy::SpdySerializedFrame f = framer.SerializeFrame(*frame);
    absl::StrAppend(&result, absl::string_view(f));
  }
  return result;
}

}  // namespace test
}  // namespace adapter
}  // namespace http2
