#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/core/spdy_protocol.h"
#include "quiche/http2/hpack/hpack_encoder.h"
#include "quiche/common/quiche_data_reader.h"

namespace http2 {
namespace adapter {
namespace test {
namespace {

using ConnectionError = Http2VisitorInterface::ConnectionError;

std::string EncodeHeaders(const quiche::HttpHeaderBlock& 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 quiche::HttpHeaderBlock& payload) {
  outbound_metadata_map_.insert({stream_id, EncodeHeaders(payload)});
}

TestMetadataSource::TestMetadataSource(const quiche::HttpHeaderBlock& 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
