#include "quiche/http2/adapter/callback_visitor.h"

#include "absl/container/flat_hash_map.h"
#include "quiche/http2/adapter/http2_protocol.h"
#include "quiche/http2/adapter/mock_nghttp2_callbacks.h"
#include "quiche/http2/adapter/nghttp2_adapter.h"
#include "quiche/http2/adapter/nghttp2_test_utils.h"
#include "quiche/http2/adapter/test_frame_sequence.h"
#include "quiche/http2/adapter/test_utils.h"
#include "quiche/common/platform/api/quiche_test.h"

namespace http2 {
namespace adapter {
namespace test {
namespace {

using testing::_;
using testing::IsEmpty;
using testing::Pair;
using testing::UnorderedElementsAre;

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

// Tests connection-level events.
TEST(ClientCallbackVisitorUnitTest, ConnectionFrames) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kClient,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);

  testing::InSequence seq;

  // SETTINGS
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, _)));
  visitor.OnFrameHeader(0, 0, SETTINGS, 0);

  visitor.OnSettingsStart();
  EXPECT_CALL(callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));
  visitor.OnSettingsEnd();

  // PING
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, PING, _)));
  visitor.OnFrameHeader(0, 8, PING, 0);

  EXPECT_CALL(callbacks, OnFrameRecv(IsPing(42)));
  visitor.OnPing(42, false);

  // WINDOW_UPDATE
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, _)));
  visitor.OnFrameHeader(0, 4, WINDOW_UPDATE, 0);

  EXPECT_CALL(callbacks, OnFrameRecv(IsWindowUpdate(1000)));
  visitor.OnWindowUpdate(0, 1000);

  // PING ack
  EXPECT_CALL(callbacks,
              OnBeginFrame(HasFrameHeader(0, PING, NGHTTP2_FLAG_ACK)));
  visitor.OnFrameHeader(0, 8, PING, 1);

  EXPECT_CALL(callbacks, OnFrameRecv(IsPingAck(247)));
  visitor.OnPing(247, true);

  // GOAWAY
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, GOAWAY, 0)));
  visitor.OnFrameHeader(0, 19, GOAWAY, 0);

  EXPECT_CALL(callbacks, OnFrameRecv(IsGoAway(5, NGHTTP2_ENHANCE_YOUR_CALM,
                                              "calm down!!")));
  visitor.OnGoAway(5, Http2ErrorCode::ENHANCE_YOUR_CALM, "calm down!!");

  EXPECT_EQ(visitor.stream_map_size(), 0);
}

