// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/spdy/core/spdy_deframer_visitor.h"

#include <stdlib.h>

#include <algorithm>
#include <cstdint>
#include <limits>
#include <memory>

#include "net/third_party/quiche/src/http2/platform/api/http2_macros.h"
#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
#include "net/third_party/quiche/src/spdy/core/hpack/hpack_constants.h"
#include "net/third_party/quiche/src/spdy/core/mock_spdy_framer_visitor.h"
#include "net/third_party/quiche/src/spdy/core/spdy_frame_reader.h"
#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_flags.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_logging.h"

using ::testing::AssertionFailure;
using ::testing::AssertionResult;
using ::testing::AssertionSuccess;

namespace spdy {
namespace test {

// Specify whether to process headers as request or response in visitor-related
// params.
enum class HeaderDirection { REQUEST, RESPONSE };

// Types of HTTP/2 frames, per RFC 7540.
// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
enum Http2FrameType {
  DATA = 0,
  HEADERS = 1,
  PRIORITY = 2,
  RST_STREAM = 3,
  SETTINGS = 4,
  PUSH_PROMISE = 5,
  PING = 6,
  GOAWAY = 7,
  WINDOW_UPDATE = 8,
  CONTINUATION = 9,
  ALTSVC = 10,

  // Not a frame type.
  UNSET = -1,
  UNKNOWN = -2,
};

// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
const char* Http2FrameTypeToString(Http2FrameType v) {
  switch (v) {
    case DATA:
      return "DATA";
    case HEADERS:
      return "HEADERS";
    case PRIORITY:
      return "PRIORITY";
    case RST_STREAM:
      return "RST_STREAM";
    case SETTINGS:
      return "SETTINGS";
    case PUSH_PROMISE:
      return "PUSH_PROMISE";
    case PING:
      return "PING";
    case GOAWAY:
      return "GOAWAY";
    case WINDOW_UPDATE:
      return "WINDOW_UPDATE";
    case CONTINUATION:
      return "CONTINUATION";
    case ALTSVC:
      return "ALTSVC";
    case UNSET:
      return "UNSET";
    case UNKNOWN:
      return "UNKNOWN";
    default:
      return "Invalid Http2FrameType";
  }
}

// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
inline std::ostream& operator<<(std::ostream& out, Http2FrameType v) {
  return out << Http2FrameTypeToString(v);
}

// Flag bits in the flag field of the common header of HTTP/2 frames
// (see https://httpwg.github.io/specs/rfc7540.html#FrameHeader for details on
// the fixed 9-octet header structure shared by all frames).
// Flag bits are only valid for specified frame types.
// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
enum Http2HeaderFlag {
  NO_FLAGS = 0,

  END_STREAM_FLAG = 0x1,
  ACK_FLAG = 0x1,
  END_HEADERS_FLAG = 0x4,
  PADDED_FLAG = 0x8,
  PRIORITY_FLAG = 0x20,
};

// Returns name of frame type.
// TODO(jamessynge): Switch to using http2/http2_constants.h when ready.
const char* Http2FrameTypeToString(Http2FrameType v);

void SpdyDeframerVisitorInterface::OnPingAck(
    std::unique_ptr<SpdyPingIR> frame) {
  OnPing(std::move(frame));
}

void SpdyDeframerVisitorInterface::OnSettingsAck(
    std::unique_ptr<SpdySettingsIR> frame) {
  OnSettings(std::move(frame), nullptr);
}

class SpdyTestDeframerImpl : public SpdyTestDeframer,
                             public SpdyHeadersHandlerInterface {
 public:
  explicit SpdyTestDeframerImpl(
      std::unique_ptr<SpdyDeframerVisitorInterface> listener)
      : listener_(std::move(listener)) {
    CHECK(listener_ != nullptr);
  }
  SpdyTestDeframerImpl(const SpdyTestDeframerImpl&) = delete;
  SpdyTestDeframerImpl& operator=(const SpdyTestDeframerImpl&) = delete;
  ~SpdyTestDeframerImpl() override = default;

  bool AtFrameEnd() override;

  // Callbacks defined in SpdyFramerVisitorInterface.  These are in the
  // alphabetical order for ease of navigation, and are not in same order
  // as in SpdyFramerVisitorInterface.
  void OnAltSvc(SpdyStreamId stream_id,
                quiche::QuicheStringPiece origin,
                const SpdyAltSvcWireFormat::AlternativeServiceVector&
                    altsvc_vector) override;
  void OnContinuation(SpdyStreamId stream_id, bool end) override;
  SpdyHeadersHandlerInterface* OnHeaderFrameStart(
      SpdyStreamId stream_id) override;
  void OnHeaderFrameEnd(SpdyStreamId stream_id) override;
  void OnDataFrameHeader(SpdyStreamId stream_id,
                         size_t length,
                         bool fin) override;
  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error) override;
  void OnGoAway(SpdyStreamId last_accepted_stream_id,
                SpdyErrorCode error_code) override;
  bool OnGoAwayFrameData(const char* goaway_data, size_t len) override;
  void OnHeaders(SpdyStreamId stream_id,
                 bool has_priority,
                 int weight,
                 SpdyStreamId parent_stream_id,
                 bool exclusive,
                 bool fin,
                 bool end) override;
  void OnPing(SpdyPingId unique_id, bool is_ack) override;
  void OnPriority(SpdyStreamId stream_id,
                  SpdyStreamId parent_stream_id,
                  int weight,
                  bool exclusive) override;
  void OnPushPromise(SpdyStreamId stream_id,
                     SpdyStreamId promised_stream_id,
                     bool end) override;
  void OnRstStream(SpdyStreamId stream_id, SpdyErrorCode error_code) override;
  void OnSetting(SpdySettingsId id, uint32_t value) override;
  void OnSettings() override;
  void OnSettingsAck() override;
  void OnSettingsEnd() override;
  void OnStreamFrameData(SpdyStreamId stream_id,
                         const char* data,
                         size_t len) override;
  void OnStreamEnd(SpdyStreamId stream_id) override;
  void OnStreamPadLength(SpdyStreamId stream_id, size_t value) override;
  void OnStreamPadding(SpdyStreamId stream_id, size_t len) override;
  bool OnUnknownFrame(SpdyStreamId stream_id, uint8_t frame_type) override;
  void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override;

