// 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/http2/test_tools/frame_parts.h"

#include <type_traits>

#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "net/third_party/quiche/src/http2/http2_structures_test_util.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_logging.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_string_utils.h"
#include "net/third_party/quiche/src/http2/platform/api/http2_test_helpers.h"

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

namespace http2 {
namespace test {
namespace {

static_assert(std::is_base_of<Http2FrameDecoderListener, FrameParts>::value &&
                  !std::is_abstract<FrameParts>::value,
              "FrameParts needs to implement all of the methods of "
              "Http2FrameDecoderListener");

// Compare two optional variables of the same type.
// TODO(jamessynge): Maybe create a ::testing::Matcher for this.
template <class T>
AssertionResult VerifyOptionalEq(const T& opt_a, const T& opt_b) {
  if (opt_a) {
    if (opt_b) {
      VERIFY_EQ(opt_a.value(), opt_b.value());
    } else {
      return AssertionFailure()
             << "opt_b is not set; opt_a.value()=" << opt_a.value();
    }
  } else if (opt_b) {
    return AssertionFailure()
           << "opt_a is not set; opt_b.value()=" << opt_b.value();
  }
  return AssertionSuccess();
}

}  // namespace

FrameParts::FrameParts(const Http2FrameHeader& header) : frame_header_(header) {
  HTTP2_VLOG(1) << "FrameParts, header: " << frame_header_;
}

FrameParts::FrameParts(const Http2FrameHeader& header, Http2StringPiece payload)
    : FrameParts(header) {
  HTTP2_VLOG(1) << "FrameParts with payload.size() = " << payload.size();
  this->payload_.append(payload.data(), payload.size());
  opt_payload_length_ = payload.size();
}
FrameParts::FrameParts(const Http2FrameHeader& header,
                       Http2StringPiece payload,
                       size_t total_pad_length)
    : FrameParts(header, payload) {
  HTTP2_VLOG(1) << "FrameParts with total_pad_length=" << total_pad_length;
  SetTotalPadLength(total_pad_length);
}

FrameParts::FrameParts(const FrameParts& header) = default;

FrameParts::~FrameParts() = default;

AssertionResult FrameParts::VerifyEquals(const FrameParts& that) const {
#define COMMON_MESSAGE "\n  this: " << *this << "\n  that: " << that

  VERIFY_EQ(frame_header_, that.frame_header_) << COMMON_MESSAGE;
  VERIFY_EQ(payload_, that.payload_) << COMMON_MESSAGE;
  VERIFY_EQ(padding_, that.padding_) << COMMON_MESSAGE;
  VERIFY_EQ(altsvc_origin_, that.altsvc_origin_) << COMMON_MESSAGE;
  VERIFY_EQ(altsvc_value_, that.altsvc_value_) << COMMON_MESSAGE;
  VERIFY_THAT(settings_, ContainerEq(that.settings_)) << COMMON_MESSAGE;

#define VERIFY_OPTIONAL_FIELD(field_name) \
  VERIFY_SUCCESS(VerifyOptionalEq(field_name, that.field_name))

  VERIFY_OPTIONAL_FIELD(opt_altsvc_origin_length_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_altsvc_value_length_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_goaway_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_missing_length_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_pad_length_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_ping_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_priority_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_push_promise_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_rst_stream_error_code_) << COMMON_MESSAGE;
  VERIFY_OPTIONAL_FIELD(opt_window_update_increment_) << COMMON_MESSAGE;

#undef VERIFY_OPTIONAL_FIELD

  return AssertionSuccess();
}

void FrameParts::SetTotalPadLength(size_t total_pad_length) {
  opt_pad_length_.reset();
  padding_.clear();
  if (total_pad_length > 0) {
    ASSERT_LE(total_pad_length, 256u);
    ASSERT_TRUE(frame_header_.IsPadded());
    opt_pad_length_ = total_pad_length - 1;
    char zero = 0;
    padding_.append(opt_pad_length_.value(), zero);
  }

  if (opt_pad_length_) {
    HTTP2_VLOG(1) << "SetTotalPadLength: pad_length="
                  << opt_pad_length_.value();
  } else {
    HTTP2_VLOG(1) << "SetTotalPadLength: has no pad length";
  }
}

void FrameParts::SetAltSvcExpected(Http2StringPiece origin,
                                   Http2StringPiece value) {
  altsvc_origin_.append(origin.data(), origin.size());
  altsvc_value_.append(value.data(), value.size());
  opt_altsvc_origin_length_ = origin.size();
  opt_altsvc_value_length_ = value.size();
}

bool FrameParts::OnFrameHeader(const Http2FrameHeader& header) {
  ADD_FAILURE() << "OnFrameHeader: " << *this;
  return true;
}

void FrameParts::OnDataStart(const Http2FrameHeader& header) {
  HTTP2_VLOG(1) << "OnDataStart: " << header;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::DATA)) << *this;
  opt_payload_length_ = header.payload_length;
}

