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

#include <cstring>
#include <optional>
#include <ostream>
#include <vector>

#include "absl/strings/str_format.h"
#include "quiche/http2/adapter/http2_visitor_interface.h"
#include "quiche/http2/hpack/hpack_encoder.h"
#include "quiche/common/quiche_data_reader.h"
#include "quiche/spdy/core/spdy_protocol.h"

namespace http2 {
namespace adapter {
namespace test {
namespace {

using ConnectionError = Http2VisitorInterface::ConnectionError;

std::string EncodeHeaders(const spdy::Http2HeaderBlock& entries) {
  spdy::HpackEncoder encoder;
  encoder.DisableCompression();
  return encoder.EncodeHeaderBlock(entries);
}

}  // anonymous namespace

TestVisitor::DataFrameHeaderInfo TestVisitor::OnReadyToSendDataForStream(
    Http2StreamId stream_id, size_t max_length) {
  auto it = data_map_.find(stream_id);
  if (it == data_map_.end()) {
    QUICHE_DVLOG(1) << "Source not in map; returning blocked.";
    return {0, false, false};
  }
  DataPayload& payload = it->second;
  if (payload.return_error) {
    QUICHE_DVLOG(1) << "Simulating error response for stream " << stream_id;
    return {DataFrameSource::kError, false, false};
  }
  const absl::string_view prefix = payload.data.GetPrefix();
  const size_t frame_length = std::min(max_length, prefix.size());
  const bool is_final_fragment = payload.data.Read().size() <= 1;
  const bool end_data =
      payload.end_data && is_final_fragment && frame_length == prefix.size();
  const bool end_stream = payload.end_stream && end_data;
  return {static_cast<int64_t>(frame_length), end_data, end_stream};
}

bool TestVisitor::SendDataFrame(Http2StreamId stream_id,
                                absl::string_view frame_header,
                                size_t payload_bytes) {
  // Sends the frame header.
  const int64_t frame_result = OnReadyToSend(frame_header);
  if (frame_result < 0 ||
      static_cast<size_t>(frame_result) != frame_header.size()) {
    return false;
  }
  auto it = data_map_.find(stream_id);
  if (it == data_map_.end()) {
    if (payload_bytes > 0) {
      // No bytes available to send; error condition.
      return false;
    } else {
      return true;
    }
  }
  DataPayload& payload = it->second;
  absl::string_view frame_payload = payload.data.GetPrefix();
  if (frame_payload.size() < payload_bytes) {
    // Not enough bytes available to send; error condition.
    return false;
  }
  frame_payload = frame_payload.substr(0, payload_bytes);
  // Sends the frame payload.
  const int64_t payload_result = OnReadyToSend(frame_payload);
  if (payload_result < 0 ||
      static_cast<size_t>(payload_result) != frame_payload.size()) {
    return false;
  }
  payload.data.RemovePrefix(payload_bytes);
  return true;
}

void TestVisitor::AppendPayloadForStream(Http2StreamId stream_id,
                                         absl::string_view payload) {
  // Allocates and appends a chunk of memory to hold `payload`, in case the test
  // is depending on specific DATA frame boundaries.
  auto char_data = std::unique_ptr<char[]>(new char[payload.size()]);
  std::copy(payload.begin(), payload.end(), char_data.get());
  data_map_[stream_id].data.Append(std::move(char_data), payload.size());
}

void TestVisitor::SetEndData(Http2StreamId stream_id, bool end_stream) {
  DataPayload& payload = data_map_[stream_id];
  payload.end_data = true;
  payload.end_stream = end_stream;
}

void TestVisitor::SimulateError(Http2StreamId stream_id) {
  DataPayload& payload = data_map_[stream_id];
  payload.return_error = true;
}

std::pair<int64_t, bool> TestVisitor::PackMetadataForStream(
    Http2StreamId stream_id, uint8_t* dest, size_t dest_len) {
  auto it = outbound_metadata_map_.find(stream_id);
  if (it == outbound_metadata_map_.end()) {
    return {-1, false};
  }
  const size_t to_copy = std::min(it->second.size(), dest_len);
  auto* src = reinterpret_cast<uint8_t*>(it->second.data());
  std::copy(src, src + to_copy, dest);
  it->second = it->second.substr(to_copy);
  if (it->second.empty()) {
    outbound_metadata_map_.erase(it);
    return {to_copy, true};
  }
  return {to_copy, false};
}

void TestVisitor::AppendMetadataForStream(
    Http2StreamId stream_id, const spdy::Http2HeaderBlock& payload) {
  outbound_metadata_map_.insert({stream_id, EncodeHeaders(payload)});
}

VisitorDataSource::VisitorDataSource(Http2VisitorInterface& visitor,
                                     Http2StreamId stream_id)
    : visitor_(visitor), stream_id_(stream_id) {}

bool VisitorDataSource::send_fin() const { return has_fin_; }

std::pair<int64_t, bool> VisitorDataSource::SelectPayloadLength(
    size_t max_length) {
  auto [payload_length, end_data, end_stream] =
      visitor_.OnReadyToSendDataForStream(stream_id_, max_length);
  has_fin_ = end_stream;
  return {payload_length, end_data};
}

bool VisitorDataSource::Send(absl::string_view frame_header,
                             size_t payload_length) {
  return visitor_.SendDataFrame(stream_id_, frame_header, payload_length);
}

TestMetadataSource::TestMetadataSource(const spdy::Http2HeaderBlock& entries)
    : encoded_entries_(EncodeHeaders(entries)) {
  remaining_ = encoded_entries_;
}

std::pair<int64_t, bool> TestMetadataSource::Pack(uint8_t* dest,
                                                  size_t dest_len) {
  if (fail_when_packing_) {
    return {-1, false};
  }
  const size_t copied = std::min(dest_len, remaining_.size());
  std::memcpy(dest, remaining_.data(), copied);
  remaining_.remove_prefix(copied);
  return std::make_pair(copied, remaining_.empty());
}

namespace {

using TypeAndOptionalLength =
    std::pair<spdy::SpdyFrameType, std::optional<size_t>>;

std::ostream& operator<<(
    std::ostream& os,
    const std::vector<TypeAndOptionalLength>& types_and_lengths) {
  for (const auto& type_and_length : types_and_lengths) {
    os << "(" << spdy::FrameTypeToString(type_and_length.first) << ", "
       << (type_and_length.second ? absl::StrCat(type_and_length.second.value())
                                  : "<unspecified>")
       << ") ";
  }
  return os;
}

std::string FrameTypeToString(uint8_t frame_type) {
  if (spdy::IsDefinedFrameType(frame_type)) {
    return spdy::FrameTypeToString(spdy::ParseFrameType(frame_type));
  } else {
    return absl::StrFormat("0x%x", static_cast<int>(frame_type));
  }
}

// Custom gMock matcher, used to implement EqualsFrames().
class SpdyControlFrameMatcher
    : public testing::MatcherInterface<absl::string_view> {
 public:
  explicit SpdyControlFrameMatcher(
      std::vector<TypeAndOptionalLength> types_and_lengths)
      : expected_types_and_lengths_(std::move(types_and_lengths)) {}

  bool MatchAndExplain(absl::string_view s,
                       testing::MatchResultListener* listener) const override {
    quiche::QuicheDataReader reader(s.data(), s.size());

    for (TypeAndOptionalLength expected : expected_types_and_lengths_) {
      if (!MatchAndExplainOneFrame(expected.first, expected.second, &reader,
                                   listener)) {
        return false;
      }
    }
    if (!reader.IsDoneReading()) {
      *listener << "; " << reader.BytesRemaining() << " bytes left to read!";
      return false;
    }
    return true;
  }

  bool MatchAndExplainOneFrame(spdy::SpdyFrameType expected_type,
                               std::optional<size_t> expected_length,
                               quiche::QuicheDataReader* reader,
                               testing::MatchResultListener* listener) const {
    uint32_t payload_length;
    if (!reader->ReadUInt24(&payload_length)) {
      *listener << "; unable to read length field for expected_type "
                << FrameTypeToString(expected_type) << ". data too short!";
      return false;
    }

    if (expected_length && payload_length != expected_length.value()) {
      *listener << "; actual length: " << payload_length
                << " but expected length: " << expected_length.value();
      return false;
    }

    uint8_t raw_type;
    if (!reader->ReadUInt8(&raw_type)) {
      *listener << "; unable to read type field for expected_type "
                << FrameTypeToString(expected_type) << ". data too short!";
      return false;
    }

    if (raw_type != static_cast<uint8_t>(expected_type)) {
      *listener << "; actual type: " << FrameTypeToString(raw_type)
                << " but expected type: " << FrameTypeToString(expected_type);
      return false;
    }

    // Seek past flags (1B), stream ID (4B), and payload. Reach the next frame.
    reader->Seek(5 + payload_length);
    return true;
  }

  void DescribeTo(std::ostream* os) const override {
    *os << "Data contains frames of types in sequence "
        << expected_types_and_lengths_;
  }

  void DescribeNegationTo(std::ostream* os) const override {
    *os << "Data does not contain frames of types in sequence "
        << expected_types_and_lengths_;
  }

 private:
  const std::vector<TypeAndOptionalLength> expected_types_and_lengths_;
};

}  // namespace

testing::Matcher<absl::string_view> EqualsFrames(
    std::vector<std::pair<spdy::SpdyFrameType, std::optional<size_t>>>
        types_and_lengths) {
  return MakeMatcher(new SpdyControlFrameMatcher(std::move(types_and_lengths)));
}

testing::Matcher<absl::string_view> EqualsFrames(
    std::vector<spdy::SpdyFrameType> types) {
  std::vector<std::pair<spdy::SpdyFrameType, std::optional<size_t>>>
      types_and_lengths;
  types_and_lengths.reserve(types.size());
  for (spdy::SpdyFrameType type : types) {
    types_and_lengths.push_back({type, std::nullopt});
  }
  return MakeMatcher(new SpdyControlFrameMatcher(std::move(types_and_lengths)));
}

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