  // Callbacks defined in SpdyHeadersHandlerInterface.

  void OnHeaderBlockStart() override;
  void OnHeader(quiche::QuicheStringPiece key,
                quiche::QuicheStringPiece value) override;
  void OnHeaderBlockEnd(size_t header_bytes_parsed,
                        size_t compressed_header_bytes_parsed) override;

 protected:
  void AtDataEnd();
  void AtGoAwayEnd();
  void AtHeadersEnd();
  void AtPushPromiseEnd();

  // Per-physical frame state.
  // Frame type of the frame currently being processed.
  Http2FrameType frame_type_ = UNSET;
  // Stream id of the frame currently being processed.
  SpdyStreamId stream_id_;
  // Did the most recent frame header include the END_HEADERS flag?
  bool end_ = false;
  // Did the most recent frame header include the ack flag?
  bool ack_ = false;

  // Per-HPACK block state. Only valid while processing a HEADERS or
  // PUSH_PROMISE frame, and its CONTINUATION frames.
  // Did the most recent HEADERS or PUSH_PROMISE include the END_STREAM flag?
  // Note that this does not necessarily indicate that the current frame is
  // the last frame for the stream (may be followed by CONTINUATION frames,
  // may only half close).
  bool fin_ = false;
  bool got_hpack_end_ = false;

  std::unique_ptr<std::string> data_;

  // Total length of the data frame.
  size_t data_len_ = 0;

  // Amount of skipped padding (i.e. total length of padding, including Pad
  // Length field).
  size_t padding_len_ = 0;

  std::unique_ptr<std::string> goaway_description_;
  std::unique_ptr<StringPairVector> headers_;
  std::unique_ptr<SettingVector> settings_;
  std::unique_ptr<TestHeadersHandler> headers_handler_;

  std::unique_ptr<SpdyGoAwayIR> goaway_ir_;
  std::unique_ptr<SpdyHeadersIR> headers_ir_;
  std::unique_ptr<SpdyPushPromiseIR> push_promise_ir_;
  std::unique_ptr<SpdySettingsIR> settings_ir_;