TEST(ClientCallbackVisitorUnitTest, StreamFrames) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kClient,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
  absl::flat_hash_map<Http2StreamId, int> stream_close_counts;
  visitor.set_stream_close_listener(
      [&stream_close_counts](Http2StreamId stream_id) {
        ++stream_close_counts[stream_id];
      });

  testing::InSequence seq;

  EXPECT_EQ(visitor.stream_map_size(), 0);

  // HEADERS on stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
  visitor.OnFrameHeader(1, 23, HEADERS, 4);

  EXPECT_CALL(callbacks,
              OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
  visitor.OnBeginHeadersForStream(1);

  EXPECT_EQ(visitor.stream_map_size(), 1);

  EXPECT_CALL(callbacks, OnHeader(_, ":status", "200", _));
  visitor.OnHeaderForStream(1, ":status", "200");

  EXPECT_CALL(callbacks, OnHeader(_, "server", "my-fake-server", _));
  visitor.OnHeaderForStream(1, "server", "my-fake-server");

  EXPECT_CALL(callbacks,
              OnHeader(_, "date", "Tue, 6 Apr 2021 12:54:01 GMT", _));
  visitor.OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT");

  EXPECT_CALL(callbacks, OnHeader(_, "trailer", "x-server-status", _));
  visitor.OnHeaderForStream(1, "trailer", "x-server-status");

  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
  visitor.OnEndHeadersForStream(1);

  // DATA for stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, DATA, 0)));
  visitor.OnFrameHeader(1, 26, DATA, 0);

  visitor.OnBeginDataForStream(1, 26);
  EXPECT_CALL(callbacks, OnDataChunkRecv(0, 1, "This is the response body."));
  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, 0)));
  visitor.OnDataForStream(1, "This is the response body.");

  // Trailers for stream 1, with a different nghttp2 "category".
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, _)));
  visitor.OnFrameHeader(1, 23, HEADERS, 4);

  EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_HEADERS)));
  visitor.OnBeginHeadersForStream(1);

  EXPECT_CALL(callbacks, OnHeader(_, "x-server-status", "OK", _));
  visitor.OnHeaderForStream(1, "x-server-status", "OK");

  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_HEADERS)));
  visitor.OnEndHeadersForStream(1);

  EXPECT_THAT(stream_close_counts, IsEmpty());

  // RST_STREAM on stream 3
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, RST_STREAM, 0)));
  visitor.OnFrameHeader(3, 4, RST_STREAM, 0);

  // No change in stream map size.
  EXPECT_EQ(visitor.stream_map_size(), 1);
  EXPECT_THAT(stream_close_counts, IsEmpty());

  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(3, NGHTTP2_INTERNAL_ERROR)));
  visitor.OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR);

  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_INTERNAL_ERROR));
  visitor.OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR);

  EXPECT_THAT(stream_close_counts, UnorderedElementsAre(Pair(3, 1)));

  // More stream close events
  EXPECT_CALL(callbacks,
              OnBeginFrame(HasFrameHeader(1, DATA, NGHTTP2_FLAG_END_STREAM)));
  visitor.OnFrameHeader(1, 0, DATA, 1);

  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
  visitor.OnBeginDataForStream(1, 0);
  EXPECT_TRUE(visitor.OnEndStream(1));

  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);

  // Stream map is empty again after both streams were closed.
  EXPECT_EQ(visitor.stream_map_size(), 0);
  EXPECT_THAT(stream_close_counts,
              UnorderedElementsAre(Pair(3, 1), Pair(1, 1)));

  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(5, RST_STREAM, _)));
  visitor.OnFrameHeader(5, 4, RST_STREAM, 0);

  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(5, NGHTTP2_REFUSED_STREAM)));
  visitor.OnRstStream(5, Http2ErrorCode::REFUSED_STREAM);

  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_REFUSED_STREAM));
  visitor.OnCloseStream(5, Http2ErrorCode::REFUSED_STREAM);

  EXPECT_EQ(visitor.stream_map_size(), 0);
  EXPECT_THAT(stream_close_counts,
              UnorderedElementsAre(Pair(3, 1), Pair(1, 1), Pair(5, 1)));
}

TEST(ClientCallbackVisitorUnitTest, HeadersWithContinuation) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kClient,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);

  testing::InSequence seq;

  // HEADERS on stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, 0x0)));
  ASSERT_TRUE(visitor.OnFrameHeader(1, 23, HEADERS, 0x0));

  EXPECT_CALL(callbacks,
              OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
  visitor.OnBeginHeadersForStream(1);

  EXPECT_CALL(callbacks, OnHeader(_, ":status", "200", _));
  visitor.OnHeaderForStream(1, ":status", "200");

  EXPECT_CALL(callbacks, OnHeader(_, "server", "my-fake-server", _));
  visitor.OnHeaderForStream(1, "server", "my-fake-server");

  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, CONTINUATION, 0x4)));
  ASSERT_TRUE(visitor.OnFrameHeader(1, 23, CONTINUATION, 0x4));

  EXPECT_CALL(callbacks,
              OnHeader(_, "date", "Tue, 6 Apr 2021 12:54:01 GMT", _));
  visitor.OnHeaderForStream(1, "date", "Tue, 6 Apr 2021 12:54:01 GMT");

  EXPECT_CALL(callbacks, OnHeader(_, "trailer", "x-server-status", _));
  visitor.OnHeaderForStream(1, "trailer", "x-server-status");

  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
  visitor.OnEndHeadersForStream(1);
}

TEST(ClientCallbackVisitorUnitTest, ContinuationNoHeaders) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kClient,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
  // Because no stream precedes the CONTINUATION frame, the stream ID does not
  // match, and the method returns false.
  EXPECT_FALSE(visitor.OnFrameHeader(1, 23, CONTINUATION, 0x4));
}

TEST(ClientCallbackVisitorUnitTest, ContinuationWrongPrecedingType) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kClient,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);

  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, WINDOW_UPDATE, _)));
  visitor.OnFrameHeader(1, 4, WINDOW_UPDATE, 0);

  // Because the CONTINUATION frame does not follow HEADERS, the method returns
  // false.
  EXPECT_FALSE(visitor.OnFrameHeader(1, 23, CONTINUATION, 0x4));
}