void FrameParts::OnDataPayload(const char* data, size_t len) {
  HTTP2_VLOG(1) << "OnDataPayload: len=" << len
                << "; frame_header_: " << frame_header_;
  ASSERT_TRUE(InFrameOfType(Http2FrameType::DATA)) << *this;
  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
                           &opt_payload_length_));
}

void FrameParts::OnDataEnd() {
  HTTP2_VLOG(1) << "OnDataEnd; frame_header_: " << frame_header_;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::DATA)) << *this;
}

void FrameParts::OnHeadersStart(const Http2FrameHeader& header) {
  HTTP2_VLOG(1) << "OnHeadersStart: " << header;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::HEADERS)) << *this;
  opt_payload_length_ = header.payload_length;
}

void FrameParts::OnHeadersPriority(const Http2PriorityFields& priority) {
  HTTP2_VLOG(1) << "OnHeadersPriority: priority: " << priority
                << "; frame_header_: " << frame_header_;
  ASSERT_TRUE(InFrameOfType(Http2FrameType::HEADERS)) << *this;
  ASSERT_FALSE(opt_priority_);
  opt_priority_ = priority;
  ASSERT_TRUE(opt_payload_length_);
  opt_payload_length_ =
      opt_payload_length_.value() - Http2PriorityFields::EncodedSize();
}

void FrameParts::OnHpackFragment(const char* data, size_t len) {
  HTTP2_VLOG(1) << "OnHpackFragment: len=" << len
                << "; frame_header_: " << frame_header_;
  ASSERT_TRUE(got_start_callback_);
  ASSERT_FALSE(got_end_callback_);
  ASSERT_TRUE(FrameCanHaveHpackPayload(frame_header_)) << *this;
  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
                           &opt_payload_length_));
}

void FrameParts::OnHeadersEnd() {
  HTTP2_VLOG(1) << "OnHeadersEnd; frame_header_: " << frame_header_;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::HEADERS)) << *this;
}

void FrameParts::OnPriorityFrame(const Http2FrameHeader& header,
                                 const Http2PriorityFields& priority) {
  HTTP2_VLOG(1) << "OnPriorityFrame: " << header << "; priority: " << priority;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PRIORITY)) << *this;
  ASSERT_FALSE(opt_priority_);
  opt_priority_ = priority;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PRIORITY)) << *this;
}

void FrameParts::OnContinuationStart(const Http2FrameHeader& header) {
  HTTP2_VLOG(1) << "OnContinuationStart: " << header;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::CONTINUATION)) << *this;
  opt_payload_length_ = header.payload_length;
}

void FrameParts::OnContinuationEnd() {
  HTTP2_VLOG(1) << "OnContinuationEnd; frame_header_: " << frame_header_;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::CONTINUATION)) << *this;
}

void FrameParts::OnPadLength(size_t trailing_length) {
  HTTP2_VLOG(1) << "OnPadLength: trailing_length=" << trailing_length;
  ASSERT_TRUE(InPaddedFrame()) << *this;
  ASSERT_FALSE(opt_pad_length_);
  ASSERT_TRUE(opt_payload_length_);
  size_t total_padding_length = trailing_length + 1;
  ASSERT_GE(opt_payload_length_.value(), total_padding_length);
  opt_payload_length_ = opt_payload_length_.value() - total_padding_length;
  opt_pad_length_ = trailing_length;
}

void FrameParts::OnPadding(const char* pad, size_t skipped_length) {
  HTTP2_VLOG(1) << "OnPadding: skipped_length=" << skipped_length;
  ASSERT_TRUE(InPaddedFrame()) << *this;
  ASSERT_TRUE(opt_pad_length_);
  ASSERT_TRUE(AppendString(Http2StringPiece(pad, skipped_length), &padding_,
                           &opt_pad_length_));
}