 private:
  std::unique_ptr<SpdyDeframerVisitorInterface> listener_;
};

// static
std::unique_ptr<SpdyTestDeframer> SpdyTestDeframer::CreateConverter(
    std::unique_ptr<SpdyDeframerVisitorInterface> listener) {
  return std::make_unique<SpdyTestDeframerImpl>(std::move(listener));
}

void SpdyTestDeframerImpl::AtDataEnd() {
  SPDY_DVLOG(1) << "AtDataEnd";
  CHECK_EQ(data_len_, padding_len_ + data_->size());
  auto ptr = std::make_unique<SpdyDataIR>(stream_id_, std::move(*data_));
  CHECK_EQ(0u, data_->size());
  data_.reset();

  CHECK_LE(0u, padding_len_);
  CHECK_LE(padding_len_, 256u);
  if (padding_len_ > 0) {
    ptr->set_padding_len(padding_len_);
  }
  padding_len_ = 0;

  ptr->set_fin(fin_);
  listener_->OnData(std::move(ptr));
  frame_type_ = UNSET;
  fin_ = false;
  data_len_ = 0;
}

void SpdyTestDeframerImpl::AtGoAwayEnd() {
  SPDY_DVLOG(1) << "AtDataEnd";
  CHECK_EQ(frame_type_, GOAWAY);
  if (HTTP2_DIE_IF_NULL(goaway_description_)->empty()) {
    listener_->OnGoAway(std::move(goaway_ir_));
  } else {
    listener_->OnGoAway(std::make_unique<SpdyGoAwayIR>(
        goaway_ir_->last_good_stream_id(), goaway_ir_->error_code(),
        std::move(*goaway_description_)));
    CHECK_EQ(0u, goaway_description_->size());
  }
  goaway_description_.reset();
  goaway_ir_.reset();
  frame_type_ = UNSET;
}

void SpdyTestDeframerImpl::AtHeadersEnd() {
  SPDY_DVLOG(1) << "AtDataEnd";
  CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(end_) << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(got_hpack_end_);

  CHECK(headers_ir_ != nullptr);
  CHECK(headers_ != nullptr);
  CHECK(headers_handler_ != nullptr);

  CHECK_LE(0u, padding_len_);
  CHECK_LE(padding_len_, 256u);
  if (padding_len_ > 0) {
    headers_ir_->set_padding_len(padding_len_);
  }
  padding_len_ = 0;

  headers_ir_->set_header_block(headers_handler_->decoded_block().Clone());
  headers_handler_.reset();
  listener_->OnHeaders(std::move(headers_ir_), std::move(headers_));

  frame_type_ = UNSET;
  fin_ = false;
  end_ = false;
  got_hpack_end_ = false;
}

void SpdyTestDeframerImpl::AtPushPromiseEnd() {
  SPDY_DVLOG(1) << "AtDataEnd";
  CHECK(frame_type_ == PUSH_PROMISE || frame_type_ == CONTINUATION)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(end_) << "   frame_type_=" << Http2FrameTypeToString(frame_type_);

  CHECK(push_promise_ir_ != nullptr);
  CHECK(headers_ != nullptr);
  CHECK(headers_handler_ != nullptr);

  CHECK_EQ(headers_ir_.get(), nullptr);

  CHECK_LE(0u, padding_len_);
  CHECK_LE(padding_len_, 256u);
  if (padding_len_ > 0) {
    push_promise_ir_->set_padding_len(padding_len_);
  }
  padding_len_ = 0;

  push_promise_ir_->set_header_block(headers_handler_->decoded_block().Clone());
  headers_handler_.reset();
  listener_->OnPushPromise(std::move(push_promise_ir_), std::move(headers_));

  frame_type_ = UNSET;
  end_ = false;
}

bool SpdyTestDeframerImpl::AtFrameEnd() {
  bool incomplete_logical_header = false;
  // The caller says that the SpdyFrame has reached the end of the frame,
  // so if we have any accumulated data, flush it.
  switch (frame_type_) {
    case DATA:
      AtDataEnd();
      break;

    case GOAWAY:
      AtGoAwayEnd();
      break;

    case HEADERS:
      if (end_) {
        AtHeadersEnd();
      } else {
        incomplete_logical_header = true;
      }
      break;

    case PUSH_PROMISE:
      if (end_) {
        AtPushPromiseEnd();
      } else {
        incomplete_logical_header = true;
      }
      break;

    case CONTINUATION:
      if (end_) {
        if (headers_ir_) {
          AtHeadersEnd();
        } else if (push_promise_ir_) {
          AtPushPromiseEnd();
        } else {
          SPDY_LOG(FATAL) << "Where is the SpdyFrameIR for the headers!";
        }
      } else {
        incomplete_logical_header = true;
      }
      break;

    case UNSET:
      // Except for the frame types above, the others don't leave any record
      // in the state of this object. Make sure nothing got left by accident.
      CHECK_EQ(data_.get(), nullptr);
      CHECK_EQ(goaway_description_.get(), nullptr);
      CHECK_EQ(goaway_ir_.get(), nullptr);
      CHECK_EQ(headers_.get(), nullptr);
      CHECK_EQ(headers_handler_.get(), nullptr);
      CHECK_EQ(headers_ir_.get(), nullptr);
      CHECK_EQ(push_promise_ir_.get(), nullptr);
      CHECK_EQ(settings_.get(), nullptr);
      CHECK_EQ(settings_ir_.get(), nullptr);
      break;

    default:
      SPDY_BUG << "Expected UNSET, instead frame_type_==" << frame_type_;
      return false;
  }
  frame_type_ = UNSET;
  stream_id_ = 0;
  end_ = false;
  ack_ = false;
  if (!incomplete_logical_header) {
    fin_ = false;
  }
  return true;
}

// Overridden methods from SpdyFramerVisitorInterface in alpha order...

void SpdyTestDeframerImpl::OnAltSvc(
    SpdyStreamId stream_id,
    quiche::QuicheStringPiece origin,
    const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) {
  SPDY_DVLOG(1) << "OnAltSvc stream_id: " << stream_id;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_GT(stream_id, 0u);
  auto ptr = std::make_unique<SpdyAltSvcIR>(stream_id);
  ptr->set_origin(std::string(origin));
  for (auto& altsvc : altsvc_vector) {
    ptr->add_altsvc(altsvc);
  }
  listener_->OnAltSvc(std::move(ptr));
}

// A CONTINUATION frame contains a Header Block Fragment, and immediately
// follows another frame that contains a Header Block Fragment (HEADERS,
// PUSH_PROMISE or CONTINUATION). The last such frame has the END flag set.
// SpdyFramer ensures that the behavior is correct before calling the visitor.
void SpdyTestDeframerImpl::OnContinuation(SpdyStreamId stream_id, bool end) {
  SPDY_DVLOG(1) << "OnContinuation stream_id: " << stream_id;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_GT(stream_id, 0u);
  CHECK_NE(nullptr, headers_.get());
  frame_type_ = CONTINUATION;

  stream_id_ = stream_id;
  end_ = end;
}

// Note that length includes the padding length (0 to 256, when the optional
// padding length field is counted). Padding comes after the payload, both
// for DATA frames and for control frames.
void SpdyTestDeframerImpl::OnDataFrameHeader(SpdyStreamId stream_id,
                                             size_t length,
                                             bool fin) {
  SPDY_DVLOG(1) << "OnDataFrameHeader stream_id: " << stream_id;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_GT(stream_id, 0u);
  CHECK_EQ(data_.get(), nullptr);
  frame_type_ = DATA;

  stream_id_ = stream_id;
  fin_ = fin;
  data_len_ = length;
  data_ = std::make_unique<std::string>();
}

// The SpdyFramer will not process any more data at this point.
void SpdyTestDeframerImpl::OnError(
    http2::Http2DecoderAdapter::SpdyFramerError error) {
  SPDY_DVLOG(1) << "SpdyFramer detected an error in the stream: "
                << http2::Http2DecoderAdapter::SpdyFramerErrorToString(error)
                << "     frame_type_: " << Http2FrameTypeToString(frame_type_);
  listener_->OnError(error, this);
}

// Received a GOAWAY frame from the peer. The last stream id it accepted from us
// is |last_accepted_stream_id|. |status| is a protocol defined error code.
// The frame may also contain data. After this OnGoAwayFrameData will be called
// for any non-zero amount of data, and after that it will be called with len==0
// to indicate the end of the GOAWAY frame.
void SpdyTestDeframerImpl::OnGoAway(SpdyStreamId last_good_stream_id,
                                    SpdyErrorCode error_code) {
  SPDY_DVLOG(1) << "OnGoAway last_good_stream_id: " << last_good_stream_id
                << "     error code: " << error_code;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  frame_type_ = GOAWAY;
  goaway_ir_ =
      std::make_unique<SpdyGoAwayIR>(last_good_stream_id, error_code, "");
  goaway_description_ = std::make_unique<std::string>();
}

// If len==0 then we've reached the end of the GOAWAY frame.
bool SpdyTestDeframerImpl::OnGoAwayFrameData(const char* goaway_data,
                                             size_t len) {
  SPDY_DVLOG(1) << "OnGoAwayFrameData";
  CHECK_EQ(frame_type_, GOAWAY)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(goaway_description_ != nullptr);
  goaway_description_->append(goaway_data, len);
  return true;
}

SpdyHeadersHandlerInterface* SpdyTestDeframerImpl::OnHeaderFrameStart(
    SpdyStreamId /*stream_id*/) {
  return this;
}

void SpdyTestDeframerImpl::OnHeaderFrameEnd(SpdyStreamId stream_id) {
  SPDY_DVLOG(1) << "OnHeaderFrameEnd stream_id: " << stream_id;
}

// Received the fixed portion of a HEADERS frame. Called before the variable
// length (including zero length) Header Block Fragment is processed. If fin
// is true then there will be no DATA or trailing HEADERS after this HEADERS
// frame.
// If end is true, then there will be no CONTINUATION frame(s) following this
// frame; else if true then there will be CONTINATION frames(s) immediately
// following this frame, terminated by a CONTINUATION frame with end==true.
void SpdyTestDeframerImpl::OnHeaders(SpdyStreamId stream_id,
                                     bool has_priority,
                                     int weight,
                                     SpdyStreamId parent_stream_id,
                                     bool exclusive,
                                     bool fin,
                                     bool end) {
  SPDY_DVLOG(1) << "OnHeaders stream_id: " << stream_id;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_GT(stream_id, 0u);
  frame_type_ = HEADERS;

  stream_id_ = stream_id;
  fin_ = fin;
  end_ = end;

  headers_ = std::make_unique<StringPairVector>();
  headers_handler_ = std::make_unique<TestHeadersHandler>();
  headers_ir_ = std::make_unique<SpdyHeadersIR>(stream_id);
  headers_ir_->set_fin(fin);
  if (has_priority) {
    headers_ir_->set_has_priority(true);
    headers_ir_->set_weight(weight);
    headers_ir_->set_parent_stream_id(parent_stream_id);
    headers_ir_->set_exclusive(exclusive);
  }
}

// The HTTP/2 protocol refers to the payload, |unique_id| here, as 8 octets of
// opaque data that is to be echoed back to the sender, with the ACK bit added.
// It isn't defined as a counter,
// or frame id, as the SpdyPingId naming might imply.
// Responding to a PING is supposed to be at the highest priority.
void SpdyTestDeframerImpl::OnPing(uint64_t unique_id, bool is_ack) {
  SPDY_DVLOG(1) << "OnPing unique_id: " << unique_id
                << "      is_ack: " << (is_ack ? "true" : "false");
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  auto ptr = std::make_unique<SpdyPingIR>(unique_id);
  if (is_ack) {
    ptr->set_is_ack(is_ack);
    listener_->OnPingAck(std::move(ptr));
  } else {
    listener_->OnPing(std::move(ptr));
  }
}

void SpdyTestDeframerImpl::OnPriority(SpdyStreamId stream_id,
                                      SpdyStreamId parent_stream_id,
                                      int weight,
                                      bool exclusive) {
  SPDY_DVLOG(1) << "OnPriority stream_id: " << stream_id;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_GT(stream_id, 0u);

  listener_->OnPriority(std::make_unique<SpdyPriorityIR>(
      stream_id, parent_stream_id, weight, exclusive));
}

void SpdyTestDeframerImpl::OnPushPromise(SpdyStreamId stream_id,
                                         SpdyStreamId promised_stream_id,
                                         bool end) {
  SPDY_DVLOG(1) << "OnPushPromise stream_id: " << stream_id;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_GT(stream_id, 0u);

  frame_type_ = PUSH_PROMISE;
  stream_id_ = stream_id;
  end_ = end;

  headers_ = std::make_unique<StringPairVector>();
  headers_handler_ = std::make_unique<TestHeadersHandler>();
  push_promise_ir_ =
      std::make_unique<SpdyPushPromiseIR>(stream_id, promised_stream_id);
}

// Closes the specified stream. After this the sender may still send PRIORITY
// frames for this stream, which we can ignore.
void SpdyTestDeframerImpl::OnRstStream(SpdyStreamId stream_id,
                                       SpdyErrorCode error_code) {
  SPDY_DVLOG(1) << "OnRstStream stream_id: " << stream_id
                << "     error code: " << error_code;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_GT(stream_id, 0u);

  listener_->OnRstStream(
      std::make_unique<SpdyRstStreamIR>(stream_id, error_code));
}

// Called for an individual setting. There is no negotiation; the sender is
// stating the value that the sender is using.
void SpdyTestDeframerImpl::OnSetting(SpdySettingsId id, uint32_t value) {
  SPDY_DVLOG(1) << "OnSetting id: " << id << std::hex << "    value: " << value;
  CHECK_EQ(frame_type_, SETTINGS)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(settings_ != nullptr);
  SpdyKnownSettingsId known_id;
  if (ParseSettingsId(id, &known_id)) {
    settings_->push_back(std::make_pair(known_id, value));
    settings_ir_->AddSetting(known_id, value);
  }
}

// Called at the start of a SETTINGS frame with setting entries, but not the
// (required) ACK of a SETTINGS frame. There is no stream_id because
// the settings apply to the entire connection, not to an individual stream.
void SpdyTestDeframerImpl::OnSettings() {
  SPDY_DVLOG(1) << "OnSettings";
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_EQ(nullptr, settings_ir_.get());
  CHECK_EQ(nullptr, settings_.get());
  frame_type_ = SETTINGS;
  ack_ = false;

  settings_ = std::make_unique<SettingVector>();
  settings_ir_ = std::make_unique<SpdySettingsIR>();
}

void SpdyTestDeframerImpl::OnSettingsAck() {
  SPDY_DVLOG(1) << "OnSettingsAck";
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  auto ptr = std::make_unique<SpdySettingsIR>();
  ptr->set_is_ack(true);
  listener_->OnSettingsAck(std::move(ptr));
}

void SpdyTestDeframerImpl::OnSettingsEnd() {
  SPDY_DVLOG(1) << "OnSettingsEnd";
  CHECK_EQ(frame_type_, SETTINGS)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(!ack_);
  CHECK_NE(nullptr, settings_ir_.get());
  CHECK_NE(nullptr, settings_.get());
  listener_->OnSettings(std::move(settings_ir_), std::move(settings_));
  frame_type_ = UNSET;
}

// Called for a zero length DATA frame with the END_STREAM flag set, or at the
// end a complete HPACK block (and its padding) that started with a HEADERS
// frame with the END_STREAM flag set. Doesn't apply to PUSH_PROMISE frames
// because they don't have END_STREAM flags.
void SpdyTestDeframerImpl::OnStreamEnd(SpdyStreamId stream_id) {
  SPDY_DVLOG(1) << "OnStreamEnd stream_id: " << stream_id;
  CHECK_EQ(stream_id_, stream_id);
  CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
        frame_type_ == CONTINUATION)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(fin_);
}