TEST(ClientCallbackVisitorUnitTest, ContinuationWrongStream) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kClient,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
  // HEADERS on stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, HEADERS, 0x0)));
  ASSERT_TRUE(visitor.OnFrameHeader(1, 23, HEADERS, 0x0));

  EXPECT_CALL(callbacks,
              OnBeginHeaders(IsHeaders(1, _, NGHTTP2_HCAT_RESPONSE)));
  visitor.OnBeginHeadersForStream(1);

  EXPECT_CALL(callbacks, OnHeader(_, ":status", "200", _));
  visitor.OnHeaderForStream(1, ":status", "200");

  EXPECT_CALL(callbacks, OnHeader(_, "server", "my-fake-server", _));
  visitor.OnHeaderForStream(1, "server", "my-fake-server");

  // The CONTINUATION stream ID does not match the one from the HEADERS.
  EXPECT_FALSE(visitor.OnFrameHeader(3, 23, CONTINUATION, 0x4));
}

TEST(ClientCallbackVisitorUnitTest, ResetAndGoaway) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kClient,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);

  testing::InSequence seq;

  // RST_STREAM on stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, RST_STREAM, 0x0)));
  EXPECT_TRUE(visitor.OnFrameHeader(1, 13, RST_STREAM, 0x0));

  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(1, NGHTTP2_INTERNAL_ERROR)));
  visitor.OnRstStream(1, Http2ErrorCode::INTERNAL_ERROR);

  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_INTERNAL_ERROR));
  EXPECT_TRUE(visitor.OnCloseStream(1, Http2ErrorCode::INTERNAL_ERROR));

  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, GOAWAY, 0x0)));
  EXPECT_TRUE(visitor.OnFrameHeader(0, 13, GOAWAY, 0x0));

  EXPECT_CALL(callbacks,
              OnFrameRecv(IsGoAway(3, NGHTTP2_ENHANCE_YOUR_CALM, "calma te")));
  EXPECT_TRUE(
      visitor.OnGoAway(3, Http2ErrorCode::ENHANCE_YOUR_CALM, "calma te"));

  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_STREAM_CLOSED))
      .WillOnce(testing::Return(NGHTTP2_ERR_CALLBACK_FAILURE));
  EXPECT_FALSE(visitor.OnCloseStream(5, Http2ErrorCode::STREAM_CLOSED));
}

TEST(ServerCallbackVisitorUnitTest, ConnectionFrames) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kServer,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);

  testing::InSequence seq;

  // SETTINGS
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, _)));
  visitor.OnFrameHeader(0, 0, SETTINGS, 0);

  visitor.OnSettingsStart();
  EXPECT_CALL(callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));
  visitor.OnSettingsEnd();

  // PING
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, PING, _)));
  visitor.OnFrameHeader(0, 8, PING, 0);

  EXPECT_CALL(callbacks, OnFrameRecv(IsPing(42)));
  visitor.OnPing(42, false);

  // WINDOW_UPDATE
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, WINDOW_UPDATE, _)));
  visitor.OnFrameHeader(0, 4, WINDOW_UPDATE, 0);

  EXPECT_CALL(callbacks, OnFrameRecv(IsWindowUpdate(1000)));
  visitor.OnWindowUpdate(0, 1000);

  // PING ack
  EXPECT_CALL(callbacks,
              OnBeginFrame(HasFrameHeader(0, PING, NGHTTP2_FLAG_ACK)));
  visitor.OnFrameHeader(0, 8, PING, 1);

  EXPECT_CALL(callbacks, OnFrameRecv(IsPingAck(247)));
  visitor.OnPing(247, true);

  EXPECT_EQ(visitor.stream_map_size(), 0);
}

