/*
 *  Copyright 2016 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <stdint.h>

#include <memory>
#include <optional>
#include <set>
#include <string>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/audio_options.h"
#include "api/data_channel_interface.h"
#include "api/make_ref_counted.h"
#include "api/peer_connection_interface.h"
#include "api/rtp_receiver_interface.h"
#include "api/rtp_sender_interface.h"
#include "api/scoped_refptr.h"
#include "api/stats/attribute.h"
#include "api/stats/rtc_stats.h"
#include "api/stats/rtc_stats_report.h"
#include "api/stats/rtcstats_objects.h"
#include "api/test/rtc_error_matchers.h"
#include "api/units/time_delta.h"
#include "pc/rtc_stats_traversal.h"
#include "pc/test/peer_connection_test_wrapper.h"
#include "pc/test/rtc_stats_obtainer.h"
#include "rtc_base/checks.h"
#include "rtc_base/thread.h"
#include "rtc_base/trace_event.h"
#include "rtc_base/virtual_socket_server.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/wait_until.h"

using ::testing::Contains;

namespace webrtc {

namespace {

const int64_t kGetStatsTimeoutMs = 10000;

class RTCStatsIntegrationTest : public ::testing::Test {
 public:
  RTCStatsIntegrationTest()
      : network_thread_(new rtc::Thread(&virtual_socket_server_)),
        worker_thread_(rtc::Thread::Create()) {
    RTC_CHECK(network_thread_->Start());
    RTC_CHECK(worker_thread_->Start());

    caller_ = rtc::make_ref_counted<PeerConnectionTestWrapper>(
        "caller", &virtual_socket_server_, network_thread_.get(),
        worker_thread_.get());
    callee_ = rtc::make_ref_counted<PeerConnectionTestWrapper>(
        "callee", &virtual_socket_server_, network_thread_.get(),
        worker_thread_.get());
  }

  void StartCall() {
    // Create PeerConnections and "connect" sigslots
    PeerConnectionInterface::RTCConfiguration config;
    config.sdp_semantics = SdpSemantics::kUnifiedPlan;
    PeerConnectionInterface::IceServer ice_server;
    ice_server.uri = "stun:1.1.1.1:3478";
    config.servers.push_back(ice_server);
    EXPECT_TRUE(caller_->CreatePc(config, CreateBuiltinAudioEncoderFactory(),
                                  CreateBuiltinAudioDecoderFactory()));
    EXPECT_TRUE(callee_->CreatePc(config, CreateBuiltinAudioEncoderFactory(),
                                  CreateBuiltinAudioDecoderFactory()));
    PeerConnectionTestWrapper::Connect(caller_.get(), callee_.get());

    // Get user media for audio and video
    caller_->GetAndAddUserMedia(true, cricket::AudioOptions(), true);
    callee_->GetAndAddUserMedia(true, cricket::AudioOptions(), true);

    // Create data channels
    DataChannelInit init;
    caller_->CreateDataChannel("data", init);
    callee_->CreateDataChannel("data", init);

    // Negotiate and wait for call to establish
    caller_->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions());
    caller_->WaitForCallEstablished();
    callee_->WaitForCallEstablished();
  }

  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCaller() {
    return GetStats(caller_->pc());
  }
  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCaller(
      rtc::scoped_refptr<RtpSenderInterface> selector) {
    return GetStats(caller_->pc(), selector);
  }
  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCaller(
      rtc::scoped_refptr<RtpReceiverInterface> selector) {
    return GetStats(caller_->pc(), selector);
  }

  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCallee() {
    return GetStats(callee_->pc());
  }
  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCallee(
      rtc::scoped_refptr<RtpSenderInterface> selector) {
    return GetStats(callee_->pc(), selector);
  }
  rtc::scoped_refptr<const RTCStatsReport> GetStatsFromCallee(
      rtc::scoped_refptr<RtpReceiverInterface> selector) {
    return GetStats(callee_->pc(), selector);
  }

 protected:
  static rtc::scoped_refptr<const RTCStatsReport> GetStats(
      PeerConnectionInterface* pc) {
    rtc::scoped_refptr<RTCStatsObtainer> stats_obtainer =
        RTCStatsObtainer::Create();
    pc->GetStats(stats_obtainer.get());
    EXPECT_THAT(
        WaitUntil([&] { return stats_obtainer->report() != nullptr; },
                  ::testing::IsTrue(),
                  {.timeout = webrtc::TimeDelta::Millis(kGetStatsTimeoutMs)}),
        IsRtcOk());
    return stats_obtainer->report();
  }

  template <typename T>
  static rtc::scoped_refptr<const RTCStatsReport> GetStats(
      PeerConnectionInterface* pc,
      rtc::scoped_refptr<T> selector) {
    rtc::scoped_refptr<RTCStatsObtainer> stats_obtainer =
        RTCStatsObtainer::Create();
    pc->GetStats(selector, stats_obtainer);
    EXPECT_THAT(
        WaitUntil([&] { return stats_obtainer->report() != nullptr; },
                  ::testing::IsTrue(),
                  {.timeout = webrtc::TimeDelta::Millis(kGetStatsTimeoutMs)}),
        IsRtcOk());
    return stats_obtainer->report();
  }

  // `network_thread_` uses `virtual_socket_server_` so they must be
  // constructed/destructed in the correct order.
  rtc::VirtualSocketServer virtual_socket_server_;
  std::unique_ptr<rtc::Thread> network_thread_;
  std::unique_ptr<rtc::Thread> worker_thread_;
  rtc::scoped_refptr<PeerConnectionTestWrapper> caller_;
  rtc::scoped_refptr<PeerConnectionTestWrapper> callee_;
};

class RTCStatsVerifier {
 public:
  RTCStatsVerifier(const RTCStatsReport* report, const RTCStats* stats)
      : report_(report), stats_(stats), all_tests_successful_(true) {
    RTC_CHECK(report_);
    RTC_CHECK(stats_);
    for (const auto& attribute : stats_->Attributes()) {
      untested_attribute_names_.insert(attribute.name());
    }
  }

  template <typename T>
  void MarkAttributeTested(const std::optional<T>& field,
                           bool test_successful) {
    untested_attribute_names_.erase(stats_->GetAttribute(field).name());
    all_tests_successful_ &= test_successful;
  }

  template <typename T>
  void TestAttributeIsDefined(const std::optional<T>& field) {
    EXPECT_TRUE(field.has_value())
        << stats_->type() << "." << stats_->GetAttribute(field).name() << "["
        << stats_->id() << "] was undefined.";
    MarkAttributeTested(field, field.has_value());
  }

  template <typename T>
  void TestAttributeIsUndefined(const std::optional<T>& field) {
    Attribute attribute = stats_->GetAttribute(field);
    EXPECT_FALSE(field.has_value())
        << stats_->type() << "." << attribute.name() << "[" << stats_->id()
        << "] was defined (" << attribute.ToString() << ").";
    MarkAttributeTested(field, !field.has_value());
  }

  template <typename T>
  void TestAttributeIsPositive(const std::optional<T>& field) {
    Attribute attribute = stats_->GetAttribute(field);
    EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name()
                                   << "[" << stats_->id() << "] was undefined.";
    if (!field.has_value()) {
      MarkAttributeTested(field, false);
      return;
    }
    bool is_positive = field.value() > T(0);
    EXPECT_TRUE(is_positive)
        << stats_->type() << "." << attribute.name() << "[" << stats_->id()
        << "] was not positive (" << attribute.ToString() << ").";
    MarkAttributeTested(field, is_positive);
  }

  template <typename T>
  void TestAttributeIsNonNegative(const std::optional<T>& field) {
    Attribute attribute = stats_->GetAttribute(field);
    EXPECT_TRUE(field.has_value()) << stats_->type() << "." << attribute.name()
                                   << "[" << stats_->id() << "] was undefined.";
    if (!field.has_value()) {
      MarkAttributeTested(field, false);
      return;
    }
    bool is_non_negative = field.value() >= T(0);
    EXPECT_TRUE(is_non_negative)
        << stats_->type() << "." << attribute.name() << "[" << stats_->id()
        << "] was not non-negative (" << attribute.ToString() << ").";
    MarkAttributeTested(field, is_non_negative);
  }

  template <typename T>
  void TestAttributeIsIDReference(const std::optional<T>& field,
                                  const char* expected_type) {
    TestAttributeIsIDReference(field, expected_type, false);
  }

  template <typename T>
  void TestAttributeIsOptionalIDReference(const std::optional<T>& field,
                                          const char* expected_type) {
    TestAttributeIsIDReference(field, expected_type, true);
  }

  bool ExpectAllAttributesSuccessfullyTested() {
    if (untested_attribute_names_.empty())
      return all_tests_successful_;
    for (const char* name : untested_attribute_names_) {
      EXPECT_TRUE(false) << stats_->type() << "." << name << "[" << stats_->id()
                         << "] was not tested.";
    }
    return false;
  }

 private:
  template <typename T>
  void TestAttributeIsIDReference(const std::optional<T>& field,
                                  const char* expected_type,
                                  bool optional) {
    if (optional && !field.has_value()) {
      MarkAttributeTested(field, true);
      return;
    }
    Attribute attribute = stats_->GetAttribute(field);
    bool valid_reference = false;
    if (attribute.has_value()) {
      if (attribute.holds_alternative<std::string>()) {
        // A single ID.
        const RTCStats* referenced_stats =
            report_->Get(attribute.get<std::string>());
        valid_reference =
            referenced_stats && referenced_stats->type() == expected_type;
      } else if (attribute.holds_alternative<std::vector<std::string>>()) {
        // A vector of IDs.
        valid_reference = true;
        for (const std::string& id :
             attribute.get<std::vector<std::string>>()) {
          const RTCStats* referenced_stats = report_->Get(id);
          if (!referenced_stats || referenced_stats->type() != expected_type) {
            valid_reference = false;
            break;
          }
        }
      }
    }
    EXPECT_TRUE(valid_reference)
        << stats_->type() << "." << attribute.name()
        << " is not a reference to an "
           "existing dictionary of type "
        << expected_type << " (value: " << attribute.ToString() << ").";
    MarkAttributeTested(field, valid_reference);
  }

  rtc::scoped_refptr<const RTCStatsReport> report_;
  const RTCStats* stats_;
  std::set<const char*> untested_attribute_names_;
  bool all_tests_successful_;
};

class RTCStatsReportVerifier {
 public:
  static std::set<const char*> StatsTypes() {
    std::set<const char*> stats_types;
    stats_types.insert(RTCCertificateStats::kType);
    stats_types.insert(RTCCodecStats::kType);
    stats_types.insert(RTCDataChannelStats::kType);
    stats_types.insert(RTCIceCandidatePairStats::kType);
    stats_types.insert(RTCLocalIceCandidateStats::kType);
    stats_types.insert(RTCRemoteIceCandidateStats::kType);
    stats_types.insert(RTCPeerConnectionStats::kType);
    stats_types.insert(RTCInboundRtpStreamStats::kType);
    stats_types.insert(RTCOutboundRtpStreamStats::kType);
    stats_types.insert(RTCTransportStats::kType);
    return stats_types;
  }

  explicit RTCStatsReportVerifier(const RTCStatsReport* report)
      : report_(report) {}

  void VerifyReport(std::vector<const char*> allowed_missing_stats) {
    std::set<const char*> missing_stats = StatsTypes();
    bool verify_successful = true;
    std::vector<const RTCTransportStats*> transport_stats =
        report_->GetStatsOfType<RTCTransportStats>();
    EXPECT_EQ(transport_stats.size(), 1U);
    std::string selected_candidate_pair_id =
        *transport_stats[0]->selected_candidate_pair_id;
    for (const RTCStats& stats : *report_) {
      missing_stats.erase(stats.type());
      if (stats.type() == RTCCertificateStats::kType) {
        verify_successful &=
            VerifyRTCCertificateStats(stats.cast_to<RTCCertificateStats>());
      } else if (stats.type() == RTCCodecStats::kType) {
        verify_successful &=
            VerifyRTCCodecStats(stats.cast_to<RTCCodecStats>());
      } else if (stats.type() == RTCDataChannelStats::kType) {
        verify_successful &=
            VerifyRTCDataChannelStats(stats.cast_to<RTCDataChannelStats>());
      } else if (stats.type() == RTCIceCandidatePairStats::kType) {
        verify_successful &= VerifyRTCIceCandidatePairStats(
            stats.cast_to<RTCIceCandidatePairStats>(),
            stats.id() == selected_candidate_pair_id);
      } else if (stats.type() == RTCLocalIceCandidateStats::kType) {
        verify_successful &= VerifyRTCLocalIceCandidateStats(
            stats.cast_to<RTCLocalIceCandidateStats>());
      } else if (stats.type() == RTCRemoteIceCandidateStats::kType) {
        verify_successful &= VerifyRTCRemoteIceCandidateStats(
            stats.cast_to<RTCRemoteIceCandidateStats>());
      } else if (stats.type() == RTCPeerConnectionStats::kType) {
        verify_successful &= VerifyRTCPeerConnectionStats(
            stats.cast_to<RTCPeerConnectionStats>());
      } else if (stats.type() == RTCInboundRtpStreamStats::kType) {
        verify_successful &= VerifyRTCInboundRtpStreamStats(
            stats.cast_to<RTCInboundRtpStreamStats>());
      } else if (stats.type() == RTCOutboundRtpStreamStats::kType) {
        verify_successful &= VerifyRTCOutboundRtpStreamStats(
            stats.cast_to<RTCOutboundRtpStreamStats>());
      } else if (stats.type() == RTCRemoteInboundRtpStreamStats::kType) {
        verify_successful &= VerifyRTCRemoteInboundRtpStreamStats(
            stats.cast_to<RTCRemoteInboundRtpStreamStats>());
      } else if (stats.type() == RTCRemoteOutboundRtpStreamStats::kType) {
        verify_successful &= VerifyRTCRemoteOutboundRtpStreamStats(
            stats.cast_to<RTCRemoteOutboundRtpStreamStats>());
      } else if (stats.type() == RTCAudioSourceStats::kType) {
        // RTCAudioSourceStats::kType and RTCVideoSourceStats::kType both have
        // the value "media-source", but they are distinguishable with pointer
        // equality (==). In JavaScript they would be distinguished with `kind`.
        verify_successful &=
            VerifyRTCAudioSourceStats(stats.cast_to<RTCAudioSourceStats>());
      } else if (stats.type() == RTCVideoSourceStats::kType) {
        // RTCAudioSourceStats::kType and RTCVideoSourceStats::kType both have
        // the value "media-source", but they are distinguishable with pointer
        // equality (==). In JavaScript they would be distinguished with `kind`.
        verify_successful &=
            VerifyRTCVideoSourceStats(stats.cast_to<RTCVideoSourceStats>());
      } else if (stats.type() == RTCTransportStats::kType) {
        verify_successful &=
            VerifyRTCTransportStats(stats.cast_to<RTCTransportStats>());
      } else if (stats.type() == RTCAudioPlayoutStats::kType) {
        verify_successful &=
            VerifyRTCAudioPlayoutStats(stats.cast_to<RTCAudioPlayoutStats>());
      } else {
        EXPECT_TRUE(false) << "Unrecognized stats type: " << stats.type();
        verify_successful = false;
      }
    }
    for (const char* missing : missing_stats) {
      if (!absl::c_linear_search(allowed_missing_stats, missing)) {
        verify_successful = false;
        EXPECT_TRUE(false) << "Missing expected stats type: " << missing;
      }
    }
    EXPECT_TRUE(verify_successful)
        << "One or more problems with the stats. This is the report:\n"
        << report_->ToJson();
  }

  bool VerifyRTCCertificateStats(const RTCCertificateStats& certificate) {
    RTCStatsVerifier verifier(report_.get(), &certificate);
    verifier.TestAttributeIsDefined(certificate.fingerprint);
    verifier.TestAttributeIsDefined(certificate.fingerprint_algorithm);
    verifier.TestAttributeIsDefined(certificate.base64_certificate);
    verifier.TestAttributeIsOptionalIDReference(
        certificate.issuer_certificate_id, RTCCertificateStats::kType);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCCodecStats(const RTCCodecStats& codec) {
    RTCStatsVerifier verifier(report_.get(), &codec);
    verifier.TestAttributeIsIDReference(codec.transport_id,
                                        RTCTransportStats::kType);
    verifier.TestAttributeIsDefined(codec.payload_type);
    verifier.TestAttributeIsDefined(codec.mime_type);
    verifier.TestAttributeIsPositive<uint32_t>(codec.clock_rate);

    if (codec.mime_type->rfind("audio", 0) == 0)
      verifier.TestAttributeIsPositive<uint32_t>(codec.channels);
    else
      verifier.TestAttributeIsUndefined(codec.channels);

    // sdp_fmtp_line is an optional field.
    verifier.MarkAttributeTested(codec.sdp_fmtp_line, true);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCDataChannelStats(const RTCDataChannelStats& data_channel) {
    RTCStatsVerifier verifier(report_.get(), &data_channel);
    verifier.TestAttributeIsDefined(data_channel.label);
    verifier.TestAttributeIsDefined(data_channel.protocol);
    verifier.TestAttributeIsDefined(data_channel.data_channel_identifier);
    verifier.TestAttributeIsDefined(data_channel.state);
    verifier.TestAttributeIsNonNegative<uint32_t>(data_channel.messages_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(data_channel.bytes_sent);
    verifier.TestAttributeIsNonNegative<uint32_t>(
        data_channel.messages_received);
    verifier.TestAttributeIsNonNegative<uint64_t>(data_channel.bytes_received);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCIceCandidatePairStats(
      const RTCIceCandidatePairStats& candidate_pair,
      bool is_selected_pair) {
    RTCStatsVerifier verifier(report_.get(), &candidate_pair);
    verifier.TestAttributeIsIDReference(candidate_pair.transport_id,
                                        RTCTransportStats::kType);
    verifier.TestAttributeIsIDReference(candidate_pair.local_candidate_id,
                                        RTCLocalIceCandidateStats::kType);
    verifier.TestAttributeIsIDReference(candidate_pair.remote_candidate_id,
                                        RTCRemoteIceCandidateStats::kType);
    verifier.TestAttributeIsDefined(candidate_pair.state);
    verifier.TestAttributeIsNonNegative<uint64_t>(candidate_pair.priority);
    verifier.TestAttributeIsDefined(candidate_pair.nominated);
    verifier.TestAttributeIsDefined(candidate_pair.writable);
    verifier.TestAttributeIsNonNegative<uint64_t>(candidate_pair.packets_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.packets_discarded_on_send);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.packets_received);
    verifier.TestAttributeIsNonNegative<uint64_t>(candidate_pair.bytes_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.bytes_discarded_on_send);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.bytes_received);
    verifier.TestAttributeIsNonNegative<double>(
        candidate_pair.total_round_trip_time);
    verifier.TestAttributeIsNonNegative<double>(
        candidate_pair.current_round_trip_time);
    if (is_selected_pair) {
      verifier.TestAttributeIsNonNegative<double>(
          candidate_pair.available_outgoing_bitrate);
      // A pair should be nominated in order to be selected.
      EXPECT_TRUE(*candidate_pair.nominated);
    } else {
      verifier.TestAttributeIsUndefined(
          candidate_pair.available_outgoing_bitrate);
    }
    verifier.TestAttributeIsUndefined(
        candidate_pair.available_incoming_bitrate);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.requests_received);
    verifier.TestAttributeIsNonNegative<uint64_t>(candidate_pair.requests_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.responses_received);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.responses_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        candidate_pair.consent_requests_sent);
    verifier.TestAttributeIsDefined(
        candidate_pair.last_packet_received_timestamp);
    verifier.TestAttributeIsDefined(candidate_pair.last_packet_sent_timestamp);

    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCIceCandidateStats(const RTCIceCandidateStats& candidate) {
    RTCStatsVerifier verifier(report_.get(), &candidate);
    verifier.TestAttributeIsIDReference(candidate.transport_id,
                                        RTCTransportStats::kType);
    verifier.TestAttributeIsDefined(candidate.is_remote);
    if (*candidate.is_remote) {
      verifier.TestAttributeIsUndefined(candidate.network_type);
      verifier.TestAttributeIsUndefined(candidate.network_adapter_type);
      verifier.TestAttributeIsUndefined(candidate.vpn);
    } else {
      verifier.TestAttributeIsDefined(candidate.network_type);
      verifier.TestAttributeIsDefined(candidate.network_adapter_type);
      verifier.TestAttributeIsDefined(candidate.vpn);
    }
    verifier.TestAttributeIsDefined(candidate.ip);
    verifier.TestAttributeIsDefined(candidate.address);
    verifier.TestAttributeIsNonNegative<int32_t>(candidate.port);
    verifier.TestAttributeIsDefined(candidate.protocol);
    verifier.TestAttributeIsDefined(candidate.candidate_type);
    verifier.TestAttributeIsNonNegative<int32_t>(candidate.priority);
    verifier.TestAttributeIsUndefined(candidate.url);
    verifier.TestAttributeIsUndefined(candidate.relay_protocol);
    verifier.TestAttributeIsDefined(candidate.foundation);
    verifier.TestAttributeIsUndefined(candidate.related_address);
    verifier.TestAttributeIsUndefined(candidate.related_port);
    verifier.TestAttributeIsDefined(candidate.username_fragment);
    verifier.TestAttributeIsUndefined(candidate.tcp_type);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCLocalIceCandidateStats(
      const RTCLocalIceCandidateStats& local_candidate) {
    return VerifyRTCIceCandidateStats(local_candidate);
  }

  bool VerifyRTCRemoteIceCandidateStats(
      const RTCRemoteIceCandidateStats& remote_candidate) {
    return VerifyRTCIceCandidateStats(remote_candidate);
  }

  bool VerifyRTCPeerConnectionStats(
      const RTCPeerConnectionStats& peer_connection) {
    RTCStatsVerifier verifier(report_.get(), &peer_connection);
    verifier.TestAttributeIsNonNegative<uint32_t>(
        peer_connection.data_channels_opened);
    verifier.TestAttributeIsNonNegative<uint32_t>(
        peer_connection.data_channels_closed);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  void VerifyRTCRtpStreamStats(const RTCRtpStreamStats& stream,
                               RTCStatsVerifier& verifier) {
    verifier.TestAttributeIsDefined(stream.ssrc);
    verifier.TestAttributeIsDefined(stream.kind);
    verifier.TestAttributeIsIDReference(stream.transport_id,
                                        RTCTransportStats::kType);
    verifier.TestAttributeIsIDReference(stream.codec_id, RTCCodecStats::kType);
  }

  void VerifyRTCSentRtpStreamStats(const RTCSentRtpStreamStats& sent_stream,
                                   RTCStatsVerifier& verifier) {
    VerifyRTCRtpStreamStats(sent_stream, verifier);
    verifier.TestAttributeIsNonNegative<uint64_t>(sent_stream.packets_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(sent_stream.bytes_sent);
  }

  bool VerifyRTCInboundRtpStreamStats(
      const RTCInboundRtpStreamStats& inbound_stream) {
    RTCStatsVerifier verifier(report_.get(), &inbound_stream);
    VerifyRTCReceivedRtpStreamStats(inbound_stream, verifier);
    verifier.TestAttributeIsOptionalIDReference(
        inbound_stream.remote_id, RTCRemoteOutboundRtpStreamStats::kType);
    verifier.TestAttributeIsDefined(inbound_stream.mid);
    verifier.TestAttributeIsDefined(inbound_stream.track_identifier);
    if (inbound_stream.kind.has_value() && *inbound_stream.kind == "video") {
      verifier.TestAttributeIsNonNegative<uint64_t>(inbound_stream.qp_sum);
      verifier.TestAttributeIsDefined(inbound_stream.decoder_implementation);
      verifier.TestAttributeIsDefined(inbound_stream.power_efficient_decoder);
    } else {
      verifier.TestAttributeIsUndefined(inbound_stream.qp_sum);
      verifier.TestAttributeIsUndefined(inbound_stream.decoder_implementation);
      verifier.TestAttributeIsUndefined(inbound_stream.power_efficient_decoder);
    }
    // As long as the corruption detection RTP header extension is not activated
    // it should not aggregate any corruption score. The tests where this header
    // extension is enabled are located in pc/peer_connection_integrationtest.cc
    verifier.TestAttributeIsUndefined(
        inbound_stream.total_corruption_probability);
    verifier.TestAttributeIsUndefined(
        inbound_stream.total_squared_corruption_probability);
    verifier.TestAttributeIsUndefined(inbound_stream.corruption_measurements);
    verifier.TestAttributeIsNonNegative<uint32_t>(
        inbound_stream.packets_received);
    if (inbound_stream.kind.has_value() && *inbound_stream.kind == "audio") {
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.packets_discarded);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.fec_packets_received);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.fec_packets_discarded);
      verifier.TestAttributeIsUndefined(inbound_stream.fec_bytes_received);
    } else {
      verifier.TestAttributeIsUndefined(inbound_stream.packets_discarded);
      // FEC stats are only present when FlexFEC was negotiated which is guarded
      // by the WebRTC-FlexFEC-03-Advertised/Enabled/ field trial and off by
      // default.
      verifier.TestAttributeIsUndefined(inbound_stream.fec_bytes_received);
      verifier.TestAttributeIsUndefined(inbound_stream.fec_packets_received);
      verifier.TestAttributeIsUndefined(inbound_stream.fec_packets_discarded);
      verifier.TestAttributeIsUndefined(inbound_stream.fec_ssrc);
    }
    verifier.TestAttributeIsNonNegative<uint64_t>(
        inbound_stream.bytes_received);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        inbound_stream.header_bytes_received);
    verifier.TestAttributeIsDefined(
        inbound_stream.last_packet_received_timestamp);
    if (inbound_stream.frames_received.value_or(0) > 0) {
      verifier.TestAttributeIsNonNegative<uint32_t>(inbound_stream.frame_width);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          inbound_stream.frame_height);
    } else {
      verifier.TestAttributeIsUndefined(inbound_stream.frame_width);
      verifier.TestAttributeIsUndefined(inbound_stream.frame_height);
    }
    if (inbound_stream.frames_per_second.has_value()) {
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.frames_per_second);
    } else {
      verifier.TestAttributeIsUndefined(inbound_stream.frames_per_second);
    }
    verifier.TestAttributeIsNonNegative<double>(
        inbound_stream.jitter_buffer_delay);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        inbound_stream.jitter_buffer_emitted_count);
    verifier.TestAttributeIsNonNegative<double>(
        inbound_stream.jitter_buffer_target_delay);
    verifier.TestAttributeIsNonNegative<double>(
        inbound_stream.jitter_buffer_minimum_delay);
    verifier.TestAttributeIsNonNegative<double>(
        inbound_stream.total_processing_delay);
    if (inbound_stream.kind.has_value() && *inbound_stream.kind == "video") {
      verifier.TestAttributeIsUndefined(inbound_stream.total_samples_received);
      verifier.TestAttributeIsUndefined(inbound_stream.concealed_samples);
      verifier.TestAttributeIsUndefined(
          inbound_stream.silent_concealed_samples);
      verifier.TestAttributeIsUndefined(inbound_stream.concealment_events);
      verifier.TestAttributeIsUndefined(
          inbound_stream.inserted_samples_for_deceleration);
      verifier.TestAttributeIsUndefined(
          inbound_stream.removed_samples_for_acceleration);
      verifier.TestAttributeIsUndefined(inbound_stream.audio_level);
      verifier.TestAttributeIsUndefined(inbound_stream.total_audio_energy);
      verifier.TestAttributeIsUndefined(inbound_stream.total_samples_duration);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          inbound_stream.frames_received);
      verifier.TestAttributeIsNonNegative<uint32_t>(inbound_stream.fir_count);
      verifier.TestAttributeIsNonNegative<uint32_t>(inbound_stream.pli_count);
      verifier.TestAttributeIsNonNegative<uint32_t>(inbound_stream.nack_count);
    } else {
      verifier.TestAttributeIsUndefined(inbound_stream.fir_count);
      verifier.TestAttributeIsUndefined(inbound_stream.pli_count);
      verifier.TestAttributeIsUndefined(inbound_stream.nack_count);
      verifier.TestAttributeIsPositive<uint64_t>(
          inbound_stream.total_samples_received);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.concealed_samples);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.silent_concealed_samples);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.concealment_events);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.inserted_samples_for_deceleration);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.removed_samples_for_acceleration);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.jitter_buffer_target_delay);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.jitter_buffer_minimum_delay);
      verifier.TestAttributeIsPositive<double>(inbound_stream.audio_level);
      verifier.TestAttributeIsPositive<double>(
          inbound_stream.total_audio_energy);
      verifier.TestAttributeIsPositive<double>(
          inbound_stream.total_samples_duration);
      verifier.TestAttributeIsUndefined(inbound_stream.frames_received);
    }

    // RTX stats are typically only defined for video where RTX is negotiated.
    if (inbound_stream.kind.has_value() && *inbound_stream.kind == "video") {
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.retransmitted_packets_received);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.retransmitted_bytes_received);
      verifier.TestAttributeIsNonNegative<uint32_t>(inbound_stream.rtx_ssrc);
    } else {
      verifier.TestAttributeIsUndefined(
          inbound_stream.retransmitted_packets_received);
      verifier.TestAttributeIsUndefined(
          inbound_stream.retransmitted_bytes_received);
      verifier.TestAttributeIsUndefined(inbound_stream.rtx_ssrc);
      verifier.TestAttributeIsUndefined(inbound_stream.fec_ssrc);
    }

    // Test runtime too short to get an estimate (at least two RTCP sender
    // reports need to be received).
    verifier.MarkAttributeTested(inbound_stream.estimated_playout_timestamp,
                                 true);
    if (inbound_stream.kind.has_value() && *inbound_stream.kind == "video") {
      verifier.TestAttributeIsDefined(inbound_stream.frames_decoded);
      verifier.TestAttributeIsDefined(inbound_stream.key_frames_decoded);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          inbound_stream.frames_dropped);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.total_decode_time);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.total_assembly_time);
      verifier.TestAttributeIsDefined(
          inbound_stream.frames_assembled_from_multiple_packets);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.total_inter_frame_delay);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.total_squared_inter_frame_delay);
      verifier.TestAttributeIsNonNegative<uint32_t>(inbound_stream.pause_count);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.total_pauses_duration);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          inbound_stream.freeze_count);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.total_freezes_duration);
      // The integration test is not set up to test screen share; don't require
      // this to be present.
      verifier.MarkAttributeTested(inbound_stream.content_type, true);
      verifier.TestAttributeIsUndefined(inbound_stream.jitter_buffer_flushes);
      verifier.TestAttributeIsUndefined(
          inbound_stream.delayed_packet_outage_samples);
      verifier.TestAttributeIsUndefined(
          inbound_stream.relative_packet_arrival_delay);
      verifier.TestAttributeIsUndefined(inbound_stream.interruption_count);
      verifier.TestAttributeIsUndefined(
          inbound_stream.total_interruption_duration);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.min_playout_delay);
      verifier.TestAttributeIsDefined(inbound_stream.goog_timing_frame_info);
    } else {
      verifier.TestAttributeIsUndefined(inbound_stream.frames_decoded);
      verifier.TestAttributeIsUndefined(inbound_stream.key_frames_decoded);
      verifier.TestAttributeIsUndefined(inbound_stream.frames_dropped);
      verifier.TestAttributeIsUndefined(inbound_stream.total_decode_time);
      verifier.TestAttributeIsUndefined(inbound_stream.total_assembly_time);
      verifier.TestAttributeIsUndefined(
          inbound_stream.frames_assembled_from_multiple_packets);
      verifier.TestAttributeIsUndefined(inbound_stream.total_inter_frame_delay);
      verifier.TestAttributeIsUndefined(
          inbound_stream.total_squared_inter_frame_delay);
      verifier.TestAttributeIsUndefined(inbound_stream.pause_count);
      verifier.TestAttributeIsUndefined(inbound_stream.total_pauses_duration);
      verifier.TestAttributeIsUndefined(inbound_stream.freeze_count);
      verifier.TestAttributeIsUndefined(inbound_stream.total_freezes_duration);
      verifier.TestAttributeIsUndefined(inbound_stream.content_type);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.jitter_buffer_flushes);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          inbound_stream.delayed_packet_outage_samples);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.relative_packet_arrival_delay);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          inbound_stream.interruption_count);
      verifier.TestAttributeIsNonNegative<double>(
          inbound_stream.total_interruption_duration);
      verifier.TestAttributeIsUndefined(inbound_stream.min_playout_delay);
      verifier.TestAttributeIsUndefined(inbound_stream.goog_timing_frame_info);
    }
    if (inbound_stream.kind.has_value() && *inbound_stream.kind == "audio") {
      verifier.TestAttributeIsDefined(inbound_stream.playout_id);
    } else {
      verifier.TestAttributeIsUndefined(inbound_stream.playout_id);
    }

    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCOutboundRtpStreamStats(
      const RTCOutboundRtpStreamStats& outbound_stream) {
    RTCStatsVerifier verifier(report_.get(), &outbound_stream);
    VerifyRTCSentRtpStreamStats(outbound_stream, verifier);

    verifier.TestAttributeIsDefined(outbound_stream.mid);
    verifier.TestAttributeIsDefined(outbound_stream.active);
    if (outbound_stream.kind.has_value() && *outbound_stream.kind == "video") {
      verifier.TestAttributeIsIDReference(outbound_stream.media_source_id,
                                          RTCVideoSourceStats::kType);
      verifier.TestAttributeIsNonNegative<uint32_t>(outbound_stream.fir_count);
      verifier.TestAttributeIsNonNegative<uint32_t>(outbound_stream.pli_count);
      if (*outbound_stream.frames_encoded > 0) {
        verifier.TestAttributeIsNonNegative<uint64_t>(outbound_stream.qp_sum);
      } else {
        verifier.TestAttributeIsUndefined(outbound_stream.qp_sum);
      }
    } else {
      verifier.TestAttributeIsUndefined(outbound_stream.fir_count);
      verifier.TestAttributeIsUndefined(outbound_stream.pli_count);
      verifier.TestAttributeIsIDReference(outbound_stream.media_source_id,
                                          RTCAudioSourceStats::kType);
      verifier.TestAttributeIsUndefined(outbound_stream.qp_sum);
    }
    verifier.TestAttributeIsNonNegative<uint32_t>(outbound_stream.nack_count);
    verifier.TestAttributeIsOptionalIDReference(
        outbound_stream.remote_id, RTCRemoteInboundRtpStreamStats::kType);
    verifier.TestAttributeIsNonNegative<double>(
        outbound_stream.total_packet_send_delay);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        outbound_stream.retransmitted_packets_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        outbound_stream.header_bytes_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        outbound_stream.retransmitted_bytes_sent);
    verifier.TestAttributeIsNonNegative<double>(outbound_stream.target_bitrate);
    if (outbound_stream.kind.has_value() && *outbound_stream.kind == "video") {
      verifier.TestAttributeIsDefined(outbound_stream.frames_encoded);
      verifier.TestAttributeIsDefined(outbound_stream.key_frames_encoded);
      verifier.TestAttributeIsNonNegative<double>(
          outbound_stream.total_encode_time);
      verifier.TestAttributeIsNonNegative<uint64_t>(
          outbound_stream.total_encoded_bytes_target);
      verifier.TestAttributeIsDefined(
          outbound_stream.quality_limitation_reason);
      verifier.TestAttributeIsDefined(
          outbound_stream.quality_limitation_durations);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          outbound_stream.quality_limitation_resolution_changes);
      // The integration test is not set up to test screen share; don't require
      // this to be present.
      verifier.MarkAttributeTested(outbound_stream.content_type, true);
      verifier.TestAttributeIsDefined(outbound_stream.encoder_implementation);
      verifier.TestAttributeIsDefined(outbound_stream.power_efficient_encoder);
      // Unless an implementation-specific amount of time has passed and at
      // least one frame has been encoded, undefined is reported. Because it
      // is hard to tell what is the case here, we treat FPS as optional.
      // TODO(hbos): Update the tests to run until all implemented metrics
      // should be populated.
      if (outbound_stream.frames_per_second.has_value()) {
        verifier.TestAttributeIsNonNegative<double>(
            outbound_stream.frames_per_second);
      } else {
        verifier.TestAttributeIsUndefined(outbound_stream.frames_per_second);
      }
      verifier.TestAttributeIsNonNegative<uint32_t>(
          outbound_stream.frame_height);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          outbound_stream.frame_width);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          outbound_stream.frames_sent);
      verifier.TestAttributeIsNonNegative<uint32_t>(
          outbound_stream.huge_frames_sent);
      verifier.MarkAttributeTested(outbound_stream.rid, true);
      verifier.TestAttributeIsDefined(outbound_stream.scalability_mode);
      verifier.TestAttributeIsNonNegative<uint32_t>(outbound_stream.rtx_ssrc);
    } else {
      verifier.TestAttributeIsUndefined(outbound_stream.frames_encoded);
      verifier.TestAttributeIsUndefined(outbound_stream.key_frames_encoded);
      verifier.TestAttributeIsUndefined(outbound_stream.total_encode_time);
      verifier.TestAttributeIsUndefined(
          outbound_stream.total_encoded_bytes_target);
      verifier.TestAttributeIsUndefined(
          outbound_stream.quality_limitation_reason);
      verifier.TestAttributeIsUndefined(
          outbound_stream.quality_limitation_durations);
      verifier.TestAttributeIsUndefined(
          outbound_stream.quality_limitation_resolution_changes);
      verifier.TestAttributeIsUndefined(outbound_stream.content_type);
      // TODO(hbos): Implement for audio as well.
      verifier.TestAttributeIsUndefined(outbound_stream.encoder_implementation);
      verifier.TestAttributeIsUndefined(
          outbound_stream.power_efficient_encoder);
      verifier.TestAttributeIsUndefined(outbound_stream.rid);
      verifier.TestAttributeIsUndefined(outbound_stream.frames_per_second);
      verifier.TestAttributeIsUndefined(outbound_stream.frame_height);
      verifier.TestAttributeIsUndefined(outbound_stream.frame_width);
      verifier.TestAttributeIsUndefined(outbound_stream.frames_sent);
      verifier.TestAttributeIsUndefined(outbound_stream.huge_frames_sent);
      verifier.TestAttributeIsUndefined(outbound_stream.scalability_mode);
      verifier.TestAttributeIsUndefined(outbound_stream.rtx_ssrc);
    }
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  void VerifyRTCReceivedRtpStreamStats(
      const RTCReceivedRtpStreamStats& received_rtp,
      RTCStatsVerifier& verifier) {
    VerifyRTCRtpStreamStats(received_rtp, verifier);
    verifier.TestAttributeIsNonNegative<double>(received_rtp.jitter);
    verifier.TestAttributeIsDefined(received_rtp.packets_lost);
  }

  bool VerifyRTCRemoteInboundRtpStreamStats(
      const RTCRemoteInboundRtpStreamStats& remote_inbound_stream) {
    RTCStatsVerifier verifier(report_.get(), &remote_inbound_stream);
    VerifyRTCReceivedRtpStreamStats(remote_inbound_stream, verifier);
    verifier.TestAttributeIsDefined(remote_inbound_stream.fraction_lost);
    verifier.TestAttributeIsIDReference(remote_inbound_stream.local_id,
                                        RTCOutboundRtpStreamStats::kType);
    verifier.TestAttributeIsNonNegative<double>(
        remote_inbound_stream.round_trip_time);
    verifier.TestAttributeIsNonNegative<double>(
        remote_inbound_stream.total_round_trip_time);
    verifier.TestAttributeIsNonNegative<int32_t>(
        remote_inbound_stream.round_trip_time_measurements);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCRemoteOutboundRtpStreamStats(
      const RTCRemoteOutboundRtpStreamStats& remote_outbound_stream) {
    RTCStatsVerifier verifier(report_.get(), &remote_outbound_stream);
    VerifyRTCRtpStreamStats(remote_outbound_stream, verifier);
    VerifyRTCSentRtpStreamStats(remote_outbound_stream, verifier);
    verifier.TestAttributeIsIDReference(remote_outbound_stream.local_id,
                                        RTCInboundRtpStreamStats::kType);
    verifier.TestAttributeIsNonNegative<double>(
        remote_outbound_stream.remote_timestamp);
    verifier.TestAttributeIsDefined(remote_outbound_stream.reports_sent);
    // RTT-related attributes need DLRR.
    verifier.MarkAttributeTested(remote_outbound_stream.round_trip_time, true);
    verifier.MarkAttributeTested(
        remote_outbound_stream.round_trip_time_measurements, true);
    verifier.MarkAttributeTested(remote_outbound_stream.total_round_trip_time,
                                 true);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  void VerifyRTCMediaSourceStats(const RTCMediaSourceStats& media_source,
                                 RTCStatsVerifier* verifier) {
    verifier->TestAttributeIsDefined(media_source.track_identifier);
    verifier->TestAttributeIsDefined(media_source.kind);
    if (media_source.kind.has_value()) {
      EXPECT_TRUE((*media_source.kind == "audio" &&
                   media_source.type() == RTCAudioSourceStats::kType) ||
                  (*media_source.kind == "video" &&
                   media_source.type() == RTCVideoSourceStats::kType));
    }
  }

  bool VerifyRTCAudioSourceStats(const RTCAudioSourceStats& audio_source) {
    RTCStatsVerifier verifier(report_.get(), &audio_source);
    VerifyRTCMediaSourceStats(audio_source, &verifier);
    // Audio level, unlike audio energy, only gets updated at a certain
    // frequency, so we don't require that one to be positive to avoid a race
    // (https://crbug.com/webrtc/10962).
    verifier.TestAttributeIsNonNegative<double>(audio_source.audio_level);
    verifier.TestAttributeIsPositive<double>(audio_source.total_audio_energy);
    verifier.TestAttributeIsPositive<double>(
        audio_source.total_samples_duration);
    // TODO(hbos): `echo_return_loss` and `echo_return_loss_enhancement` are
    // flaky on msan bot (sometimes defined, sometimes undefined). Should the
    // test run until available or is there a way to have it always be
    // defined? crbug.com/627816
    verifier.MarkAttributeTested(audio_source.echo_return_loss, true);
    verifier.MarkAttributeTested(audio_source.echo_return_loss_enhancement,
                                 true);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCVideoSourceStats(const RTCVideoSourceStats& video_source) {
    RTCStatsVerifier verifier(report_.get(), &video_source);
    VerifyRTCMediaSourceStats(video_source, &verifier);
    // TODO(hbos): This integration test uses fakes that doesn't support
    // VideoTrackSourceInterface::Stats. When this is fixed we should
    // TestAttributeIsNonNegative<uint32_t>() for `width` and `height` instead
    // to reflect real code.
    verifier.TestAttributeIsUndefined(video_source.width);
    verifier.TestAttributeIsUndefined(video_source.height);
    verifier.TestAttributeIsNonNegative<uint32_t>(video_source.frames);
    verifier.TestAttributeIsNonNegative<double>(video_source.frames_per_second);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCTransportStats(const RTCTransportStats& transport) {
    RTCStatsVerifier verifier(report_.get(), &transport);
    verifier.TestAttributeIsNonNegative<uint64_t>(transport.bytes_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(transport.packets_sent);
    verifier.TestAttributeIsNonNegative<uint64_t>(transport.bytes_received);
    verifier.TestAttributeIsNonNegative<uint64_t>(transport.packets_received);
    verifier.TestAttributeIsOptionalIDReference(
        transport.rtcp_transport_stats_id, RTCTransportStats::kType);
    verifier.TestAttributeIsDefined(transport.dtls_state);
    verifier.TestAttributeIsIDReference(transport.selected_candidate_pair_id,
                                        RTCIceCandidatePairStats::kType);
    verifier.TestAttributeIsIDReference(transport.local_certificate_id,
                                        RTCCertificateStats::kType);
    verifier.TestAttributeIsIDReference(transport.remote_certificate_id,
                                        RTCCertificateStats::kType);
    verifier.TestAttributeIsDefined(transport.tls_version);
    verifier.TestAttributeIsDefined(transport.dtls_cipher);
    verifier.TestAttributeIsDefined(transport.dtls_role);
    verifier.TestAttributeIsDefined(transport.srtp_cipher);
    verifier.TestAttributeIsPositive<uint32_t>(
        transport.selected_candidate_pair_changes);
    verifier.TestAttributeIsDefined(transport.ice_role);
    verifier.TestAttributeIsDefined(transport.ice_local_username_fragment);
    verifier.TestAttributeIsDefined(transport.ice_state);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

  bool VerifyRTCAudioPlayoutStats(const RTCAudioPlayoutStats& audio_playout) {
    RTCStatsVerifier verifier(report_.get(), &audio_playout);
    verifier.TestAttributeIsDefined(audio_playout.kind);
    if (audio_playout.kind.has_value()) {
      EXPECT_EQ(*audio_playout.kind, "audio");
    }
    verifier.TestAttributeIsNonNegative<uint64_t>(
        audio_playout.synthesized_samples_events);
    verifier.TestAttributeIsNonNegative<double>(
        audio_playout.synthesized_samples_duration);
    verifier.TestAttributeIsNonNegative<uint64_t>(
        audio_playout.total_samples_count);
    verifier.TestAttributeIsNonNegative<double>(
        audio_playout.total_samples_duration);
    verifier.TestAttributeIsNonNegative<double>(
        audio_playout.total_playout_delay);
    return verifier.ExpectAllAttributesSuccessfullyTested();
  }

 private:
  rtc::scoped_refptr<const RTCStatsReport> report_;
};

#ifdef WEBRTC_HAVE_SCTP
TEST_F(RTCStatsIntegrationTest, GetStatsFromCaller) {
  StartCall();

  rtc::scoped_refptr<const RTCStatsReport> report = GetStatsFromCaller();
  RTCStatsReportVerifier(report.get()).VerifyReport({});
}

TEST_F(RTCStatsIntegrationTest, GetStatsFromCallee) {
  StartCall();

  rtc::scoped_refptr<const RTCStatsReport> report;
  // Wait for round trip time measurements to be defined.
  constexpr int kMaxWaitMs = 10000;
  auto GetStatsReportAndReturnTrueIfRttIsDefined = [&report, this] {
    report = GetStatsFromCallee();
    auto inbound_stats =
        report->GetStatsOfType<RTCRemoteInboundRtpStreamStats>();
    return !inbound_stats.empty() &&
           inbound_stats.front()->round_trip_time.has_value() &&
           inbound_stats.front()->round_trip_time_measurements.has_value();
  };
  EXPECT_THAT(
      WaitUntil([&] { return GetStatsReportAndReturnTrueIfRttIsDefined(); },
                ::testing::IsTrue(),
                {.timeout = webrtc::TimeDelta::Millis(kMaxWaitMs)}),
      IsRtcOk());
  RTCStatsReportVerifier(report.get()).VerifyReport({});
}

// These tests exercise the integration of the stats selection algorithm inside
// of PeerConnection. See rtcstatstraveral_unittest.cc for more detailed stats
// traversal tests on particular stats graphs.
TEST_F(RTCStatsIntegrationTest, GetStatsWithSenderSelector) {
  StartCall();
  ASSERT_FALSE(caller_->pc()->GetSenders().empty());
  rtc::scoped_refptr<const RTCStatsReport> report =
      GetStatsFromCaller(caller_->pc()->GetSenders()[0]);
  std::vector<const char*> allowed_missing_stats = {
      // TODO(hbos): Include RTC[Audio/Video]ReceiverStats when implemented.
      // TODO(hbos): Include RTCRemoteOutboundRtpStreamStats when implemented.
      // TODO(hbos): Include RTCRtpContributingSourceStats when implemented.
      RTCInboundRtpStreamStats::kType,
      RTCPeerConnectionStats::kType,
      RTCDataChannelStats::kType,
  };
  RTCStatsReportVerifier(report.get()).VerifyReport(allowed_missing_stats);
  EXPECT_TRUE(report->size());
}

TEST_F(RTCStatsIntegrationTest, GetStatsWithReceiverSelector) {
  StartCall();

  ASSERT_FALSE(caller_->pc()->GetReceivers().empty());
  rtc::scoped_refptr<const RTCStatsReport> report =
      GetStatsFromCaller(caller_->pc()->GetReceivers()[0]);
  std::vector<const char*> allowed_missing_stats = {
      // TODO(hbos): Include RTC[Audio/Video]SenderStats when implemented.
      // TODO(hbos): Include RTCRemoteInboundRtpStreamStats when implemented.
      // TODO(hbos): Include RTCRtpContributingSourceStats when implemented.
      RTCOutboundRtpStreamStats::kType,
      RTCPeerConnectionStats::kType,
      RTCDataChannelStats::kType,
  };
  RTCStatsReportVerifier(report.get()).VerifyReport(allowed_missing_stats);
  EXPECT_TRUE(report->size());
}

TEST_F(RTCStatsIntegrationTest, GetStatsWithInvalidSenderSelector) {
  StartCall();

  ASSERT_FALSE(callee_->pc()->GetSenders().empty());
  // The selector is invalid for the caller because it belongs to the callee.
  auto invalid_selector = callee_->pc()->GetSenders()[0];
  rtc::scoped_refptr<const RTCStatsReport> report =
      GetStatsFromCaller(invalid_selector);
  EXPECT_FALSE(report->size());
}

TEST_F(RTCStatsIntegrationTest, GetStatsWithInvalidReceiverSelector) {
  StartCall();

  ASSERT_FALSE(callee_->pc()->GetReceivers().empty());
  // The selector is invalid for the caller because it belongs to the callee.
  auto invalid_selector = callee_->pc()->GetReceivers()[0];
  rtc::scoped_refptr<const RTCStatsReport> report =
      GetStatsFromCaller(invalid_selector);
  EXPECT_FALSE(report->size());
}

// TODO(bugs.webrtc.org/10041) For now this is equivalent to the following
// test GetsStatsWhileClosingPeerConnection, because pc() is closed by
// PeerConnectionTestWrapper. See: bugs.webrtc.org/9847
TEST_F(RTCStatsIntegrationTest,
       DISABLED_GetStatsWhileDestroyingPeerConnection) {
  StartCall();

  rtc::scoped_refptr<RTCStatsObtainer> stats_obtainer =
      RTCStatsObtainer::Create();
  caller_->pc()->GetStats(stats_obtainer.get());
  // This will destroy the peer connection.
  caller_ = nullptr;
  // Any pending stats requests should have completed in the act of destroying
  // the peer connection.
  ASSERT_TRUE(stats_obtainer->report());
}

TEST_F(RTCStatsIntegrationTest, GetsStatsWhileClosingPeerConnection) {
  StartCall();

  rtc::scoped_refptr<RTCStatsObtainer> stats_obtainer =
      RTCStatsObtainer::Create();
  caller_->pc()->GetStats(stats_obtainer.get());
  caller_->pc()->Close();

  ASSERT_TRUE(stats_obtainer->report());
}

// GetStatsReferencedIds() is optimized to recognize what is or isn't a
// referenced ID based on dictionary type information and knowing what
// attributes are used as references, as opposed to iterating all attributes to
// find the ones with the "Id" or "Ids" suffix. As such, GetStatsReferencedIds()
// is tested as an integration test instead of a unit test in order to guard
// against adding new references and forgetting to update
// GetStatsReferencedIds().
TEST_F(RTCStatsIntegrationTest, GetStatsReferencedIds) {
  StartCall();

  rtc::scoped_refptr<const RTCStatsReport> report = GetStatsFromCallee();
  for (const RTCStats& stats : *report) {
    // Find all references by looking at all string attributes with the "Id" or
    // "Ids" suffix.
    std::set<const std::string*> expected_ids;
    for (const auto& attribute : stats.Attributes()) {
      if (!attribute.has_value())
        continue;
      if (attribute.holds_alternative<std::string>()) {
        if (absl::EndsWith(attribute.name(), "Id")) {
          expected_ids.insert(&attribute.get<std::string>());
        }
      } else if (attribute.holds_alternative<std::vector<std::string>>()) {
        if (absl::EndsWith(attribute.name(), "Ids")) {
          for (const std::string& id :
               attribute.get<std::vector<std::string>>())
            expected_ids.insert(&id);
        }
      }
    }

    std::vector<const std::string*> neighbor_ids = GetStatsReferencedIds(stats);
    EXPECT_EQ(neighbor_ids.size(), expected_ids.size());
    for (const std::string* neighbor_id : neighbor_ids) {
      EXPECT_THAT(expected_ids, Contains(neighbor_id));
    }
    for (const std::string* expected_id : expected_ids) {
      EXPECT_THAT(neighbor_ids, Contains(expected_id));
    }
  }
}

TEST_F(RTCStatsIntegrationTest, GetStatsContainsNoDuplicateAttributes) {
  StartCall();

  rtc::scoped_refptr<const RTCStatsReport> report = GetStatsFromCallee();
  for (const RTCStats& stats : *report) {
    std::set<std::string> attribute_names;
    for (const auto& attribute : stats.Attributes()) {
      EXPECT_TRUE(attribute_names.find(attribute.name()) ==
                  attribute_names.end())
          << attribute.name() << " is a duplicate!";
      attribute_names.insert(attribute.name());
    }
  }
}
#endif  // WEBRTC_HAVE_SCTP

}  // namespace

}  // namespace webrtc