// The data arg points into the non-padding payload of a DATA frame.
// This must be a DATA frame (i.e. this method will not be
// called for HEADERS or CONTINUATION frames).
// This method may be called multiple times for a single DATA frame, depending
// upon buffer boundaries.
void SpdyTestDeframerImpl::OnStreamFrameData(SpdyStreamId stream_id,
                                             const char* data,
                                             size_t len) {
  SPDY_DVLOG(1) << "OnStreamFrameData stream_id: " << stream_id
                << "    len: " << len;
  CHECK_EQ(stream_id_, stream_id);
  CHECK_EQ(frame_type_, DATA);
  data_->append(data, len);
}

// Called when receiving the padding length field at the start of the DATA frame
// payload. value will be in the range 0 to 255.
void SpdyTestDeframerImpl::OnStreamPadLength(SpdyStreamId stream_id,
                                             size_t value) {
  SPDY_DVLOG(1) << "OnStreamPadding stream_id: " << stream_id
                << "    value: " << value;
  CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
        frame_type_ == PUSH_PROMISE)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_EQ(stream_id_, stream_id);
  CHECK_GE(255u, value);
  // Count the padding length byte against total padding.
  padding_len_ += 1;
  CHECK_EQ(1u, padding_len_);
}

// Called when padding is skipped over at the end of the DATA frame. len will
// be in the range 1 to 255.
void SpdyTestDeframerImpl::OnStreamPadding(SpdyStreamId stream_id, size_t len) {
  SPDY_DVLOG(1) << "OnStreamPadding stream_id: " << stream_id
                << "    len: " << len;
  CHECK(frame_type_ == DATA || frame_type_ == HEADERS ||
        frame_type_ == PUSH_PROMISE)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_EQ(stream_id_, stream_id);
  CHECK_LE(1u, len);
  CHECK_GE(255u, len);
  padding_len_ += len;
  CHECK_LE(padding_len_, 256u) << "len=" << len;
}