TEST(ServerCallbackVisitorUnitTest, StreamFrames) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kServer,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);

  testing::InSequence seq;

  // HEADERS on stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(
                             1, HEADERS, NGHTTP2_FLAG_END_HEADERS)));
  visitor.OnFrameHeader(1, 23, HEADERS, 4);

  EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
                                                  NGHTTP2_HCAT_REQUEST)));
  visitor.OnBeginHeadersForStream(1);

  EXPECT_EQ(visitor.stream_map_size(), 1);

  EXPECT_CALL(callbacks, OnHeader(_, ":method", "POST", _));
  visitor.OnHeaderForStream(1, ":method", "POST");

  EXPECT_CALL(callbacks, OnHeader(_, ":path", "/example/path", _));
  visitor.OnHeaderForStream(1, ":path", "/example/path");

  EXPECT_CALL(callbacks, OnHeader(_, ":scheme", "https", _));
  visitor.OnHeaderForStream(1, ":scheme", "https");

  EXPECT_CALL(callbacks, OnHeader(_, ":authority", "example.com", _));
  visitor.OnHeaderForStream(1, ":authority", "example.com");

  EXPECT_CALL(callbacks, OnHeader(_, "accept", "text/html", _));
  visitor.OnHeaderForStream(1, "accept", "text/html");

  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
                                               NGHTTP2_HCAT_REQUEST)));
  visitor.OnEndHeadersForStream(1);

  // DATA on stream 1
  EXPECT_CALL(callbacks,
              OnBeginFrame(HasFrameHeader(1, DATA, NGHTTP2_FLAG_END_STREAM)));
  visitor.OnFrameHeader(1, 25, DATA, NGHTTP2_FLAG_END_STREAM);

  visitor.OnBeginDataForStream(1, 25);
  EXPECT_CALL(callbacks, OnDataChunkRecv(NGHTTP2_FLAG_END_STREAM, 1,
                                         "This is the request body."));
  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, NGHTTP2_FLAG_END_STREAM)));
  visitor.OnDataForStream(1, "This is the request body.");
  EXPECT_TRUE(visitor.OnEndStream(1));

  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);

  EXPECT_EQ(visitor.stream_map_size(), 0);

  // RST_STREAM on stream 3
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, RST_STREAM, 0)));
  visitor.OnFrameHeader(3, 4, RST_STREAM, 0);

  EXPECT_CALL(callbacks, OnFrameRecv(IsRstStream(3, NGHTTP2_INTERNAL_ERROR)));
  visitor.OnRstStream(3, Http2ErrorCode::INTERNAL_ERROR);

  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_INTERNAL_ERROR));
  visitor.OnCloseStream(3, Http2ErrorCode::INTERNAL_ERROR);

  EXPECT_EQ(visitor.stream_map_size(), 0);
}

TEST(ServerCallbackVisitorUnitTest, DataWithPadding) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kServer,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);

  const size_t kPaddingLength = 39;
  const uint8_t kFlags = NGHTTP2_FLAG_PADDED | NGHTTP2_FLAG_END_STREAM;

  testing::InSequence seq;

  // DATA on stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(1, DATA, kFlags)));
  EXPECT_TRUE(visitor.OnFrameHeader(1, 25 + kPaddingLength, DATA, kFlags));

  EXPECT_TRUE(visitor.OnBeginDataForStream(1, 25 + kPaddingLength));

  // Padding before data.
  EXPECT_TRUE(visitor.OnDataPaddingLength(1, kPaddingLength));

  EXPECT_CALL(callbacks,
              OnDataChunkRecv(kFlags, 1, "This is the request body."));
  EXPECT_CALL(callbacks, OnFrameRecv(IsData(1, _, kFlags, kPaddingLength)));
  EXPECT_TRUE(visitor.OnDataForStream(1, "This is the request body."));
  EXPECT_TRUE(visitor.OnEndStream(1));

  EXPECT_CALL(callbacks, OnStreamClose(1, NGHTTP2_NO_ERROR));
  visitor.OnCloseStream(1, Http2ErrorCode::HTTP2_NO_ERROR);

  // DATA on stream 3
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(3, DATA, kFlags)));
  EXPECT_TRUE(visitor.OnFrameHeader(3, 25 + kPaddingLength, DATA, kFlags));

  EXPECT_TRUE(visitor.OnBeginDataForStream(3, 25 + kPaddingLength));

  // Data before padding.
  EXPECT_CALL(callbacks,
              OnDataChunkRecv(kFlags, 3, "This is the request body."));
  EXPECT_TRUE(visitor.OnDataForStream(3, "This is the request body."));

  EXPECT_CALL(callbacks, OnFrameRecv(IsData(3, _, kFlags, kPaddingLength)));
  EXPECT_TRUE(visitor.OnDataPaddingLength(3, kPaddingLength));
  EXPECT_TRUE(visitor.OnEndStream(3));

  EXPECT_CALL(callbacks, OnStreamClose(3, NGHTTP2_NO_ERROR));
  visitor.OnCloseStream(3, Http2ErrorCode::HTTP2_NO_ERROR);

  // DATA on stream 5
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(5, DATA, kFlags)));
  EXPECT_TRUE(visitor.OnFrameHeader(5, 25 + kPaddingLength, DATA, kFlags));

  EXPECT_TRUE(visitor.OnBeginDataForStream(5, 25 + kPaddingLength));

  // Error during padding.
  EXPECT_CALL(callbacks,
              OnDataChunkRecv(kFlags, 5, "This is the request body."));
  EXPECT_TRUE(visitor.OnDataForStream(5, "This is the request body."));

  EXPECT_CALL(callbacks, OnFrameRecv(IsData(5, _, kFlags, kPaddingLength)))
      .WillOnce(testing::Return(NGHTTP2_ERR_CALLBACK_FAILURE));
  EXPECT_TRUE(visitor.OnDataPaddingLength(5, kPaddingLength));
  EXPECT_FALSE(visitor.OnEndStream(3));

  EXPECT_CALL(callbacks, OnStreamClose(5, NGHTTP2_NO_ERROR));
  visitor.OnCloseStream(5, Http2ErrorCode::HTTP2_NO_ERROR);
}