void FrameParts::OnRstStream(const Http2FrameHeader& header,
                             Http2ErrorCode error_code) {
  HTTP2_VLOG(1) << "OnRstStream: " << header << "; code=" << error_code;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::RST_STREAM)) << *this;
  ASSERT_FALSE(opt_rst_stream_error_code_);
  opt_rst_stream_error_code_ = error_code;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::RST_STREAM)) << *this;
}

void FrameParts::OnSettingsStart(const Http2FrameHeader& header) {
  HTTP2_VLOG(1) << "OnSettingsStart: " << header;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
  ASSERT_EQ(0u, settings_.size());
  ASSERT_FALSE(header.IsAck()) << header;
}

void FrameParts::OnSetting(const Http2SettingFields& setting_fields) {
  HTTP2_VLOG(1) << "OnSetting: " << setting_fields;
  ASSERT_TRUE(InFrameOfType(Http2FrameType::SETTINGS)) << *this;
  settings_.push_back(setting_fields);
}

void FrameParts::OnSettingsEnd() {
  HTTP2_VLOG(1) << "OnSettingsEnd; frame_header_: " << frame_header_;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
}

void FrameParts::OnSettingsAck(const Http2FrameHeader& header) {
  HTTP2_VLOG(1) << "OnSettingsAck: " << header;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::SETTINGS)) << *this;
  ASSERT_EQ(0u, settings_.size());
  ASSERT_TRUE(header.IsAck());
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::SETTINGS)) << *this;
}

void FrameParts::OnPushPromiseStart(const Http2FrameHeader& header,
                                    const Http2PushPromiseFields& promise,
                                    size_t total_padding_length) {
  HTTP2_VLOG(1) << "OnPushPromiseStart header: " << header
                << "; promise: " << promise
                << "; total_padding_length: " << total_padding_length;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PUSH_PROMISE)) << *this;
  ASSERT_GE(header.payload_length, Http2PushPromiseFields::EncodedSize());
  opt_payload_length_ =
      header.payload_length - Http2PushPromiseFields::EncodedSize();
  ASSERT_FALSE(opt_push_promise_);
  opt_push_promise_ = promise;
  if (total_padding_length > 0) {
    ASSERT_GE(opt_payload_length_.value(), total_padding_length);
    OnPadLength(total_padding_length - 1);
  } else {
    ASSERT_FALSE(header.IsPadded());
  }
}

void FrameParts::OnPushPromiseEnd() {
  HTTP2_VLOG(1) << "OnPushPromiseEnd; frame_header_: " << frame_header_;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PUSH_PROMISE)) << *this;
}

void FrameParts::OnPing(const Http2FrameHeader& header,
                        const Http2PingFields& ping) {
  HTTP2_VLOG(1) << "OnPing header: " << header << "   ping: " << ping;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
  ASSERT_FALSE(header.IsAck());
  ASSERT_FALSE(opt_ping_);
  opt_ping_ = ping;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
}

void FrameParts::OnPingAck(const Http2FrameHeader& header,
                           const Http2PingFields& ping) {
  HTTP2_VLOG(1) << "OnPingAck header: " << header << "   ping: " << ping;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::PING)) << *this;
  ASSERT_TRUE(header.IsAck());
  ASSERT_FALSE(opt_ping_);
  opt_ping_ = ping;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::PING)) << *this;
}

void FrameParts::OnGoAwayStart(const Http2FrameHeader& header,
                               const Http2GoAwayFields& goaway) {
  HTTP2_VLOG(1) << "OnGoAwayStart: " << goaway;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::GOAWAY)) << *this;
  ASSERT_FALSE(opt_goaway_);
  opt_goaway_ = goaway;
  opt_payload_length_ =
      header.payload_length - Http2GoAwayFields::EncodedSize();
}

void FrameParts::OnGoAwayOpaqueData(const char* data, size_t len) {
  HTTP2_VLOG(1) << "OnGoAwayOpaqueData: len=" << len;
  ASSERT_TRUE(InFrameOfType(Http2FrameType::GOAWAY)) << *this;
  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
                           &opt_payload_length_));
}