// WINDOW_UPDATE is supposed to be hop-by-hop, according to the spec.
// stream_id is 0 if the update applies to the connection, else stream_id
// will be the id of a stream previously seen, which maybe half or fully
// closed.
void SpdyTestDeframerImpl::OnWindowUpdate(SpdyStreamId stream_id,
                                          int delta_window_size) {
  SPDY_DVLOG(1) << "OnWindowUpdate stream_id: " << stream_id
                << "    delta_window_size: " << delta_window_size;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK_NE(0, delta_window_size);

  listener_->OnWindowUpdate(
      std::make_unique<SpdyWindowUpdateIR>(stream_id, delta_window_size));
}

// Return true to indicate that the stream_id is valid; if not valid then
// SpdyFramer considers the connection corrupted. Requires keeping track
// of the set of currently open streams. For now we'll assume that unknown
// frame types are unsupported.
bool SpdyTestDeframerImpl::OnUnknownFrame(SpdyStreamId stream_id,
                                          uint8_t /*frame_type*/) {
  SPDY_DVLOG(1) << "OnAltSvc stream_id: " << stream_id;
  CHECK_EQ(frame_type_, UNSET)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  frame_type_ = UNKNOWN;

  stream_id_ = stream_id;
  return false;
}

// Callbacks defined in SpdyHeadersHandlerInterface.