// In the case of a Content-Length mismatch where the header value is larger
// than the actual data for the stream, nghttp2 will call
// `on_begin_frame_callback` and `on_data_chunk_recv_callback`, but not the
// `on_frame_recv_callback`.
TEST(ServerCallbackVisitorUnitTest, MismatchedContentLengthCallbacks) {
  testing::StrictMock<MockNghttp2Callbacks> callbacks;
  CallbackVisitor visitor(Perspective::kServer,
                          *MockNghttp2Callbacks::GetCallbacks(), &callbacks);
  auto adapter = NgHttp2Adapter::CreateServerAdapter(visitor);

  const std::string frames = TestFrameSequence()
                                 .ClientPreface()
                                 .Headers(1,
                                          {{":method", "POST"},
                                           {":scheme", "https"},
                                           {":authority", "example.com"},
                                           {":path", "/"},
                                           {"content-length", "50"}},
                                          /*fin=*/false)
                                 .Data(1, "Less than 50 bytes.", true)
                                 .Serialize();

  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(0, SETTINGS, _)));

  EXPECT_CALL(callbacks, OnFrameRecv(IsSettings(testing::IsEmpty())));

  // HEADERS on stream 1
  EXPECT_CALL(callbacks, OnBeginFrame(HasFrameHeader(
                             1, HEADERS, NGHTTP2_FLAG_END_HEADERS)));

  EXPECT_CALL(callbacks, OnBeginHeaders(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
                                                  NGHTTP2_HCAT_REQUEST)));

  EXPECT_CALL(callbacks, OnHeader(_, ":method", "POST", _));
  EXPECT_CALL(callbacks, OnHeader(_, ":path", "/", _));
  EXPECT_CALL(callbacks, OnHeader(_, ":scheme", "https", _));
  EXPECT_CALL(callbacks, OnHeader(_, ":authority", "example.com", _));
  EXPECT_CALL(callbacks, OnHeader(_, "content-length", "50", _));
  EXPECT_CALL(callbacks, OnFrameRecv(IsHeaders(1, NGHTTP2_FLAG_END_HEADERS,
                                               NGHTTP2_HCAT_REQUEST)));

  // DATA on stream 1
  EXPECT_CALL(callbacks,
              OnBeginFrame(HasFrameHeader(1, DATA, NGHTTP2_FLAG_END_STREAM)));

  EXPECT_CALL(callbacks, OnDataChunkRecv(NGHTTP2_FLAG_END_STREAM, 1,
                                         "Less than 50 bytes."));

  // Like nghttp2, CallbackVisitor does not pass on a call to OnFrameRecv in the
  // case of Content-Length mismatch.

  int64_t result = adapter->ProcessBytes(frames);
  EXPECT_EQ(frames.size(), result);
}

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