// Copyright 2013 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/quic/quic_test_packet_maker.h"

#include <list>
#include <utility>

#include "net/quic/mock_crypto_client_stream.h"
#include "net/quic/quic_http_utils.h"
#include "net/third_party/quic/core/quic_framer.h"
#include "net/third_party/quic/core/quic_utils.h"
#include "net/third_party/quic/test_tools/mock_random.h"
#include "net/third_party/quic/test_tools/quic_test_utils.h"
#include "net/third_party/quic/test_tools/simple_data_producer.h"

namespace net {
namespace test {
namespace {

quic::QuicAckFrame MakeAckFrame(uint64_t largest_observed) {
  quic::QuicAckFrame ack;
  ack.largest_acked = quic::QuicPacketNumber(largest_observed);
  return ack;
}

}  // namespace

QuicTestPacketMaker::QuicTestPacketMaker(
    quic::QuicTransportVersion version,
    quic::QuicConnectionId connection_id,
    quic::MockClock* clock,
    const std::string& host,
    quic::Perspective perspective,
    bool client_headers_include_h2_stream_dependency)
    : version_(version),
      connection_id_(connection_id),
      clock_(clock),
      host_(host),
      spdy_request_framer_(spdy::SpdyFramer::ENABLE_COMPRESSION),
      spdy_response_framer_(spdy::SpdyFramer::ENABLE_COMPRESSION),
      perspective_(perspective),
      encryption_level_(quic::ENCRYPTION_FORWARD_SECURE),
      long_header_type_(quic::INVALID_PACKET_TYPE),
      client_headers_include_h2_stream_dependency_(
          client_headers_include_h2_stream_dependency &&
          version >= quic::QUIC_VERSION_43) {
  DCHECK(!(perspective_ == quic::Perspective::IS_SERVER &&
           client_headers_include_h2_stream_dependency_));
}

QuicTestPacketMaker::~QuicTestPacketMaker() {}

void QuicTestPacketMaker::set_hostname(const std::string& host) {
  host_.assign(host);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeConnectivityProbingPacket(uint64_t num,
                                                   bool include_version) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicFramer framer(quic::test::SupportedVersions(quic::ParsedQuicVersion(
                              quic::PROTOCOL_QUIC_CRYPTO, version_)),
                          clock_->Now(), perspective_);
  size_t max_plaintext_size =
      framer.GetMaxPlaintextSize(quic::kDefaultMaxPacketSize);
  char buffer[quic::kDefaultMaxPacketSize];
  size_t length;
  if (version_ != quic::QUIC_VERSION_99) {
    length = framer.BuildConnectivityProbingPacket(
        header, buffer, max_plaintext_size, encryption_level_);
  } else if (perspective_ == quic::Perspective::IS_CLIENT) {
    quic::test::MockRandom rand(0);
    quic::QuicPathFrameBuffer payload;
    length = framer.BuildPaddedPathChallengePacket(
        header, buffer, max_plaintext_size, &payload, &rand, encryption_level_);
  } else {
    quic::test::MockRandom rand(0);
    quic::QuicPathFrameBuffer payload;
    rand.RandBytes(payload.data(), payload.size());
    quic::QuicDeque<quic::QuicPathFrameBuffer> payloads{payload};
    length = framer.BuildPathResponsePacket(header, buffer, max_plaintext_size,
                                            payloads, true, encryption_level_);
  }
  size_t encrypted_size = framer.EncryptInPlace(
      quic::ENCRYPTION_NONE, header.packet_number,
      GetStartOfEncryptedData(framer.transport_version(), header), length,
      quic::kDefaultMaxPacketSize, buffer);
  EXPECT_EQ(quic::kDefaultMaxPacketSize, encrypted_size);
  quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
                                     false);
  return encrypted.Clone();
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakePingPacket(
    uint64_t num,
    bool include_version) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicPingFrame ping;
  return MakePacket(header, quic::QuicFrame(ping));
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeDummyCHLOPacket(uint64_t packet_num) {
  SetEncryptionLevel(quic::ENCRYPTION_NONE);
  InitializeHeader(packet_num, /*include_version=*/true);

  quic::CryptoHandshakeMessage message =
      MockCryptoClientStream::GetDummyCHLOMessage();
  const quic::QuicData& data = message.GetSerialized();

  quic::QuicFrames frames;
  quic::QuicCryptoFrame crypto_frame;
  quic::test::SimpleDataProducer producer;
  quic::QuicStreamFrameDataProducer* producer_p = nullptr;
  if (version_ < quic::QUIC_VERSION_47) {
    quic::QuicStreamFrame frame(quic::QuicUtils::GetCryptoStreamId(version_),
                                /*fin=*/false, /*offset=*/0,
                                data.AsStringPiece());
    frames.push_back(quic::QuicFrame(frame));
  } else {
    crypto_frame =
        quic::QuicCryptoFrame(quic::ENCRYPTION_NONE, 0, data.length());
    producer.SaveCryptoData(quic::ENCRYPTION_NONE, 0, data.AsStringPiece());
    frames.push_back(quic::QuicFrame(&crypto_frame));
    producer_p = &producer;
  }
  DVLOG(1) << "Adding frame: " << frames.back();
  quic::QuicPaddingFrame padding;
  frames.push_back(quic::QuicFrame(padding));
  DVLOG(1) << "Adding frame: " << frames.back();

  std::unique_ptr<quic::QuicReceivedPacket> packet =
      MakeMultipleFramesPacket(header_, frames, producer_p);
  return packet;
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndPingPacket(uint64_t num,
                                          bool include_version,
                                          uint64_t largest_received,
                                          uint64_t smallest_received,
                                          uint64_t least_unacked) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = quic::QuicTime::Delta::Zero();
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    ack.packets.AddRange(quic::QuicPacketNumber(1),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(&ack));
  DVLOG(1) << "Adding frame: " << frames.back();

  frames.push_back(quic::QuicFrame(quic::QuicPingFrame()));
  DVLOG(1) << "Adding frame: " << frames.back();

  return MakeMultipleFramesPacket(header, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
    uint64_t num,
    bool include_version,
    quic::QuicStreamId stream_id,
    quic::QuicRstStreamErrorCode error_code) {
  return MakeRstPacket(num, include_version, stream_id, error_code, 0,
                       /*include_stop_sending_if_v99=*/true);
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
    uint64_t num,
    bool include_version,
    quic::QuicStreamId stream_id,
    quic::QuicRstStreamErrorCode error_code,
    size_t bytes_written,
    bool include_stop_sending_if_v99) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicFrames frames;

  quic::QuicRstStreamFrame rst(1, stream_id, error_code, bytes_written);
  frames.push_back(quic::QuicFrame(&rst));
  DVLOG(1) << "Adding frame: " << frames.back();

  // The STOP_SENDING frame must be outside of the if (version==99) so that it
  // stays in scope until the packet is built.
  quic::QuicStopSendingFrame stop(1, stream_id, error_code);
  if (include_stop_sending_if_v99 && version_ == quic::QUIC_VERSION_99) {
    frames.push_back(quic::QuicFrame(&stop));
    DVLOG(1) << "Adding frame: " << frames.back();
  }
  return MakeMultipleFramesPacket(header, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeStreamIdBlockedPacket(uint64_t num,
                                               bool include_version,
                                               quic::QuicStreamId stream_id) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicStreamIdBlockedFrame frame(1, stream_id);
  DVLOG(1) << "Adding frame: " << quic::QuicFrame(frame);
  return MakePacket(header, quic::QuicFrame(frame));
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeMaxStreamIdPacket(uint64_t num,
                                           bool include_version,
                                           quic::QuicStreamId stream_id) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicMaxStreamIdFrame frame(1, stream_id);
  DVLOG(1) << "Adding frame: " << quic::QuicFrame(frame);
  return MakePacket(header, quic::QuicFrame(frame));
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRstAndRequestHeadersPacket(
    uint64_t num,
    bool include_version,
    quic::QuicStreamId rst_stream_id,
    quic::QuicRstStreamErrorCode rst_error_code,
    quic::QuicStreamId stream_id,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id,
    size_t* spdy_headers_frame_length,
    quic::QuicStreamOffset* offset) {
  quic::QuicRstStreamFrame rst_frame(1, rst_stream_id, rst_error_code, 0);

  spdy::SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
      stream_id, fin, priority, std::move(headers), parent_stream_id);
  if (spdy_headers_frame_length) {
    *spdy_headers_frame_length = spdy_frame.size();
  }
  quic::QuicStreamOffset header_offset = 0;
  if (offset != nullptr) {
    header_offset = *offset;
    *offset += spdy_frame.size();
  }
  quic::QuicStreamFrame headers_frame(
      quic::QuicUtils::GetHeadersStreamId(version_), false, header_offset,
      quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));

  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(&rst_frame));
  DVLOG(1) << "Adding frame: " << frames.back();