void SpdyTestDeframerImpl::OnHeaderBlockStart() {
  CHECK(frame_type_ == HEADERS || frame_type_ == PUSH_PROMISE)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(headers_ != nullptr);
  CHECK_EQ(0u, headers_->size());
  got_hpack_end_ = false;
}

void SpdyTestDeframerImpl::OnHeader(quiche::QuicheStringPiece key,
                                    quiche::QuicheStringPiece value) {
  CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION ||
        frame_type_ == PUSH_PROMISE)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(!got_hpack_end_);
  HTTP2_DIE_IF_NULL(headers_)->emplace_back(std::string(key),
                                            std::string(value));
  HTTP2_DIE_IF_NULL(headers_handler_)->OnHeader(key, value);
}

void SpdyTestDeframerImpl::OnHeaderBlockEnd(
    size_t /* header_bytes_parsed */,
    size_t /* compressed_header_bytes_parsed */) {
  CHECK(headers_ != nullptr);
  CHECK(frame_type_ == HEADERS || frame_type_ == CONTINUATION ||
        frame_type_ == PUSH_PROMISE)
      << "   frame_type_=" << Http2FrameTypeToString(frame_type_);
  CHECK(end_);
  CHECK(!got_hpack_end_);
  got_hpack_end_ = true;
}

