#ifndef QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
#define QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_

#include <cstdint>
#include <string>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "http2/adapter/data_source.h"
#include "http2/adapter/http2_protocol.h"
#include "http2/adapter/mock_http2_visitor.h"
#include "common/platform/api/quiche_export.h"
#include "common/platform/api/quiche_test.h"
#include "spdy/core/spdy_header_block.h"
#include "spdy/core/spdy_protocol.h"

namespace http2 {
namespace adapter {
namespace test {

class QUICHE_NO_EXPORT DataSavingVisitor
    : public testing::StrictMock<MockHttp2Visitor> {
 public:
  int64_t OnReadyToSend(absl::string_view data) override {
    if (has_write_error_) {
      return kSendError;
    }
    if (is_write_blocked_) {
      return kSendBlocked;
    }
    const size_t to_accept = std::min(send_limit_, data.size());
    if (to_accept == 0) {
      return kSendBlocked;
    }
    absl::StrAppend(&data_, data.substr(0, to_accept));
    return to_accept;
  }

  bool OnMetadataForStream(Http2StreamId stream_id,
                           absl::string_view metadata) override {
    const bool ret = testing::StrictMock<MockHttp2Visitor>::OnMetadataForStream(
        stream_id, metadata);
    if (ret) {
      auto result =
          metadata_map_.try_emplace(stream_id, std::vector<std::string>());
      result.first->second.push_back(std::string(metadata));
    }
    return ret;
  }

  const std::vector<std::string> GetMetadata(Http2StreamId stream_id) {
    auto it = metadata_map_.find(stream_id);
    if (it == metadata_map_.end()) {
      return {};
    } else {
      return it->second;
    }
  }

  const std::string& data() { return data_; }
  void Clear() { data_.clear(); }

  void set_send_limit(size_t limit) { send_limit_ = limit; }

  bool is_write_blocked() const { return is_write_blocked_; }
  void set_is_write_blocked(bool value) { is_write_blocked_ = value; }

  void set_has_write_error() { has_write_error_ = true; }

 private:
  std::string data_;
  absl::flat_hash_map<Http2StreamId, std::vector<std::string>> metadata_map_;
  size_t send_limit_ = std::numeric_limits<size_t>::max();
  bool is_write_blocked_ = false;
  bool has_write_error_ = false;
};

// A test DataFrameSource. Starts out in the empty, blocked state.
class QUICHE_NO_EXPORT TestDataFrameSource : public DataFrameSource {
 public:
  TestDataFrameSource(Http2VisitorInterface& visitor, bool has_fin);

  void AppendPayload(absl::string_view payload);
  void EndData();
  void SimulateError() { return_error_ = true; }

  std::pair<int64_t, bool> SelectPayloadLength(size_t max_length) override;
  bool Send(absl::string_view frame_header, size_t payload_length) override;
  bool send_fin() const override { return has_fin_; }

 private:
  Http2VisitorInterface& visitor_;
  std::vector<std::string> payload_fragments_;
  absl::string_view current_fragment_;
  // Whether the stream should end with the final frame of data.
  const bool has_fin_;
  // Whether |payload_fragments_| contains the final segment of data.
  bool end_data_ = false;
  // Whether SelectPayloadLength() should return an error.
  bool return_error_ = false;
};

class QUICHE_NO_EXPORT TestMetadataSource : public MetadataSource {
 public:
  explicit TestMetadataSource(const spdy::SpdyHeaderBlock& entries);

  size_t NumFrames(size_t max_frame_size) const override {
    // Round up to the next frame.
    return (encoded_entries_.size() + max_frame_size - 1) / max_frame_size;
  }
  std::pair<int64_t, bool> Pack(uint8_t* dest, size_t dest_len) override;

 private:
  const std::string encoded_entries_;
  absl::string_view remaining_;
};

// These matchers check whether a string consists entirely of HTTP/2 frames of
// the specified ordered sequence. This is useful in tests where we want to show
// that one or more particular frame types are serialized for sending to the
// peer. The match will fail if there are input bytes not consumed by the
// matcher.

// Requires that frames match both types and lengths.
testing::Matcher<absl::string_view> EqualsFrames(
    std::vector<std::pair<spdy::SpdyFrameType, absl::optional<size_t>>>
        types_and_lengths);

// Requires that frames match the specified types.
testing::Matcher<absl::string_view> EqualsFrames(
    std::vector<spdy::SpdyFrameType> types);

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

#endif  // QUICHE_HTTP2_ADAPTER_TEST_UTILS_H_