  // The STOP_SENDING frame must be outside of the if (version==99) so that it
  // stays in scope until the packet is built.
  quic::QuicStopSendingFrame stop(1, rst_stream_id, rst_error_code);
  if (version_ == quic::QUIC_VERSION_99) {
    frames.push_back(quic::QuicFrame(&stop));
    DVLOG(1) << "Adding frame: " << frames.back();
  }
  frames.push_back(quic::QuicFrame(headers_frame));
  DVLOG(1) << "Adding frame: " << frames.back();

  InitializeHeader(num, include_version);
  return MakeMultipleFramesPacket(header_, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndRstPacket(
    uint64_t num,
    bool include_version,
    quic::QuicStreamId stream_id,
    quic::QuicRstStreamErrorCode error_code,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    bool send_feedback) {
  return MakeAckAndRstPacket(num, include_version, stream_id, error_code,
                             largest_received, smallest_received, least_unacked,
                             send_feedback, 0,
                             /*include_stop_sending_if_v99=*/true);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndRstPacket(
    uint64_t num,
    bool include_version,
    quic::QuicStreamId stream_id,
    quic::QuicRstStreamErrorCode error_code,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    bool send_feedback,
    size_t bytes_written,
    bool include_stop_sending_if_v99) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = quic::QuicTime::Delta::Zero();
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    ack.packets.AddRange(quic::QuicPacketNumber(1),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(&ack));
  DVLOG(1) << "Adding frame: " << frames.back();

  quic::QuicRstStreamFrame rst(1, stream_id, error_code, bytes_written);
  frames.push_back(quic::QuicFrame(&rst));
  DVLOG(1) << "Adding frame: " << frames.back();

  // The STOP_SENDING frame must be outside of the if (version==99) so that it
  // stays in scope until the packet is built.
  quic::QuicStopSendingFrame stop(1, stream_id, error_code);
  if (version_ == quic::QUIC_VERSION_99 && include_stop_sending_if_v99) {
    frames.push_back(quic::QuicFrame(&stop));
    DVLOG(1) << "Adding frame: " << frames.back();
  }

  return MakeMultipleFramesPacket(header, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRstAckAndConnectionClosePacket(
    uint64_t num,
    bool include_version,
    quic::QuicStreamId stream_id,
    quic::QuicRstStreamErrorCode error_code,
    quic::QuicTime::Delta ack_delay_time,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    quic::QuicErrorCode quic_error,
    const std::string& quic_error_details) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicFrames frames;
  quic::QuicRstStreamFrame rst(1, stream_id, error_code, 0);
  frames.push_back(quic::QuicFrame(&rst));
  DVLOG(1) << "Adding frame: " << frames.back();

  // The STOP_SENDING frame must be outside of the if (version==99) so that it
  // stays in scope until the packet is built.
  quic::QuicStopSendingFrame stop(
      1, stream_id, static_cast<quic::QuicApplicationErrorCode>(error_code));
  if (version_ == quic::QUIC_VERSION_99) {
    frames.push_back(quic::QuicFrame(&stop));
    DVLOG(1) << "Adding frame: " << frames.back();
  }

  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = ack_delay_time;
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    ack.packets.AddRange(quic::QuicPacketNumber(1),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  frames.push_back(quic::QuicFrame(&ack));
  DVLOG(1) << "Adding frame: " << frames.back();

  quic::QuicConnectionCloseFrame close;
  close.error_code = quic_error;
  close.error_details = quic_error_details;

  frames.push_back(quic::QuicFrame(&close));
  DVLOG(1) << "Adding frame: " << frames.back();

  return MakeMultipleFramesPacket(header, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndConnectionClosePacket(
    uint64_t num,
    bool include_version,
    quic::QuicTime::Delta ack_delay_time,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    quic::QuicErrorCode quic_error,
    const std::string& quic_error_details) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = ack_delay_time;
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    ack.packets.AddRange(quic::QuicPacketNumber(1),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(&ack));
  DVLOG(1) << "Adding frame: " << frames.back();

  quic::QuicConnectionCloseFrame close;
  close.error_code = quic_error;
  close.error_details = quic_error_details;

  frames.push_back(quic::QuicFrame(&close));
  DVLOG(1) << "Adding frame: " << frames.back();

  return MakeMultipleFramesPacket(header, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeConnectionClosePacket(
    uint64_t num,
    bool include_version,
    quic::QuicErrorCode quic_error,
    const std::string& quic_error_details) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(include_version);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicConnectionCloseFrame close;
  close.error_code = quic_error;
  close.error_details = quic_error_details;
  return MakePacket(header, quic::QuicFrame(&close));
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeGoAwayPacket(
    uint64_t num,
    quic::QuicErrorCode error_code,
    std::string reason_phrase) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(false);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(num);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicGoAwayFrame goaway;
  goaway.error_code = error_code;
  goaway.last_good_stream_id = 0;
  goaway.reason_phrase = reason_phrase;
  return MakePacket(header, quic::QuicFrame(&goaway));
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
    uint64_t packet_number,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    bool send_feedback) {
  return MakeAckPacket(packet_number, 1, largest_received, smallest_received,
                       least_unacked, send_feedback,
                       quic::QuicTime::Delta::Zero());
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
    uint64_t packet_number,
    uint64_t first_received,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    bool send_feedback) {
  return MakeAckPacket(packet_number, first_received, largest_received,
                       smallest_received, least_unacked, send_feedback,
                       quic::QuicTime::Delta::Zero());
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
    uint64_t packet_number,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    bool send_feedback,
    quic::QuicTime::Delta ack_delay_time) {
  return MakeAckPacket(packet_number, 1, largest_received, smallest_received,
                       least_unacked, send_feedback, ack_delay_time);
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
    uint64_t packet_number,
    uint64_t first_received,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    bool send_feedback,
    quic::QuicTime::Delta ack_delay_time) {
  quic::QuicPacketHeader header;
  header.destination_connection_id = connection_id_;
  header.destination_connection_id_included = HasDestinationConnectionId();
  header.source_connection_id = connection_id_;
  header.source_connection_id_included = HasSourceConnectionId();
  header.reset_flag = false;
  header.version_flag = ShouldIncludeVersion(false);
  header.long_packet_type = long_header_type_;
  header.packet_number_length = GetPacketNumberLength();
  header.packet_number = quic::QuicPacketNumber(packet_number);

  if (quic::QuicVersionHasLongHeaderLengths(version_) && header.version_flag) {
    if (long_header_type_ == quic::INITIAL) {
      header.retry_token_length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }

  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = ack_delay_time;
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    DCHECK_GE(largest_received, first_received);
    ack.packets.AddRange(quic::QuicPacketNumber(first_received),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  quic::QuicFramer framer(quic::test::SupportedVersions(quic::ParsedQuicVersion(
                              quic::PROTOCOL_QUIC_CRYPTO, version_)),
                          clock_->Now(), perspective_);
  quic::QuicFrames frames;
  quic::QuicFrame ack_frame(&ack);
  frames.push_back(ack_frame);
  DVLOG(1) << "Adding frame: " << frames.back();

  std::unique_ptr<quic::QuicPacket> packet(
      quic::test::BuildUnsizedDataPacket(&framer, header, frames));
  char buffer[quic::kMaxPacketSize];
  size_t encrypted_size =
      framer.EncryptPayload(quic::ENCRYPTION_NONE, header.packet_number,
                            *packet, buffer, quic::kMaxPacketSize);
  EXPECT_NE(0u, encrypted_size);
  quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
                                     false);
  return encrypted.Clone();
}

// Returns a newly created packet to send kData on stream 1.
std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeDataPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    quic::QuicStreamOffset offset,
    quic::QuicStringPiece data) {
  InitializeHeader(packet_number, should_include_version);
  quic::QuicStreamFrame frame(stream_id, fin, offset, data);
  DVLOG(1) << "Adding frame: " << frame;
  return MakePacket(header_, quic::QuicFrame(frame));
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeMultipleDataFramesPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    quic::QuicStreamOffset offset,
    const std::vector<std::string>& data_writes) {
  InitializeHeader(packet_number, should_include_version);
  quic::QuicFrames data_frames;
  for (size_t i = 0; i < data_writes.size(); ++i) {
    bool is_fin = fin && (i == data_writes.size() - 1);
    quic::QuicFrame quic_frame(quic::QuicStreamFrame(
        stream_id, is_fin, offset, quic::QuicStringPiece(data_writes[i])));
    DVLOG(1) << "Adding frame: " << quic_frame;
    data_frames.push_back(quic_frame);
    offset += data_writes[i].length();
  }
  return MakeMultipleFramesPacket(header_, data_frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndDataPacket(uint64_t packet_number,
                                          bool include_version,
                                          quic::QuicStreamId stream_id,
                                          uint64_t largest_received,
                                          uint64_t smallest_received,
                                          uint64_t least_unacked,
                                          bool fin,
                                          quic::QuicStreamOffset offset,
                                          quic::QuicStringPiece data) {
  InitializeHeader(packet_number, include_version);

  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = quic::QuicTime::Delta::Zero();
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    ack.packets.AddRange(quic::QuicPacketNumber(1),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(&ack));
  DVLOG(1) << "Adding frame: " << frames.back();

  frames.push_back(
      quic::QuicFrame(quic::QuicStreamFrame(stream_id, fin, offset, data)));
  DVLOG(1) << "Adding frame: " << frames.back();

  return MakeMultipleFramesPacket(header_, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndMultipleDataFramesPacket(
    uint64_t packet_number,
    bool include_version,
    quic::QuicStreamId stream_id,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    bool fin,
    quic::QuicStreamOffset offset,
    const std::vector<std::string>& data_writes) {
  InitializeHeader(packet_number, include_version);

  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = quic::QuicTime::Delta::Zero();
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    ack.packets.AddRange(quic::QuicPacketNumber(1),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(&ack));
  DVLOG(1) << "Adding frame: " << frames.back();

  for (size_t i = 0; i < data_writes.size(); ++i) {
    bool is_fin = fin && (i == data_writes.size() - 1);
    quic::QuicFrame quic_frame(quic::QuicStreamFrame(
        stream_id, is_fin, offset, quic::QuicStringPiece(data_writes[i])));
    DVLOG(1) << "Adding frame: " << quic_frame;
    frames.push_back(quic_frame);
    offset += data_writes[i].length();
  }
  return MakeMultipleFramesPacket(header_, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRequestHeadersAndMultipleDataFramesPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id,
    quic::QuicStreamOffset* header_stream_offset,
    size_t* spdy_headers_frame_length,
    const std::vector<std::string>& data_writes) {
  InitializeHeader(packet_number, should_include_version);
  spdy::SpdySerializedFrame spdy_frame =
      MakeSpdyHeadersFrame(stream_id, fin && data_writes.empty(), priority,
                           std::move(headers), parent_stream_id);

  if (spdy_headers_frame_length) {
    *spdy_headers_frame_length = spdy_frame.size();
  }
  quic::QuicFrames frames;
  quic::QuicStreamOffset header_offset =
      header_stream_offset == nullptr ? 0 : *header_stream_offset;
  quic::QuicStreamFrame frame(
      quic::QuicUtils::GetHeadersStreamId(version_), false, header_offset,
      quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
  frames.push_back(quic::QuicFrame(frame));
  DVLOG(1) << "Adding frame: " << frames.back();
  if (header_stream_offset != nullptr) {
    *header_stream_offset += spdy_frame.size();
  }

  quic::QuicStreamOffset offset = 0;
  // quic::QuicFrame takes a raw pointer. Use a std::vector here so we keep
  // StreamFrames alive until MakeMultipleFramesPacket is done.
  std::vector<std::unique_ptr<quic::QuicStreamFrame>> stream_frames;
  for (size_t i = 0; i < data_writes.size(); ++i) {
    bool is_fin = fin && (i == data_writes.size() - 1);
    quic::QuicFrame quic_frame(quic::QuicStreamFrame(
        stream_id, is_fin, offset, quic::QuicStringPiece(data_writes[i])));
    DVLOG(1) << "Adding frame: " << quic_frame;
    frames.push_back(quic_frame);
    offset += data_writes[i].length();
  }
  return MakeMultipleFramesPacket(header_, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRequestHeadersPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id,
    size_t* spdy_headers_frame_length) {
  return MakeRequestHeadersPacket(
      packet_number, stream_id, should_include_version, fin, priority,
      std::move(headers), parent_stream_id, spdy_headers_frame_length, nullptr);
}

// If |offset| is provided, will use the value when creating the packet.
// Will also update the value after packet creation.
std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRequestHeadersPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id,
    size_t* spdy_headers_frame_length,
    quic::QuicStreamOffset* offset) {
  std::string unused_stream_data;
  return MakeRequestHeadersPacketAndSaveData(
      packet_number, stream_id, should_include_version, fin, priority,
      std::move(headers), parent_stream_id, spdy_headers_frame_length, offset,
      &unused_stream_data);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRequestHeadersPacketAndSaveData(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id,
    size_t* spdy_headers_frame_length,
    quic::QuicStreamOffset* offset,
    std::string* stream_data) {
  InitializeHeader(packet_number, should_include_version);
  spdy::SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
      stream_id, fin, priority, std::move(headers), parent_stream_id);
  *stream_data = std::string(spdy_frame.data(), spdy_frame.size());

  if (spdy_headers_frame_length)
    *spdy_headers_frame_length = spdy_frame.size();

  if (offset != nullptr) {
    quic::QuicStreamFrame frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, *offset,
        quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
    *offset += spdy_frame.size();
    return MakePacket(header_, quic::QuicFrame(frame));
  } else {
    quic::QuicStreamFrame frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, 0,
        quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));

    return MakePacket(header_, quic::QuicFrame(frame));
  }
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRequestHeadersAndRstPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id,
    size_t* spdy_headers_frame_length,
    quic::QuicStreamOffset* header_stream_offset,
    quic::QuicRstStreamErrorCode error_code,
    size_t bytes_written) {
  spdy::SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
      stream_id, fin, priority, std::move(headers), parent_stream_id);
  if (spdy_headers_frame_length) {
    *spdy_headers_frame_length = spdy_frame.size();
  }
  quic::QuicStreamOffset header_offset = 0;
  if (header_stream_offset != nullptr) {
    header_offset = *header_stream_offset;
    *header_stream_offset += spdy_frame.size();
  }
  quic::QuicStreamFrame headers_frame(
      quic::QuicUtils::GetHeadersStreamId(version_), false, header_offset,
      quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));

  quic::QuicRstStreamFrame rst_frame(1, stream_id, error_code, bytes_written);

  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(headers_frame));
  DVLOG(1) << "Adding frame: " << frames.back();
  frames.push_back(quic::QuicFrame(&rst_frame));
  DVLOG(1) << "Adding frame: " << frames.back();

  // The STOP_SENDING frame must be outside of the if (version==99) so that it
  // stays in scope until the packet is built.
  quic::QuicStopSendingFrame stop(1, stream_id, error_code);
  if (version_ == quic::QUIC_VERSION_99) {
    frames.push_back(quic::QuicFrame(&stop));
    DVLOG(1) << "Adding frame: " << frames.back();
  }

  InitializeHeader(packet_number, should_include_version);
  return MakeMultipleFramesPacket(header_, frames, nullptr);
}

spdy::SpdySerializedFrame QuicTestPacketMaker::MakeSpdyHeadersFrame(
    quic::QuicStreamId stream_id,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id) {
  spdy::SpdyHeadersIR headers_frame(stream_id, std::move(headers));
  headers_frame.set_fin(fin);
  headers_frame.set_weight(spdy::Spdy3PriorityToHttp2Weight(priority));
  headers_frame.set_has_priority(true);

  if (client_headers_include_h2_stream_dependency_) {
    headers_frame.set_parent_stream_id(parent_stream_id);
    headers_frame.set_exclusive(true);
  } else {
    headers_frame.set_parent_stream_id(0);
    headers_frame.set_exclusive(false);
  }

  return spdy_request_framer_.SerializeFrame(headers_frame);
}

// Convenience method for calling MakeRequestHeadersPacket with nullptr for
// |spdy_headers_frame_length|.
std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeRequestHeadersPacketWithOffsetTracking(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyPriority priority,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamId parent_stream_id,
    quic::QuicStreamOffset* offset) {
  return MakeRequestHeadersPacket(
      packet_number, stream_id, should_include_version, fin, priority,
      std::move(headers), parent_stream_id, nullptr, offset);
}

// If |offset| is provided, will use the value when creating the packet.
// Will also update the value after packet creation.
std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakePushPromisePacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    quic::QuicStreamId promised_stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyHeaderBlock headers,
    size_t* spdy_headers_frame_length,
    quic::QuicStreamOffset* offset) {
  InitializeHeader(packet_number, should_include_version);
  spdy::SpdySerializedFrame spdy_frame;
  spdy::SpdyPushPromiseIR promise_frame(stream_id, promised_stream_id,
                                        std::move(headers));
  promise_frame.set_fin(fin);
  spdy_frame = spdy_request_framer_.SerializeFrame(promise_frame);
  if (spdy_headers_frame_length) {
    *spdy_headers_frame_length = spdy_frame.size();
  }
  if (offset != nullptr) {
    quic::QuicStreamFrame frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, *offset,
        quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
    *offset += spdy_frame.size();
    return MakePacket(header_, quic::QuicFrame(frame));
  } else {
    quic::QuicStreamFrame frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, 0,
        quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
    return MakePacket(header_, quic::QuicFrame(frame));
  }
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeForceHolDataPacket(uint64_t packet_number,
                                            quic::QuicStreamId stream_id,
                                            bool should_include_version,
                                            bool fin,
                                            quic::QuicStreamOffset* offset,
                                            quic::QuicStringPiece data) {
  spdy::SpdyDataIR spdy_data(stream_id, data);
  spdy_data.set_fin(fin);
  spdy::SpdySerializedFrame spdy_frame(
      spdy_request_framer_.SerializeFrame(spdy_data));
  InitializeHeader(packet_number, should_include_version);
  quic::QuicStreamFrame quic_frame(
      quic::QuicUtils::GetHeadersStreamId(version_), false, *offset,
      quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
  *offset += spdy_frame.size();
  return MakePacket(header_, quic::QuicFrame(quic_frame));
}

// If |offset| is provided, will use the value when creating the packet.
// Will also update the value after packet creation.
std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeResponseHeadersPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyHeaderBlock headers,
    size_t* spdy_headers_frame_length,
    quic::QuicStreamOffset* offset) {
  InitializeHeader(packet_number, should_include_version);
  spdy::SpdySerializedFrame spdy_frame;
  spdy::SpdyHeadersIR headers_frame(stream_id, std::move(headers));
  headers_frame.set_fin(fin);
  spdy_frame = spdy_response_framer_.SerializeFrame(headers_frame);

  if (spdy_headers_frame_length) {
    *spdy_headers_frame_length = spdy_frame.size();
  }
  if (offset != nullptr) {
    quic::QuicStreamFrame frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, *offset,
        quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
    *offset += spdy_frame.size();
    return MakePacket(header_, quic::QuicFrame(frame));
  } else {
    quic::QuicStreamFrame frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, 0,
        quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
    return MakePacket(header_, quic::QuicFrame(frame));
  }
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeResponseHeadersPacket(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyHeaderBlock headers,
    size_t* spdy_headers_frame_length) {
  return MakeResponseHeadersPacket(
      packet_number, stream_id, should_include_version, fin, std::move(headers),
      spdy_headers_frame_length, nullptr);
}

// Convenience method for calling MakeResponseHeadersPacket with nullptr for
// |spdy_headers_frame_length|.
std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeResponseHeadersPacketWithOffsetTracking(
    uint64_t packet_number,
    quic::QuicStreamId stream_id,
    bool should_include_version,
    bool fin,
    spdy::SpdyHeaderBlock headers,
    quic::QuicStreamOffset* offset) {
  return MakeResponseHeadersPacket(packet_number, stream_id,
                                   should_include_version, fin,
                                   std::move(headers), nullptr, offset);
}

spdy::SpdyHeaderBlock QuicTestPacketMaker::GetRequestHeaders(
    const std::string& method,
    const std::string& scheme,
    const std::string& path) {
  spdy::SpdyHeaderBlock headers;
  headers[":method"] = method;
  headers[":authority"] = host_;
  headers[":scheme"] = scheme;
  headers[":path"] = path;
  return headers;
}

spdy::SpdyHeaderBlock QuicTestPacketMaker::ConnectRequestHeaders(
    const std::string& host_port) {
  spdy::SpdyHeaderBlock headers;
  headers[":method"] = "CONNECT";
  headers[":authority"] = host_port;
  return headers;
}

spdy::SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
    const std::string& status) {
  spdy::SpdyHeaderBlock headers;
  headers[":status"] = status;
  headers["content-type"] = "text/plain";
  return headers;
}

spdy::SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
    const std::string& status,
    const std::string& alt_svc) {
  spdy::SpdyHeaderBlock headers;
  headers[":status"] = status;
  headers["alt-svc"] = alt_svc;
  headers["content-type"] = "text/plain";
  return headers;
}

std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakePacket(
    const quic::QuicPacketHeader& header,
    const quic::QuicFrame& frame) {
  quic::QuicFrames frames;
  frames.push_back(frame);
  return MakeMultipleFramesPacket(header, frames, nullptr);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeMultipleFramesPacket(
    const quic::QuicPacketHeader& header,
    const quic::QuicFrames& frames,
    quic::QuicStreamFrameDataProducer* data_producer) {
  quic::QuicFramer framer(quic::test::SupportedVersions(quic::ParsedQuicVersion(
                              quic::PROTOCOL_QUIC_CRYPTO, version_)),
                          clock_->Now(), perspective_);
  if (data_producer != nullptr) {
    framer.set_data_producer(data_producer);
  }
  size_t max_plaintext_size =
      framer.GetMaxPlaintextSize(quic::kDefaultMaxPacketSize);
  std::unique_ptr<quic::QuicPacket> packet(quic::test::BuildUnsizedDataPacket(
      &framer, header, frames, max_plaintext_size));
  char buffer[quic::kMaxPacketSize];
  size_t encrypted_size =
      framer.EncryptPayload(quic::ENCRYPTION_NONE, header.packet_number,
                            *packet, buffer, quic::kMaxPacketSize);
  EXPECT_NE(0u, encrypted_size);
  quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
                                     false);
  return encrypted.Clone();
}

void QuicTestPacketMaker::InitializeHeader(uint64_t packet_number,
                                           bool should_include_version) {
  header_.destination_connection_id = connection_id_;
  header_.destination_connection_id_included = HasDestinationConnectionId();
  header_.source_connection_id = connection_id_;
  header_.source_connection_id_included = HasSourceConnectionId();
  header_.reset_flag = false;
  header_.version_flag = ShouldIncludeVersion(should_include_version);
  header_.long_packet_type = long_header_type_;
  header_.packet_number_length = GetPacketNumberLength();
  header_.packet_number = quic::QuicPacketNumber(packet_number);
  if (quic::QuicVersionHasLongHeaderLengths(version_) &&
      should_include_version) {
    if (long_header_type_ == quic::INITIAL) {
      header_.retry_token_length_length =
          quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
    }
    header_.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
  }
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeInitialSettingsPacket(uint64_t packet_number,
                                               quic::QuicStreamOffset* offset) {
  std::string unused_data;
  return MakeInitialSettingsPacketAndSaveData(packet_number, offset,
                                              &unused_data);
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeInitialSettingsPacketAndSaveData(
    uint64_t packet_number,
    quic::QuicStreamOffset* offset,
    std::string* stream_data) {
  spdy::SpdySettingsIR settings_frame;
  settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
                            quic::kDefaultMaxUncompressedHeaderSize);
  spdy::SpdySerializedFrame spdy_frame(
      spdy_request_framer_.SerializeFrame(settings_frame));
  InitializeHeader(packet_number, /*should_include_version*/ true);
  *stream_data = std::string(spdy_frame.data(), spdy_frame.size());
  if (offset != nullptr) {
    quic::QuicStreamFrame quic_frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, *offset,
        quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
    *offset += spdy_frame.size();
    return MakePacket(header_, quic::QuicFrame(quic_frame));
  }
  quic::QuicStreamFrame quic_frame(
      quic::QuicUtils::GetHeadersStreamId(version_), false, 0,
      quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
  return MakePacket(header_, quic::QuicFrame(quic_frame));
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakePriorityPacket(uint64_t packet_number,
                                        bool should_include_version,
                                        quic::QuicStreamId id,
                                        quic::QuicStreamId parent_stream_id,
                                        spdy::SpdyPriority priority,
                                        quic::QuicStreamOffset* offset) {
  if (!client_headers_include_h2_stream_dependency_) {
    parent_stream_id = 0;
  }
  int weight = spdy::Spdy3PriorityToHttp2Weight(priority);
  bool exclusive = client_headers_include_h2_stream_dependency_;
  spdy::SpdyPriorityIR priority_frame(id, parent_stream_id, weight, exclusive);
  spdy::SpdySerializedFrame spdy_frame(
      spdy_request_framer_.SerializeFrame(priority_frame));

  quic::QuicStreamOffset header_offset = 0;
  if (offset != nullptr) {
    header_offset = *offset;
    *offset += spdy_frame.size();
  }
  quic::QuicStreamFrame quic_frame(
      quic::QuicUtils::GetHeadersStreamId(version_), false, header_offset,
      quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
  DVLOG(1) << "Adding frame: " << quic::QuicFrame(quic_frame);
  InitializeHeader(packet_number, should_include_version);
  return MakePacket(header_, quic::QuicFrame(quic_frame));
}

std::unique_ptr<quic::QuicReceivedPacket>
QuicTestPacketMaker::MakeAckAndMultiplePriorityFramesPacket(
    uint64_t packet_number,
    bool should_include_version,
    uint64_t largest_received,
    uint64_t smallest_received,
    uint64_t least_unacked,
    const std::vector<Http2StreamDependency>& priority_frames,
    quic::QuicStreamOffset* offset) {
  quic::QuicAckFrame ack(MakeAckFrame(largest_received));
  ack.ack_delay_time = quic::QuicTime::Delta::Zero();
  for (uint64_t i = smallest_received; i <= largest_received; ++i) {
    ack.received_packet_times.push_back(
        std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
  }
  if (largest_received > 0) {
    ack.packets.AddRange(quic::QuicPacketNumber(1),
                         quic::QuicPacketNumber(largest_received + 1));
  }
  quic::QuicFrames frames;
  frames.push_back(quic::QuicFrame(&ack));
  DVLOG(1) << "Adding frame: " << frames.back();

  const bool exclusive = client_headers_include_h2_stream_dependency_;
  quic::QuicStreamOffset header_offset = 0;
  if (offset == nullptr) {
    offset = &header_offset;
  }
  // Keep SpdySerializedFrames alive until MakeMultipleFramesPacket is done.
  std::vector<std::unique_ptr<spdy::SpdySerializedFrame>> spdy_frames;
  for (const Http2StreamDependency& info : priority_frames) {
    spdy::SpdyPriorityIR priority_frame(
        info.stream_id, info.parent_stream_id,
        spdy::Spdy3PriorityToHttp2Weight(info.spdy_priority), exclusive);

    spdy_frames.push_back(std::make_unique<spdy::SpdySerializedFrame>(
        spdy_request_framer_.SerializeFrame(priority_frame)));

    spdy::SpdySerializedFrame* spdy_frame = spdy_frames.back().get();
    quic::QuicStreamFrame stream_frame(
        quic::QuicUtils::GetHeadersStreamId(version_), false, *offset,
        quic::QuicStringPiece(spdy_frame->data(), spdy_frame->size()));
    *offset += spdy_frame->size();

    frames.push_back(quic::QuicFrame(stream_frame));
    DVLOG(1) << "Adding frame: " << frames.back();
  }

  InitializeHeader(packet_number, should_include_version);
  return MakeMultipleFramesPacket(header_, frames, nullptr);
}

void QuicTestPacketMaker::SetEncryptionLevel(quic::EncryptionLevel level) {
  encryption_level_ = level;
    switch (level) {
      case quic::ENCRYPTION_NONE:
        long_header_type_ = quic::INITIAL;
        break;
      case quic::ENCRYPTION_ZERO_RTT:
        long_header_type_ = quic::ZERO_RTT_PROTECTED;
        break;
      case quic::ENCRYPTION_FORWARD_SECURE:
        long_header_type_ = quic::INVALID_PACKET_TYPE;
        break;
      default:
        QUIC_BUG << quic::QuicUtils::EncryptionLevelToString(level);
        long_header_type_ = quic::INVALID_PACKET_TYPE;
    }
}

bool QuicTestPacketMaker::ShouldIncludeVersion(bool include_version) const {
  if (version_ > quic::QUIC_VERSION_43) {
    return encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE;
  }
  return include_version;
}

quic::QuicPacketNumberLength QuicTestPacketMaker::GetPacketNumberLength()
    const {
  if (version_ > quic::QUIC_VERSION_43 &&
      encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE &&
      version_ != quic::QUIC_VERSION_99) {
    return quic::PACKET_4BYTE_PACKET_NUMBER;
  }
  return quic::PACKET_1BYTE_PACKET_NUMBER;
}

quic::QuicConnectionIdIncluded QuicTestPacketMaker::HasDestinationConnectionId()
    const {
  if (perspective_ == quic::Perspective::IS_SERVER &&
      version_ > quic::QUIC_VERSION_43) {
    return quic::CONNECTION_ID_ABSENT;
  }
  return quic::CONNECTION_ID_PRESENT;
}

quic::QuicConnectionIdIncluded QuicTestPacketMaker::HasSourceConnectionId()
    const {
  if (perspective_ == quic::Perspective::IS_SERVER &&
      version_ > quic::QUIC_VERSION_43 &&
      encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE) {
    return quic::CONNECTION_ID_PRESENT;
  }
  return quic::CONNECTION_ID_ABSENT;
}

}  // namespace test
}  // namespace net