class LoggingSpdyDeframerDelegate : public SpdyDeframerVisitorInterface {
 public:
  explicit LoggingSpdyDeframerDelegate(
      std::unique_ptr<SpdyDeframerVisitorInterface> wrapped)
      : wrapped_(std::move(wrapped)) {
    if (!wrapped_) {
      wrapped_ = std::make_unique<SpdyDeframerVisitorInterface>();
    }
  }
  ~LoggingSpdyDeframerDelegate() override = default;

  void OnAltSvc(std::unique_ptr<SpdyAltSvcIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnAltSvc";
    wrapped_->OnAltSvc(std::move(frame));
  }
  void OnData(std::unique_ptr<SpdyDataIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnData";
    wrapped_->OnData(std::move(frame));
  }
  void OnGoAway(std::unique_ptr<SpdyGoAwayIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnGoAway";
    wrapped_->OnGoAway(std::move(frame));
  }

  // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
  // significantly modifies the headers, so the actual header entries (name
  // and value strings) are provided in a vector.
  void OnHeaders(std::unique_ptr<SpdyHeadersIR> frame,
                 std::unique_ptr<StringPairVector> headers) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnHeaders";
    wrapped_->OnHeaders(std::move(frame), std::move(headers));
  }

  void OnPing(std::unique_ptr<SpdyPingIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPing";
    wrapped_->OnPing(std::move(frame));
  }
  void OnPingAck(std::unique_ptr<SpdyPingIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPingAck";
    wrapped_->OnPingAck(std::move(frame));
  }

  void OnPriority(std::unique_ptr<SpdyPriorityIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPriority";
    wrapped_->OnPriority(std::move(frame));
  }

  // SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
  // significantly modifies the headers, so the actual header entries (name
  // and value strings) are provided in a vector.
  void OnPushPromise(std::unique_ptr<SpdyPushPromiseIR> frame,
                     std::unique_ptr<StringPairVector> headers) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnPushPromise";
    wrapped_->OnPushPromise(std::move(frame), std::move(headers));
  }

  void OnRstStream(std::unique_ptr<SpdyRstStreamIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnRstStream";
    wrapped_->OnRstStream(std::move(frame));
  }

  // SpdySettingsIR has a map for settings, so loses info about the order of
  // settings, and whether the same setting appeared more than once, so the
  // the actual settings (parameter and value) are provided in a vector.
  void OnSettings(std::unique_ptr<SpdySettingsIR> frame,
                  std::unique_ptr<SettingVector> settings) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnSettings";
    wrapped_->OnSettings(std::move(frame), std::move(settings));
  }

  // A settings frame with an ACK has no content, but for uniformity passing
  // a frame with the ACK flag set.
  void OnSettingsAck(std::unique_ptr<SpdySettingsIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnSettingsAck";
    wrapped_->OnSettingsAck(std::move(frame));
  }

  void OnWindowUpdate(std::unique_ptr<SpdyWindowUpdateIR> frame) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnWindowUpdate";
    wrapped_->OnWindowUpdate(std::move(frame));
  }

  // The SpdyFramer will not process any more data at this point.
  void OnError(http2::Http2DecoderAdapter::SpdyFramerError error,
               SpdyTestDeframer* deframer) override {
    SPDY_DVLOG(1) << "LoggingSpdyDeframerDelegate::OnError";
    wrapped_->OnError(error, deframer);
  }

 private:
  std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_;
};

// static
std::unique_ptr<SpdyDeframerVisitorInterface>
SpdyDeframerVisitorInterface::LogBeforeVisiting(
    std::unique_ptr<SpdyDeframerVisitorInterface> wrapped_listener) {
  return std::make_unique<LoggingSpdyDeframerDelegate>(
      std::move(wrapped_listener));
}

CollectedFrame::CollectedFrame() = default;

