// 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_protocol_test_utils.h"

#include <cstdint>

#include "net/third_party/quiche/src/spdy/platform/api/spdy_string_piece.h"

namespace spdy {
namespace test {

// TODO(jamessynge): Where it makes sense in these functions, it would be nice
// to make use of the existing gMock matchers here, instead of rolling our own.

::testing::AssertionResult VerifySpdyFrameWithHeaderBlockIREquals(
    const SpdyFrameWithHeaderBlockIR& expected,
    const SpdyFrameWithHeaderBlockIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameWithHeaderBlockIREquals";
  VERIFY_TRUE(actual.header_block() == expected.header_block());
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyAltSvcIR& expected,
                                                   const SpdyAltSvcIR& actual) {
  VERIFY_EQ(expected.stream_id(), actual.stream_id());
  VERIFY_EQ(expected.origin(), actual.origin());
  VERIFY_THAT(actual.altsvc_vector(),
              ::testing::ContainerEq(expected.altsvc_vector()));
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(
    const SpdyContinuationIR& /*expected*/,
    const SpdyContinuationIR& /*actual*/) {
  return ::testing::AssertionFailure()
         << "VerifySpdyFrameIREquals SpdyContinuationIR not yet implemented";
}

::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyDataIR& expected,
                                                   const SpdyDataIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyDataIR";
  VERIFY_EQ(expected.stream_id(), actual.stream_id());
  VERIFY_EQ(expected.fin(), actual.fin());
  VERIFY_EQ(expected.data_len(), actual.data_len());
  if (expected.data() == nullptr) {
    VERIFY_EQ(nullptr, actual.data());
  } else {
    VERIFY_EQ(SpdyStringPiece(expected.data(), expected.data_len()),
              SpdyStringPiece(actual.data(), actual.data_len()));
  }
  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyGoAwayIR& expected,
                                                   const SpdyGoAwayIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyGoAwayIR";
  VERIFY_EQ(expected.last_good_stream_id(), actual.last_good_stream_id());
  VERIFY_EQ(expected.error_code(), actual.error_code());
  VERIFY_EQ(expected.description(), actual.description());
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(
    const SpdyHeadersIR& expected,
    const SpdyHeadersIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyHeadersIR";
  VERIFY_EQ(expected.stream_id(), actual.stream_id());
  VERIFY_EQ(expected.fin(), actual.fin());
  VERIFY_SUCCESS(VerifySpdyFrameWithHeaderBlockIREquals(expected, actual));
  VERIFY_EQ(expected.has_priority(), actual.has_priority());
  if (expected.has_priority()) {
    VERIFY_SUCCESS(VerifySpdyFrameWithPriorityIREquals(expected, actual));
  }
  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(const SpdyPingIR& expected,
                                                   const SpdyPingIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyPingIR";
  VERIFY_EQ(expected.id(), actual.id());
  VERIFY_EQ(expected.is_ack(), actual.is_ack());
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(
    const SpdyPriorityIR& expected,
    const SpdyPriorityIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyPriorityIR";
  VERIFY_EQ(expected.stream_id(), actual.stream_id());
  VERIFY_SUCCESS(VerifySpdyFrameWithPriorityIREquals(expected, actual));
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(
    const SpdyPushPromiseIR& expected,
    const SpdyPushPromiseIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyPushPromiseIR";
  VERIFY_EQ(expected.stream_id(), actual.stream_id());
  VERIFY_SUCCESS(VerifySpdyFrameWithPaddingIREquals(expected, actual));
  VERIFY_EQ(expected.promised_stream_id(), actual.promised_stream_id());
  VERIFY_SUCCESS(VerifySpdyFrameWithHeaderBlockIREquals(expected, actual));
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(
    const SpdyRstStreamIR& expected,
    const SpdyRstStreamIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyRstStreamIR";
  VERIFY_EQ(expected.stream_id(), actual.stream_id());
  VERIFY_EQ(expected.error_code(), actual.error_code());
  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(
    const SpdySettingsIR& expected,
    const SpdySettingsIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdySettingsIR";
  // Note, ignoring non-HTTP/2 fields such as clear_settings.
  VERIFY_EQ(expected.is_ack(), actual.is_ack());

  // Note, the following doesn't work because there isn't a comparator and
  // formatter for SpdySettingsIR::Value. Fixable if we cared.
  //
  //   VERIFY_THAT(actual.values(), ::testing::ContainerEq(actual.values()));

  VERIFY_EQ(expected.values().size(), actual.values().size());
  for (const auto& entry : expected.values()) {
    const auto& param = entry.first;
    auto actual_itr = actual.values().find(param);
    VERIFY_TRUE(!(actual_itr == actual.values().end()))
        << "actual doesn't contain param: " << param;
    uint32_t expected_value = entry.second;
    uint32_t actual_value = actual_itr->second;
    VERIFY_EQ(expected_value, actual_value)
        << "Values don't match for parameter: " << param;
  }

  return ::testing::AssertionSuccess();
}

::testing::AssertionResult VerifySpdyFrameIREquals(
    const SpdyWindowUpdateIR& expected,
    const SpdyWindowUpdateIR& actual) {
  SPDY_VLOG(1) << "VerifySpdyFrameIREquals SpdyWindowUpdateIR";
  VERIFY_EQ(expected.stream_id(), actual.stream_id());
  VERIFY_EQ(expected.delta(), actual.delta());
  return ::testing::AssertionSuccess();
}

}  // namespace test
}  // namespace spdy
