#ifndef QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
#define QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_

#include <vector>

#include "absl/strings/string_view.h"
#include "http2/adapter/http2_protocol.h"
#include "third_party/nghttp2/src/lib/includes/nghttp2/nghttp2.h"
#include "common/platform/api/quiche_export.h"
#include "common/platform/api/quiche_test.h"

namespace http2 {
namespace adapter {
namespace test {

// A simple class that can easily be adapted to act as a nghttp2_data_source.
class QUICHE_NO_EXPORT TestDataSource {
 public:
  explicit TestDataSource(absl::string_view data) : data_(std::string(data)) {}

  absl::string_view ReadNext(size_t size) {
    const size_t to_send = std::min(size, remaining_.size());
    auto ret = remaining_.substr(0, to_send);
    remaining_.remove_prefix(to_send);
    return ret;
  }

  size_t SelectPayloadLength(size_t max_length) {
    return std::min(max_length, remaining_.size());
  }

  nghttp2_data_provider MakeDataProvider() {
    return nghttp2_data_provider{
        .source = {.ptr = this},
        .read_callback = [](nghttp2_session*, int32_t, uint8_t*, size_t length,
                            uint32_t* data_flags, nghttp2_data_source* source,
                            void*) -> ssize_t {
          *data_flags |= NGHTTP2_DATA_FLAG_NO_COPY;
          auto* s = static_cast<TestDataSource*>(source->ptr);
          if (!s->is_data_available()) {
            return NGHTTP2_ERR_DEFERRED;
          }
          const ssize_t ret = s->SelectPayloadLength(length);
          if (ret < length) {
            *data_flags |= NGHTTP2_DATA_FLAG_EOF;
          }
          return ret;
        }};
  }

  bool is_data_available() const { return is_data_available_; }
  void set_is_data_available(bool value) { is_data_available_ = value; }

 private:
  const std::string data_;
  absl::string_view remaining_ = data_;
  bool is_data_available_ = true;
};

// Matchers for nghttp2 data types.
testing::Matcher<const nghttp2_frame_hd*> HasFrameHeader(
    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags);
testing::Matcher<const nghttp2_frame_hd&> HasFrameHeaderRef(
    uint32_t streamid, uint8_t type, const testing::Matcher<int> flags);

testing::Matcher<const nghttp2_frame*> IsData(
    const testing::Matcher<uint32_t> stream_id,
    const testing::Matcher<size_t> length, const testing::Matcher<int> flags);

testing::Matcher<const nghttp2_frame*> IsHeaders(
    const testing::Matcher<uint32_t> stream_id,
    const testing::Matcher<int> flags, const testing::Matcher<int> category);

testing::Matcher<const nghttp2_frame*> IsRstStream(
    const testing::Matcher<uint32_t> stream_id,
    const testing::Matcher<uint32_t> error_code);

testing::Matcher<const nghttp2_frame*> IsSettings(
    const testing::Matcher<std::vector<Http2Setting>> values);

testing::Matcher<const nghttp2_frame*> IsPing(
    const testing::Matcher<uint64_t> id);

testing::Matcher<const nghttp2_frame*> IsPingAck(
    const testing::Matcher<uint64_t> id);

testing::Matcher<const nghttp2_frame*> IsGoAway(
    const testing::Matcher<uint32_t> last_stream_id,
    const testing::Matcher<uint32_t> error_code,
    const testing::Matcher<absl::string_view> opaque_data);

testing::Matcher<const nghttp2_frame*> IsWindowUpdate(
    const testing::Matcher<uint32_t> delta);

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

#endif  // QUICHE_HTTP2_ADAPTER_NGHTTP2_TEST_UTILS_H_