void FrameParts::OnGoAwayEnd() {
  HTTP2_VLOG(1) << "OnGoAwayEnd; frame_header_: " << frame_header_;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::GOAWAY)) << *this;
}

void FrameParts::OnWindowUpdate(const Http2FrameHeader& header,
                                uint32_t increment) {
  HTTP2_VLOG(1) << "OnWindowUpdate header: " << header
                << "     increment=" << increment;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::WINDOW_UPDATE)) << *this;
  ASSERT_FALSE(opt_window_update_increment_);
  opt_window_update_increment_ = increment;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::WINDOW_UPDATE)) << *this;
}

void FrameParts::OnAltSvcStart(const Http2FrameHeader& header,
                               size_t origin_length,
                               size_t value_length) {
  HTTP2_VLOG(1) << "OnAltSvcStart: " << header
                << "    origin_length: " << origin_length
                << "    value_length: " << value_length;
  ASSERT_TRUE(StartFrameOfType(header, Http2FrameType::ALTSVC)) << *this;
  ASSERT_FALSE(opt_altsvc_origin_length_);
  opt_altsvc_origin_length_ = origin_length;
  ASSERT_FALSE(opt_altsvc_value_length_);
  opt_altsvc_value_length_ = value_length;
}

void FrameParts::OnAltSvcOriginData(const char* data, size_t len) {
  HTTP2_VLOG(1) << "OnAltSvcOriginData: len=" << len;
  ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_origin_,
                           &opt_altsvc_origin_length_));
}

void FrameParts::OnAltSvcValueData(const char* data, size_t len) {
  HTTP2_VLOG(1) << "OnAltSvcValueData: len=" << len;
  ASSERT_TRUE(InFrameOfType(Http2FrameType::ALTSVC)) << *this;
  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &altsvc_value_,
                           &opt_altsvc_value_length_));
}

void FrameParts::OnAltSvcEnd() {
  HTTP2_VLOG(1) << "OnAltSvcEnd; frame_header_: " << frame_header_;
  ASSERT_TRUE(EndFrameOfType(Http2FrameType::ALTSVC)) << *this;
}

void FrameParts::OnUnknownStart(const Http2FrameHeader& header) {
  HTTP2_VLOG(1) << "OnUnknownStart: " << header;
  ASSERT_FALSE(IsSupportedHttp2FrameType(header.type)) << header;
  ASSERT_FALSE(got_start_callback_);
  ASSERT_EQ(frame_header_, header);
  got_start_callback_ = true;
  opt_payload_length_ = header.payload_length;
}

void FrameParts::OnUnknownPayload(const char* data, size_t len) {
  HTTP2_VLOG(1) << "OnUnknownPayload: len=" << len;
  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
  ASSERT_TRUE(got_start_callback_);
  ASSERT_FALSE(got_end_callback_);
  ASSERT_TRUE(AppendString(Http2StringPiece(data, len), &payload_,
                           &opt_payload_length_));
}

void FrameParts::OnUnknownEnd() {
  HTTP2_VLOG(1) << "OnUnknownEnd; frame_header_: " << frame_header_;
  ASSERT_FALSE(IsSupportedHttp2FrameType(frame_header_.type)) << *this;
  ASSERT_TRUE(got_start_callback_);
  ASSERT_FALSE(got_end_callback_);
  got_end_callback_ = true;
}

void FrameParts::OnPaddingTooLong(const Http2FrameHeader& header,
                                  size_t missing_length) {
  HTTP2_VLOG(1) << "OnPaddingTooLong: " << header
                << "; missing_length: " << missing_length;
  ASSERT_EQ(frame_header_, header);
  ASSERT_FALSE(got_end_callback_);
  ASSERT_TRUE(FrameIsPadded(header));
  ASSERT_FALSE(opt_pad_length_);
  ASSERT_FALSE(opt_missing_length_);
  opt_missing_length_ = missing_length;
  got_start_callback_ = true;
  got_end_callback_ = true;
}

void FrameParts::OnFrameSizeError(const Http2FrameHeader& header) {
  HTTP2_VLOG(1) << "OnFrameSizeError: " << header;
  ASSERT_EQ(frame_header_, header);
  ASSERT_FALSE(got_end_callback_);
  ASSERT_FALSE(has_frame_size_error_);
  has_frame_size_error_ = true;
  got_end_callback_ = true;
}

