// 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 "absl/strings/string_view.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_macros.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,
                absl::string_view 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,
               std::string detailed_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(absl::string_view key, absl::string_view 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,
    absl::string_view 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,
    std::string /*detailed_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_accepted_stream_id,
                                    SpdyErrorCode error_code) {
  SPDY_DVLOG(1) << "OnGoAway last_accepted_stream_id: "
                << last_accepted_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_accepted_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(absl::string_view key,
                                    absl::string_view 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
