#include <memory>
#include <string>
#include <vector>

#include "quiche/http2/adapter/http2_protocol.h"
#include "quiche/http2/adapter/mock_http2_visitor.h"
#include "quiche/http2/adapter/nghttp2_adapter.h"
#include "quiche/http2/adapter/oghttp2_adapter.h"
#include "quiche/http2/adapter/recording_http2_visitor.h"
#include "quiche/http2/adapter/test_frame_sequence.h"
#include "quiche/http2/adapter/test_utils.h"
#include "quiche/http2/core/spdy_protocol.h"
#include "quiche/common/platform/api/quiche_test.h"

namespace http2 {
namespace adapter {
namespace test {
namespace {

using ::testing::_;
using ::testing::AssertionResult;
using ::testing::InvokeWithoutArgs;

enum FrameType {
  DATA,
  HEADERS,
  PRIORITY,
  RST_STREAM,
  SETTINGS,
  PUSH_PROMISE,
  PING,
  GOAWAY,
  WINDOW_UPDATE,
  CONTINUATION,
};

enum class Impl {
  kNgHttp2,
  kOgHttp2,
};

absl::string_view ToString(Impl impl) {
  if (impl == Impl::kNgHttp2) {
    return "nghttp2";
  }
  return "oghttp2";
}

class ComparisonTest : public ::quiche::test::QuicheTest {
 public:
  // The range of characters over which to run a TestEachChar invocation.
  using CharRange = std::pair<char, char>;
  // The function that creates and appends a HEADERS frame to the
  // TestFrameSequence, given a particular character.
  using AddHeadersFn = absl::AnyInvocable<void(char, TestFrameSequence&)>;

  std::vector<Impl> implementations() {
    return {Impl::kNgHttp2, Impl::kOgHttp2};
  }

  std::unique_ptr<Http2Adapter> CreateAdapter(Http2VisitorInterface& visitor,
                                              Impl impl, Perspective p) {
    switch (impl) {
      case Impl::kNgHttp2:
        if (p == Perspective::kClient) {
          return NgHttp2Adapter::CreateClientAdapter(visitor);
        } else {
          return NgHttp2Adapter::CreateServerAdapter(visitor);
        }
      case Impl::kOgHttp2:
        OgHttp2Adapter::Options options;
        options.perspective = p;
        return OgHttp2Adapter::Create(visitor, options);
    }
    return nullptr;  // Unreachable unless enum is corrupted.
  }