void FrameParts::OutputTo(std::ostream& out) const {
  out << "FrameParts{\n  frame_header_: " << frame_header_ << "\n";
  if (!payload_.empty()) {
    out << "  payload_=\"" << Http2HexEscape(payload_) << "\"\n";
  }
  if (!padding_.empty()) {
    out << "  padding_=\"" << Http2HexEscape(padding_) << "\"\n";
  }
  if (!altsvc_origin_.empty()) {
    out << "  altsvc_origin_=\"" << Http2HexEscape(altsvc_origin_) << "\"\n";
  }
  if (!altsvc_value_.empty()) {
    out << "  altsvc_value_=\"" << Http2HexEscape(altsvc_value_) << "\"\n";
  }
  if (opt_priority_) {
    out << "  priority=" << opt_priority_.value() << "\n";
  }
  if (opt_rst_stream_error_code_) {
    out << "  rst_stream=" << opt_rst_stream_error_code_.value() << "\n";
  }
  if (opt_push_promise_) {
    out << "  push_promise=" << opt_push_promise_.value() << "\n";
  }
  if (opt_ping_) {
    out << "  ping=" << opt_ping_.value() << "\n";
  }
  if (opt_goaway_) {
    out << "  goaway=" << opt_goaway_.value() << "\n";
  }
  if (opt_window_update_increment_) {
    out << "  window_update=" << opt_window_update_increment_.value() << "\n";
  }
  if (opt_payload_length_) {
    out << "  payload_length=" << opt_payload_length_.value() << "\n";
  }
  if (opt_pad_length_) {
    out << "  pad_length=" << opt_pad_length_.value() << "\n";
  }
  if (opt_missing_length_) {
    out << "  missing_length=" << opt_missing_length_.value() << "\n";
  }
  if (opt_altsvc_origin_length_) {
    out << "  origin_length=" << opt_altsvc_origin_length_.value() << "\n";
  }
  if (opt_altsvc_value_length_) {
    out << "  value_length=" << opt_altsvc_value_length_.value() << "\n";
  }
  if (has_frame_size_error_) {
    out << "  has_frame_size_error\n";
  }
  if (got_start_callback_) {
    out << "  got_start_callback\n";
  }
  if (got_end_callback_) {
    out << "  got_end_callback\n";
  }
  for (size_t ndx = 0; ndx < settings_.size(); ++ndx) {
    out << "  setting[" << ndx << "]=" << settings_[ndx];
  }
  out << "}";
}

AssertionResult FrameParts::StartFrameOfType(
    const Http2FrameHeader& header,
    Http2FrameType expected_frame_type) {
  VERIFY_EQ(header.type, expected_frame_type);
  VERIFY_FALSE(got_start_callback_);
  VERIFY_FALSE(got_end_callback_);
  VERIFY_EQ(frame_header_, header);
  got_start_callback_ = true;
  return AssertionSuccess();
}

AssertionResult FrameParts::InFrameOfType(Http2FrameType expected_frame_type) {
  VERIFY_TRUE(got_start_callback_);
  VERIFY_FALSE(got_end_callback_);
  VERIFY_EQ(frame_header_.type, expected_frame_type);
  return AssertionSuccess();
}

AssertionResult FrameParts::EndFrameOfType(Http2FrameType expected_frame_type) {
  VERIFY_SUCCESS(InFrameOfType(expected_frame_type));
  got_end_callback_ = true;
  return AssertionSuccess();
}

AssertionResult FrameParts::InPaddedFrame() {
  VERIFY_TRUE(got_start_callback_);
  VERIFY_FALSE(got_end_callback_);
  VERIFY_TRUE(FrameIsPadded(frame_header_));
  return AssertionSuccess();
}

AssertionResult FrameParts::AppendString(Http2StringPiece source,
                                         Http2String* target,
                                         Http2Optional<size_t>* opt_length) {
  target->append(source.data(), source.size());
  if (opt_length != nullptr) {
    VERIFY_TRUE(*opt_length) << "Length is not set yet\n" << *this;
    VERIFY_LE(target->size(), opt_length->value())
        << "String too large; source.size() = " << source.size() << "\n"
        << *this;
  }
  return ::testing::AssertionSuccess();
}

std::ostream& operator<<(std::ostream& out, const FrameParts& v) {
  v.OutputTo(out);
  return out;
}

}  // namespace test
}  // namespace http2
