#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_test.h"

namespace http2 {
namespace adapter {
namespace test {

// A simple class that can easily be adapted to act as a nghttp2_data_source.
class 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*> 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_