CollectedFrame::CollectedFrame(CollectedFrame&& other)
    : frame_ir(std::move(other.frame_ir)),
      headers(std::move(other.headers)),
      settings(std::move(other.settings)),
      error_reported(other.error_reported) {}

CollectedFrame::~CollectedFrame() = default;

CollectedFrame& CollectedFrame::operator=(CollectedFrame&& other) {
  frame_ir = std::move(other.frame_ir);
  headers = std::move(other.headers);
  settings = std::move(other.settings);
  error_reported = other.error_reported;
  return *this;
}

AssertionResult CollectedFrame::VerifyHasHeaders(
    const StringPairVector& expected_headers) const {
  VERIFY_NE(headers.get(), nullptr);
  VERIFY_THAT(*headers, ::testing::ContainerEq(expected_headers));
  return AssertionSuccess();
}

AssertionResult CollectedFrame::VerifyHasSettings(
    const SettingVector& expected_settings) const {
  VERIFY_NE(settings.get(), nullptr);
  VERIFY_THAT(*settings, testing::ContainerEq(expected_settings));
  return AssertionSuccess();
}

DeframerCallbackCollector::DeframerCallbackCollector(
    std::vector<CollectedFrame>* collected_frames)
    : collected_frames_(HTTP2_DIE_IF_NULL(collected_frames)) {}

void DeframerCallbackCollector::OnAltSvc(
    std::unique_ptr<SpdyAltSvcIR> frame_ir) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}
void DeframerCallbackCollector::OnData(std::unique_ptr<SpdyDataIR> frame_ir) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}
void DeframerCallbackCollector::OnGoAway(
    std::unique_ptr<SpdyGoAwayIR> frame_ir) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}

// SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
// significantly modifies the headers, so the actual header entries (name
// and value strings) are provided in a vector.
void DeframerCallbackCollector::OnHeaders(
    std::unique_ptr<SpdyHeadersIR> frame_ir,
    std::unique_ptr<StringPairVector> headers) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  cf.headers = std::move(headers);
  collected_frames_->push_back(std::move(cf));
}

void DeframerCallbackCollector::OnPing(std::unique_ptr<SpdyPingIR> frame_ir) {
  EXPECT_TRUE(frame_ir && !frame_ir->is_ack());
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}

void DeframerCallbackCollector::OnPingAck(
    std::unique_ptr<SpdyPingIR> frame_ir) {
  EXPECT_TRUE(frame_ir && frame_ir->is_ack());
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}

void DeframerCallbackCollector::OnPriority(
    std::unique_ptr<SpdyPriorityIR> frame_ir) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}

// SpdyHeadersIR and SpdyPushPromiseIR each has a SpdyHeaderBlock which
// significantly modifies the headers, so the actual header entries (name
// and value strings) are provided in a vector.
void DeframerCallbackCollector::OnPushPromise(
    std::unique_ptr<SpdyPushPromiseIR> frame_ir,
    std::unique_ptr<StringPairVector> headers) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  cf.headers = std::move(headers);
  collected_frames_->push_back(std::move(cf));
}

void DeframerCallbackCollector::OnRstStream(
    std::unique_ptr<SpdyRstStreamIR> frame_ir) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}

// SpdySettingsIR has a map for settings, so loses info about the order of
// settings, and whether the same setting appeared more than once, so the
// the actual settings (parameter and value) are provided in a vector.
void DeframerCallbackCollector::OnSettings(
    std::unique_ptr<SpdySettingsIR> frame_ir,
    std::unique_ptr<SettingVector> settings) {
  EXPECT_TRUE(frame_ir && !frame_ir->is_ack());
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  cf.settings = std::move(settings);
  collected_frames_->push_back(std::move(cf));
}

// A settings frame_ir with an ACK has no content, but for uniformity passing
// a frame_ir with the ACK flag set.
void DeframerCallbackCollector::OnSettingsAck(
    std::unique_ptr<SpdySettingsIR> frame_ir) {
  EXPECT_TRUE(frame_ir && frame_ir->is_ack());
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}

void DeframerCallbackCollector::OnWindowUpdate(
    std::unique_ptr<SpdyWindowUpdateIR> frame_ir) {
  CollectedFrame cf;
  cf.frame_ir = std::move(frame_ir);
  collected_frames_->push_back(std::move(cf));
}

// The SpdyFramer will not process any more data at this point.
void DeframerCallbackCollector::OnError(
    http2::Http2DecoderAdapter::SpdyFramerError /*error*/,
    SpdyTestDeframer* /*deframer*/) {
  CollectedFrame cf;
  cf.error_reported = true;
  collected_frames_->push_back(std::move(cf));
}

}  // namespace test
}  // namespace spdy