  AssertionResult TestEachChar(CharRange range, AddHeadersFn add_headers) {
    const char low = range.first;
    const char high = range.second;
    // An int is used as the loop variable so that it does not overflow when the
    // value is the maximum possible character value.
    for (int i = low; i < high; ++i) {
      const char c = static_cast<char>(i);

      TestFrameSequence sequence;
      sequence.ClientPreface();
      add_headers(c, sequence);
      const std::string frames = sequence.Serialize();

      // Accumulates frame validation results.
      std::vector<bool> frame_valid_results;
      bool frame_valid = true;

      testing::NiceMock<MockHttp2Visitor> visitor;
      ON_CALL(visitor, OnInvalidFrame).WillByDefault([&frame_valid]() {
        // Records that the frame was not valid.
        frame_valid = false;
        return true;
      });

      for (Impl impl : implementations()) {
        frame_valid = true;
        auto adapter = CreateAdapter(visitor, impl, Perspective::kServer);
        const int64_t result = adapter->ProcessBytes(frames);
        if (frames.size() != static_cast<size_t>(result)) {
          return testing::AssertionFailure()
                 << "Failed to parse encoded bytes! (Expected " << frames.size()
                 << ", saw " << result << ")";
        }
        frame_valid_results.push_back(frame_valid);
      }
      // All implementations should agree on whether the frame was valid.
      for (bool result : frame_valid_results) {
        if (result != frame_valid_results.back()) {
          return testing::AssertionFailure()
                 << "All implementations should agree!";
        }
      }
    }
    return testing::AssertionSuccess();
  }
};

// Verifies that the implementations consider the same set of characters valid
// in paths.
TEST_F(ComparisonTest, PathCharValidation) {
  // Iterates over all character values.
  const CharRange test_range = {std::numeric_limits<char>::min(),
                                std::numeric_limits<char>::max()};
  auto add_headers_frame = [](char c, TestFrameSequence& seq) {
    // Constructs a path with the desired character.
    const std::string path_value =
        absl::StrCat("/aaa", absl::string_view(&c, 1), "bbb");

    SCOPED_TRACE(absl::StrCat("Path: [", absl::CEscape(path_value), "]"));
    seq.Headers(1,
                {{":method", "GET"},
                 {":scheme", "https"},
                 {":authority", "example.com"},
                 {":path", path_value},
                 {"name", "value"}},
                /*fin=*/true);
  };
  EXPECT_TRUE(TestEachChar(test_range, std::move(add_headers_frame)));
}

// Verifies that the implementations consider the same set of characters valid
// in HTTP header field names.
TEST_F(ComparisonTest, HeaderNameCharValidation) {
  // Iterates over all character values.
  const CharRange test_range = {std::numeric_limits<char>::min(),
                                std::numeric_limits<char>::max()};

  auto add_headers_frame = [](char c, TestFrameSequence& seq) {
    // Constructs a header name with the desired character.
    const std::string name_text =
        absl::StrCat("na", absl::string_view(&c, 1), "me");

    SCOPED_TRACE(absl::StrCat("Name: [", absl::CEscape(name_text), "]"));

    // Constructs a request with the desired header name text.
    seq.Headers(1,
                {{":method", "GET"},
                 {":scheme", "https"},
                 {":authority", "example.com"},
                 {":path", "/my/fun/path?with_query"},
                 {name_text, "value"}},
                /*fin=*/true);
  };
  EXPECT_TRUE(TestEachChar(test_range, std::move(add_headers_frame)));
}

// Verifies that the implementations consider the same set of characters valid
// in HTTP header field values.
TEST_F(ComparisonTest, HeaderValueCharValidation) {
  // Iterates over all character values except \0, which cannot be properly
  // encoded by the test utility.
  const CharRange test_range = {1, std::numeric_limits<char>::max()};
  auto add_headers_frame = [](char c, TestFrameSequence& seq) {
    // Constructs a header value with the desired character.
    const std::string value_text =
        absl::StrCat("va", absl::string_view(&c, 1), "lue");

    SCOPED_TRACE(absl::StrCat("Value: [", absl::CEscape(value_text), "]"));

    // Constructs a request with the desired header value text.
    seq.Headers(1,
                {{":method", "GET"},
                 {":scheme", "https"},
                 {":authority", "example.com"},
                 {":path", "/my/fun/path?with_query"},
                 {"name", value_text}},
                /*fin=*/true);
  };
  EXPECT_TRUE(TestEachChar(test_range, std::move(add_headers_frame)));
}

TEST_F(ComparisonTest, StreamCloseAfterReset) {
  for (Impl impl : implementations()) {
    SCOPED_TRACE(absl::StrCat("Implementation: ", ToString(impl)));

    testing::InSequence s;

    TestVisitor visitor;
    std::unique_ptr<Http2Adapter> adapter =
        CreateAdapter(visitor, impl, Perspective::kClient);

    const std::vector<Header> request_headers =
        ToHeaders({{":method", "POST"},
                   {":scheme", "https"},
                   {":authority", "example.com"},
                   {":path", "/"}});

    const int32_t stream_id =
        adapter->SubmitRequest(request_headers, false, nullptr);
    EXPECT_GT(stream_id, 0);

    if (impl == Impl::kOgHttp2) {
      // oghttp2 generates an empty SETTINGS frame, per the HTTP/2 spec.
      EXPECT_CALL(visitor, OnBeforeFrameSent(SETTINGS, 0, _, 0x0));
      EXPECT_CALL(visitor, OnFrameSent(SETTINGS, 0, _, 0x0, 0));
    }

    EXPECT_CALL(visitor, OnBeforeFrameSent(HEADERS, 1, _, 0x4));
    EXPECT_CALL(visitor, OnFrameSent(HEADERS, 1, _, 0x4, 0));

    int result = adapter->Send();
    EXPECT_EQ(result, 0);

    // The WINDOW_UPDATE frame before the RST_STREAM is dropped.

    EXPECT_CALL(visitor, OnBeforeFrameSent(RST_STREAM, 1, _, _));
    EXPECT_CALL(visitor, OnFrameSent(RST_STREAM, 1, _, _, _));

    // The WINDOW_UPDATE frame after the RST_STREAM is dropped.

    EXPECT_CALL(visitor, OnCloseStream(1, _));

    adapter->SubmitWindowUpdate(1, 10000);
    adapter->SubmitRst(1, Http2ErrorCode::CANCEL);
    adapter->SubmitWindowUpdate(1, 10000);

    result = adapter->Send();
    EXPECT_EQ(result, 0);
  }
}

TEST(AdapterImplComparisonTest, ClientHandlesFrames) {
  RecordingHttp2Visitor nghttp2_visitor;
  std::unique_ptr<NgHttp2Adapter> nghttp2_adapter =
      NgHttp2Adapter::CreateClientAdapter(nghttp2_visitor);

  RecordingHttp2Visitor oghttp2_visitor;
  OgHttp2Adapter::Options options;
  options.perspective = Perspective::kClient;
  std::unique_ptr<OgHttp2Adapter> oghttp2_adapter =
      OgHttp2Adapter::Create(oghttp2_visitor, options);

  const std::string initial_frames = TestFrameSequence()
                                         .ServerPreface()
                                         .Ping(42)
                                         .WindowUpdate(0, 1000)
                                         .Serialize();

  nghttp2_adapter->ProcessBytes(initial_frames);
  oghttp2_adapter->ProcessBytes(initial_frames);

  EXPECT_EQ(nghttp2_visitor.GetEventSequence(),
            oghttp2_visitor.GetEventSequence());

  // TODO(b/181586191): Consider consistent behavior for delivering events on
  // non-existent streams between nghttp2_adapter and oghttp2_adapter.
}

TEST(AdapterImplComparisonTest, SubmitWindowUpdateBumpsWindow) {
  RecordingHttp2Visitor nghttp2_visitor;
  std::unique_ptr<NgHttp2Adapter> nghttp2_adapter =
      NgHttp2Adapter::CreateClientAdapter(nghttp2_visitor);

  RecordingHttp2Visitor oghttp2_visitor;
  OgHttp2Adapter::Options options;
  options.perspective = Perspective::kClient;
  std::unique_ptr<OgHttp2Adapter> oghttp2_adapter =
      OgHttp2Adapter::Create(oghttp2_visitor, options);

  int result;

  const std::vector<Header> request_headers =
      ToHeaders({{":method", "POST"},
                 {":scheme", "https"},
                 {":authority", "example.com"},
                 {":path", "/"}});
  const int kInitialFlowControlWindow = 65535;
  const int kConnectionWindowIncrease = 192 * 1024;

  const int32_t nghttp2_stream_id =
      nghttp2_adapter->SubmitRequest(request_headers, true, nullptr);

  // Both the connection and stream flow control windows are increased.
  nghttp2_adapter->SubmitWindowUpdate(0, kConnectionWindowIncrease);
  nghttp2_adapter->SubmitWindowUpdate(nghttp2_stream_id,
                                      kConnectionWindowIncrease);
  result = nghttp2_adapter->Send();
  EXPECT_EQ(0, result);
  int nghttp2_window = nghttp2_adapter->GetReceiveWindowSize();
  EXPECT_EQ(kInitialFlowControlWindow + kConnectionWindowIncrease,
            nghttp2_window);

  const int32_t oghttp2_stream_id =
      oghttp2_adapter->SubmitRequest(request_headers, true, nullptr);
  // Both the connection and stream flow control windows are increased.
  oghttp2_adapter->SubmitWindowUpdate(0, kConnectionWindowIncrease);
  oghttp2_adapter->SubmitWindowUpdate(oghttp2_stream_id,
                                      kConnectionWindowIncrease);
  result = oghttp2_adapter->Send();
  EXPECT_EQ(0, result);
  int oghttp2_window = oghttp2_adapter->GetReceiveWindowSize();
  EXPECT_EQ(kInitialFlowControlWindow + kConnectionWindowIncrease,
            oghttp2_window);

  // nghttp2 and oghttp2 agree on the advertised window.
  EXPECT_EQ(nghttp2_window, oghttp2_window);

  ASSERT_EQ(nghttp2_stream_id, oghttp2_stream_id);

  const int kMaxFrameSize = 16 * 1024;
  const std::string body_chunk(kMaxFrameSize, 'a');
  auto sequence = TestFrameSequence();
  sequence.ServerPreface().Headers(nghttp2_stream_id, {{":status", "200"}},
                                   /*fin=*/false);
  // This loop generates enough DATA frames to consume the window increase.
  const int kNumFrames = kConnectionWindowIncrease / kMaxFrameSize;
  for (int i = 0; i < kNumFrames; ++i) {
    sequence.Data(nghttp2_stream_id, body_chunk);
  }
  const std::string frames = sequence.Serialize();

  nghttp2_adapter->ProcessBytes(frames);
  // Marking the data consumed causes a window update, which is reflected in the
  // advertised window size.
  nghttp2_adapter->MarkDataConsumedForStream(nghttp2_stream_id,
                                             kNumFrames * kMaxFrameSize);
  result = nghttp2_adapter->Send();
  EXPECT_EQ(0, result);
  nghttp2_window = nghttp2_adapter->GetReceiveWindowSize();

  oghttp2_adapter->ProcessBytes(frames);
  // Marking the data consumed causes a window update, which is reflected in the
  // advertised window size.
  oghttp2_adapter->MarkDataConsumedForStream(oghttp2_stream_id,
                                             kNumFrames * kMaxFrameSize);
  result = oghttp2_adapter->Send();
  EXPECT_EQ(0, result);
  oghttp2_window = oghttp2_adapter->GetReceiveWindowSize();

  const int kMinExpectation =
      (kInitialFlowControlWindow + kConnectionWindowIncrease) / 2;
  EXPECT_GT(nghttp2_window, kMinExpectation);
  EXPECT_GT(oghttp2_window, kMinExpectation);
}

TEST(AdapterImplComparisonTest, ServerHandlesFrames) {
  RecordingHttp2Visitor nghttp2_visitor;
  std::unique_ptr<NgHttp2Adapter> nghttp2_adapter =
      NgHttp2Adapter::CreateServerAdapter(nghttp2_visitor);

  RecordingHttp2Visitor oghttp2_visitor;
  OgHttp2Adapter::Options options;
  options.perspective = Perspective::kServer;
  std::unique_ptr<OgHttp2Adapter> oghttp2_adapter =
      OgHttp2Adapter::Create(oghttp2_visitor, options);

  const std::string frames = TestFrameSequence()
                                 .ClientPreface()
                                 .Ping(42)
                                 .WindowUpdate(0, 1000)
                                 .Headers(1,
                                          {{":method", "POST"},
                                           {":scheme", "https"},
                                           {":authority", "example.com"},
                                           {":path", "/this/is/request/one"}},
                                          /*fin=*/false)
                                 .WindowUpdate(1, 2000)
                                 .Data(1, "This is the request body.")
                                 .Headers(3,
                                          {{":method", "GET"},
                                           {":scheme", "http"},
                                           {":authority", "example.com"},
                                           {":path", "/this/is/request/two"}},
                                          /*fin=*/true)
                                 .RstStream(3, Http2ErrorCode::CANCEL)
                                 .Ping(47)
                                 .Serialize();

  nghttp2_adapter->ProcessBytes(frames);
  oghttp2_adapter->ProcessBytes(frames);

  EXPECT_EQ(nghttp2_visitor.GetEventSequence(),
            oghttp2_visitor.GetEventSequence());
}

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