/*
 *  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 "pc/rtcstatscollector.h"

#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>

#include "api/candidate.h"
#include "api/mediastreaminterface.h"
#include "api/peerconnectioninterface.h"
#include "media/base/mediachannel.h"
#include "p2p/base/p2pconstants.h"
#include "p2p/base/port.h"
#include "pc/peerconnection.h"
#include "rtc_base/checks.h"
#include "rtc_base/stringutils.h"
#include "rtc_base/timeutils.h"
#include "rtc_base/trace_event.h"

namespace webrtc {

namespace {

std::string RTCCertificateIDFromFingerprint(const std::string& fingerprint) {
  return "RTCCertificate_" + fingerprint;
}

std::string RTCCodecStatsIDFromDirectionMediaAndPayload(
    bool inbound, bool audio, uint32_t payload_type) {
  // TODO(hbos): The present codec ID assignment is not sufficient to support
  // Unified Plan or unbundled connections in all cases. When we are able to
  // handle multiple m= lines of the same media type (and multiple BaseChannels
  // for the same type is possible?) this needs to be updated to differentiate
  // the transport being used, and stats need to be collected for all of them.
  if (inbound) {
    return audio ? "RTCCodec_InboundAudio_" + rtc::ToString<>(payload_type)
                 : "RTCCodec_InboundVideo_" + rtc::ToString<>(payload_type);
  }
  return audio ? "RTCCodec_OutboundAudio_" + rtc::ToString<>(payload_type)
               : "RTCCodec_OutboundVideo_" + rtc::ToString<>(payload_type);
}

std::string RTCIceCandidatePairStatsIDFromConnectionInfo(
    const cricket::ConnectionInfo& info) {
  return "RTCIceCandidatePair_" + info.local_candidate.id() + "_" +
      info.remote_candidate.id();
}

std::string RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
    bool is_local, const char* kind, const std::string& id, uint32_t ssrc) {
  RTC_DCHECK(kind == MediaStreamTrackInterface::kAudioKind ||
             kind == MediaStreamTrackInterface::kVideoKind);
  std::ostringstream oss;
  oss << (is_local ? "RTCMediaStreamTrack_local_"
                   : "RTCMediaStreamTrack_remote_");
  oss << kind << "_";
  oss << id << "_";
  oss << ssrc;
  return oss.str();
}

std::string RTCTransportStatsIDFromTransportChannel(
    const std::string& transport_name, int channel_component) {
  return "RTCTransport_" + transport_name + "_" +
      rtc::ToString<>(channel_component);
}

std::string RTCTransportStatsIDFromBaseChannel(
    const std::map<std::string, std::string>& proxy_to_transport,
    const cricket::BaseChannel& base_channel) {
  auto proxy_it = proxy_to_transport.find(base_channel.content_name());
  if (proxy_it == proxy_to_transport.cend())
    return "";
  return RTCTransportStatsIDFromTransportChannel(
      proxy_it->second, cricket::ICE_CANDIDATE_COMPONENT_RTP);
}

std::string RTCInboundRTPStreamStatsIDFromSSRC(bool audio, uint32_t ssrc) {
  return audio ? "RTCInboundRTPAudioStream_" + rtc::ToString<>(ssrc)
               : "RTCInboundRTPVideoStream_" + rtc::ToString<>(ssrc);
}

std::string RTCOutboundRTPStreamStatsIDFromSSRC(bool audio, uint32_t ssrc) {
  return audio ? "RTCOutboundRTPAudioStream_" + rtc::ToString<>(ssrc)
               : "RTCOutboundRTPVideoStream_" + rtc::ToString<>(ssrc);
}

const char* CandidateTypeToRTCIceCandidateType(const std::string& type) {
  if (type == cricket::LOCAL_PORT_TYPE)
    return RTCIceCandidateType::kHost;
  if (type == cricket::STUN_PORT_TYPE)
    return RTCIceCandidateType::kSrflx;
  if (type == cricket::PRFLX_PORT_TYPE)
    return RTCIceCandidateType::kPrflx;
  if (type == cricket::RELAY_PORT_TYPE)
    return RTCIceCandidateType::kRelay;
  RTC_NOTREACHED();
  return nullptr;
}

const char* DataStateToRTCDataChannelState(
    DataChannelInterface::DataState state) {
  switch (state) {
    case DataChannelInterface::kConnecting:
      return RTCDataChannelState::kConnecting;
    case DataChannelInterface::kOpen:
      return RTCDataChannelState::kOpen;
    case DataChannelInterface::kClosing:
      return RTCDataChannelState::kClosing;
    case DataChannelInterface::kClosed:
      return RTCDataChannelState::kClosed;
    default:
      RTC_NOTREACHED();
      return nullptr;
  }
}

const char* IceCandidatePairStateToRTCStatsIceCandidatePairState(
    cricket::IceCandidatePairState state) {
  switch (state) {
    case cricket::IceCandidatePairState::WAITING:
      return RTCStatsIceCandidatePairState::kWaiting;
    case cricket::IceCandidatePairState::IN_PROGRESS:
      return RTCStatsIceCandidatePairState::kInProgress;
    case cricket::IceCandidatePairState::SUCCEEDED:
      return RTCStatsIceCandidatePairState::kSucceeded;
    case cricket::IceCandidatePairState::FAILED:
      return RTCStatsIceCandidatePairState::kFailed;
    default:
      RTC_NOTREACHED();
      return nullptr;
  }
}

const char* DtlsTransportStateToRTCDtlsTransportState(
    cricket::DtlsTransportState state) {
  switch (state) {
    case cricket::DTLS_TRANSPORT_NEW:
      return RTCDtlsTransportState::kNew;
    case cricket::DTLS_TRANSPORT_CONNECTING:
      return RTCDtlsTransportState::kConnecting;
    case cricket::DTLS_TRANSPORT_CONNECTED:
      return RTCDtlsTransportState::kConnected;
    case cricket::DTLS_TRANSPORT_CLOSED:
      return RTCDtlsTransportState::kClosed;
    case cricket::DTLS_TRANSPORT_FAILED:
      return RTCDtlsTransportState::kFailed;
    default:
      RTC_NOTREACHED();
      return nullptr;
  }
}

const char* NetworkAdapterTypeToStatsType(rtc::AdapterType type) {
  switch (type) {
    case rtc::ADAPTER_TYPE_CELLULAR:
      return RTCNetworkType::kCellular;
    case rtc::ADAPTER_TYPE_ETHERNET:
      return RTCNetworkType::kEthernet;
    case rtc::ADAPTER_TYPE_WIFI:
      return RTCNetworkType::kWifi;
    case rtc::ADAPTER_TYPE_VPN:
      return RTCNetworkType::kVpn;
    case rtc::ADAPTER_TYPE_UNKNOWN:
    case rtc::ADAPTER_TYPE_LOOPBACK:
      return RTCNetworkType::kUnknown;
  }
  RTC_NOTREACHED();
  return nullptr;
}

double DoubleAudioLevelFromIntAudioLevel(int audio_level) {
  RTC_DCHECK_GE(audio_level, 0);
  RTC_DCHECK_LE(audio_level, 32767);
  return audio_level / 32767.0;
}

std::unique_ptr<RTCCodecStats> CodecStatsFromRtpCodecParameters(
    uint64_t timestamp_us, bool inbound, bool audio,
    const RtpCodecParameters& codec_params) {
  RTC_DCHECK_GE(codec_params.payload_type, 0);
  RTC_DCHECK_LE(codec_params.payload_type, 127);
  RTC_DCHECK(codec_params.clock_rate);
  uint32_t payload_type = static_cast<uint32_t>(codec_params.payload_type);
  std::unique_ptr<RTCCodecStats> codec_stats(new RTCCodecStats(
      RTCCodecStatsIDFromDirectionMediaAndPayload(inbound, audio, payload_type),
      timestamp_us));
  codec_stats->payload_type = payload_type;
  codec_stats->mime_type = codec_params.mime_type();
  if (codec_params.clock_rate) {
    codec_stats->clock_rate = static_cast<uint32_t>(*codec_params.clock_rate);
  }
  return codec_stats;
}

void SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
    const MediaStreamTrackInterface& track,
    RTCMediaStreamTrackStats* track_stats) {
  track_stats->track_identifier = track.id();
  track_stats->ended = (track.state() == MediaStreamTrackInterface::kEnded);
}

// Provides the media independent counters (both audio and video).
void SetInboundRTPStreamStatsFromMediaReceiverInfo(
    const cricket::MediaReceiverInfo& media_receiver_info,
    RTCInboundRTPStreamStats* inbound_stats) {
  RTC_DCHECK(inbound_stats);
  inbound_stats->ssrc = media_receiver_info.ssrc();
  // TODO(hbos): Support the remote case. crbug.com/657855
  inbound_stats->is_remote = false;
  inbound_stats->packets_received =
      static_cast<uint32_t>(media_receiver_info.packets_rcvd);
  inbound_stats->bytes_received =
      static_cast<uint64_t>(media_receiver_info.bytes_rcvd);
  inbound_stats->packets_lost =
      static_cast<uint32_t>(media_receiver_info.packets_lost);
  inbound_stats->fraction_lost =
      static_cast<double>(media_receiver_info.fraction_lost);
}

void SetInboundRTPStreamStatsFromVoiceReceiverInfo(
    const cricket::VoiceReceiverInfo& voice_receiver_info,
    RTCInboundRTPStreamStats* inbound_audio) {
  SetInboundRTPStreamStatsFromMediaReceiverInfo(
      voice_receiver_info, inbound_audio);
  inbound_audio->media_type = "audio";
  if (voice_receiver_info.codec_payload_type) {
    inbound_audio->codec_id =
        RTCCodecStatsIDFromDirectionMediaAndPayload(
            true, true, *voice_receiver_info.codec_payload_type);
  }
  inbound_audio->jitter =
      static_cast<double>(voice_receiver_info.jitter_ms) /
          rtc::kNumMillisecsPerSec;
  // |fir_count|, |pli_count| and |sli_count| are only valid for video and are
  // purposefully left undefined for audio.
}

void SetInboundRTPStreamStatsFromVideoReceiverInfo(
    const cricket::VideoReceiverInfo& video_receiver_info,
    RTCInboundRTPStreamStats* inbound_video) {
  SetInboundRTPStreamStatsFromMediaReceiverInfo(
      video_receiver_info, inbound_video);
  inbound_video->media_type = "video";
  if (video_receiver_info.codec_payload_type) {
    inbound_video->codec_id =
        RTCCodecStatsIDFromDirectionMediaAndPayload(
            true, false, *video_receiver_info.codec_payload_type);
  }
  inbound_video->fir_count =
      static_cast<uint32_t>(video_receiver_info.firs_sent);
  inbound_video->pli_count =
      static_cast<uint32_t>(video_receiver_info.plis_sent);
  inbound_video->nack_count =
      static_cast<uint32_t>(video_receiver_info.nacks_sent);
  inbound_video->frames_decoded = video_receiver_info.frames_decoded;
  if (video_receiver_info.qp_sum)
    inbound_video->qp_sum = *video_receiver_info.qp_sum;
}

// Provides the media independent counters (both audio and video).
void SetOutboundRTPStreamStatsFromMediaSenderInfo(
    const cricket::MediaSenderInfo& media_sender_info,
    RTCOutboundRTPStreamStats* outbound_stats) {
  RTC_DCHECK(outbound_stats);
  outbound_stats->ssrc = media_sender_info.ssrc();
  // TODO(hbos): Support the remote case. crbug.com/657856
  outbound_stats->is_remote = false;
  outbound_stats->packets_sent =
      static_cast<uint32_t>(media_sender_info.packets_sent);
  outbound_stats->bytes_sent =
      static_cast<uint64_t>(media_sender_info.bytes_sent);
}

void SetOutboundRTPStreamStatsFromVoiceSenderInfo(
    const cricket::VoiceSenderInfo& voice_sender_info,
    RTCOutboundRTPStreamStats* outbound_audio) {
  SetOutboundRTPStreamStatsFromMediaSenderInfo(
      voice_sender_info, outbound_audio);
  outbound_audio->media_type = "audio";
  if (voice_sender_info.codec_payload_type) {
    outbound_audio->codec_id =
        RTCCodecStatsIDFromDirectionMediaAndPayload(
            false, true, *voice_sender_info.codec_payload_type);
  }
  // |fir_count|, |pli_count| and |sli_count| are only valid for video and are
  // purposefully left undefined for audio.
}

void SetOutboundRTPStreamStatsFromVideoSenderInfo(
    const cricket::VideoSenderInfo& video_sender_info,
    RTCOutboundRTPStreamStats* outbound_video) {
  SetOutboundRTPStreamStatsFromMediaSenderInfo(
      video_sender_info, outbound_video);
  outbound_video->media_type = "video";
  if (video_sender_info.codec_payload_type) {
    outbound_video->codec_id =
        RTCCodecStatsIDFromDirectionMediaAndPayload(
            false, false, *video_sender_info.codec_payload_type);
  }
  outbound_video->fir_count =
      static_cast<uint32_t>(video_sender_info.firs_rcvd);
  outbound_video->pli_count =
      static_cast<uint32_t>(video_sender_info.plis_rcvd);
  outbound_video->nack_count =
      static_cast<uint32_t>(video_sender_info.nacks_rcvd);
  if (video_sender_info.qp_sum)
    outbound_video->qp_sum = *video_sender_info.qp_sum;
  outbound_video->frames_encoded = video_sender_info.frames_encoded;
}

void ProduceCertificateStatsFromSSLCertificateStats(
    int64_t timestamp_us, const rtc::SSLCertificateStats& certificate_stats,
    RTCStatsReport* report) {
  RTCCertificateStats* prev_certificate_stats = nullptr;
  for (const rtc::SSLCertificateStats* s = &certificate_stats; s;
       s = s->issuer.get()) {
    std::string certificate_stats_id =
        RTCCertificateIDFromFingerprint(s->fingerprint);
    // It is possible for the same certificate to show up multiple times, e.g.
    // if local and remote side use the same certificate in a loopback call.
    // If the report already contains stats for this certificate, skip it.
    if (report->Get(certificate_stats_id)) {
      RTC_DCHECK_EQ(s, &certificate_stats);
      break;
    }
    RTCCertificateStats* certificate_stats = new RTCCertificateStats(
        certificate_stats_id, timestamp_us);
    certificate_stats->fingerprint = s->fingerprint;
    certificate_stats->fingerprint_algorithm = s->fingerprint_algorithm;
    certificate_stats->base64_certificate = s->base64_certificate;
    if (prev_certificate_stats)
      prev_certificate_stats->issuer_certificate_id = certificate_stats->id();
    report->AddStats(std::unique_ptr<RTCCertificateStats>(certificate_stats));
    prev_certificate_stats = certificate_stats;
  }
}

const std::string& ProduceIceCandidateStats(
    int64_t timestamp_us, const cricket::Candidate& candidate, bool is_local,
    const std::string& transport_id, RTCStatsReport* report) {
  const std::string& id = "RTCIceCandidate_" + candidate.id();
  const RTCStats* stats = report->Get(id);
  if (!stats) {
    std::unique_ptr<RTCIceCandidateStats> candidate_stats;
    if (is_local)
      candidate_stats.reset(new RTCLocalIceCandidateStats(id, timestamp_us));
    else
      candidate_stats.reset(new RTCRemoteIceCandidateStats(id, timestamp_us));
    candidate_stats->transport_id = transport_id;
    if (is_local) {
      candidate_stats->network_type =
          NetworkAdapterTypeToStatsType(candidate.network_type());
    } else {
      // We don't expect to know the adapter type of remote candidates.
      RTC_DCHECK_EQ(rtc::ADAPTER_TYPE_UNKNOWN, candidate.network_type());
    }
    candidate_stats->ip = candidate.address().ipaddr().ToString();
    candidate_stats->port = static_cast<int32_t>(candidate.address().port());
    candidate_stats->protocol = candidate.protocol();
    candidate_stats->candidate_type = CandidateTypeToRTCIceCandidateType(
        candidate.type());
    candidate_stats->priority = static_cast<int32_t>(candidate.priority());

    stats = candidate_stats.get();
    report->AddStats(std::move(candidate_stats));
  }
  RTC_DCHECK_EQ(stats->type(), is_local ? RTCLocalIceCandidateStats::kType
                                        : RTCRemoteIceCandidateStats::kType);
  return stats->id();
}

std::unique_ptr<RTCMediaStreamTrackStats>
ProduceMediaStreamTrackStatsFromVoiceSenderInfo(
    int64_t timestamp_us,
    const AudioTrackInterface& audio_track,
    const cricket::VoiceSenderInfo& voice_sender_info) {
  std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats(
      new RTCMediaStreamTrackStats(
          RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
              true, MediaStreamTrackInterface::kAudioKind, audio_track.id(),
              voice_sender_info.ssrc()),
          timestamp_us,
          RTCMediaStreamTrackKind::kAudio));
  SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
      audio_track, audio_track_stats.get());
  audio_track_stats->remote_source = false;
  audio_track_stats->detached = false;
  if (voice_sender_info.audio_level >= 0) {
    audio_track_stats->audio_level = DoubleAudioLevelFromIntAudioLevel(
        voice_sender_info.audio_level);
  }
  audio_track_stats->total_audio_energy = voice_sender_info.total_input_energy;
  audio_track_stats->total_samples_duration =
      voice_sender_info.total_input_duration;
  if (voice_sender_info.echo_return_loss != -100) {
    audio_track_stats->echo_return_loss = static_cast<double>(
        voice_sender_info.echo_return_loss);
  }
  if (voice_sender_info.echo_return_loss_enhancement != -100) {
    audio_track_stats->echo_return_loss_enhancement = static_cast<double>(
        voice_sender_info.echo_return_loss_enhancement);
  }
  return audio_track_stats;
}

std::unique_ptr<RTCMediaStreamTrackStats>
ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
    int64_t timestamp_us,
    const AudioTrackInterface& audio_track,
    const cricket::VoiceReceiverInfo& voice_receiver_info) {
  std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats(
      new RTCMediaStreamTrackStats(
          RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
              false, MediaStreamTrackInterface::kAudioKind, audio_track.id(),
              voice_receiver_info.ssrc()),
          timestamp_us,
          RTCMediaStreamTrackKind::kAudio));
  SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
      audio_track, audio_track_stats.get());
  audio_track_stats->remote_source = true;
  audio_track_stats->detached = false;
  if (voice_receiver_info.audio_level >= 0) {
    audio_track_stats->audio_level = DoubleAudioLevelFromIntAudioLevel(
        voice_receiver_info.audio_level);
  }
  audio_track_stats->jitter_buffer_delay =
      voice_receiver_info.jitter_buffer_delay_seconds;
  audio_track_stats->total_audio_energy =
      voice_receiver_info.total_output_energy;
  audio_track_stats->total_samples_received =
      voice_receiver_info.total_samples_received;
  audio_track_stats->total_samples_duration =
      voice_receiver_info.total_output_duration;
  audio_track_stats->concealed_samples = voice_receiver_info.concealed_samples;
  audio_track_stats->concealment_events =
      voice_receiver_info.concealment_events;
  return audio_track_stats;
}

std::unique_ptr<RTCMediaStreamTrackStats>
ProduceMediaStreamTrackStatsFromVideoSenderInfo(
    int64_t timestamp_us,
    const VideoTrackInterface& video_track,
    const cricket::VideoSenderInfo& video_sender_info) {
  std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats(
      new RTCMediaStreamTrackStats(
          RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
              true, MediaStreamTrackInterface::kVideoKind, video_track.id(),
              video_sender_info.ssrc()),
          timestamp_us,
          RTCMediaStreamTrackKind::kVideo));
  SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
      video_track, video_track_stats.get());
  video_track_stats->remote_source = false;
  video_track_stats->detached = false;
  video_track_stats->frame_width = static_cast<uint32_t>(
      video_sender_info.send_frame_width);
  video_track_stats->frame_height = static_cast<uint32_t>(
      video_sender_info.send_frame_height);
  // TODO(hbos): Will reduce this by frames dropped due to congestion control
  // when available. crbug.com/659137
  video_track_stats->frames_sent = video_sender_info.frames_encoded;
  return video_track_stats;
}

std::unique_ptr<RTCMediaStreamTrackStats>
ProduceMediaStreamTrackStatsFromVideoReceiverInfo(
    int64_t timestamp_us,
    const VideoTrackInterface& video_track,
    const cricket::VideoReceiverInfo& video_receiver_info) {
  std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats(
      new RTCMediaStreamTrackStats(
          RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
              false, MediaStreamTrackInterface::kVideoKind, video_track.id(),
              video_receiver_info.ssrc()),
          timestamp_us,
          RTCMediaStreamTrackKind::kVideo));
  SetMediaStreamTrackStatsFromMediaStreamTrackInterface(
      video_track, video_track_stats.get());
  video_track_stats->remote_source = true;
  video_track_stats->detached = false;
  if (video_receiver_info.frame_width > 0 &&
      video_receiver_info.frame_height > 0) {
    video_track_stats->frame_width = static_cast<uint32_t>(
        video_receiver_info.frame_width);
    video_track_stats->frame_height = static_cast<uint32_t>(
        video_receiver_info.frame_height);
  }
  video_track_stats->frames_received = video_receiver_info.frames_received;
  // TODO(hbos): When we support receiving simulcast, this should be the total
  // number of frames correctly decoded, independent of which SSRC it was
  // received from. Since we don't support that, this is correct and is the same
  // value as "RTCInboundRTPStreamStats.framesDecoded". crbug.com/659137
  video_track_stats->frames_decoded = video_receiver_info.frames_decoded;
  RTC_DCHECK_GE(video_receiver_info.frames_received,
                video_receiver_info.frames_rendered);
  video_track_stats->frames_dropped = video_receiver_info.frames_received -
                                      video_receiver_info.frames_rendered;
  return video_track_stats;
}

void ProduceMediaStreamAndTrackStats(
    int64_t timestamp_us,
    const TrackMediaInfoMap& track_media_info_map,
    rtc::scoped_refptr<StreamCollectionInterface> streams,
    bool is_local,
    RTCStatsReport* report) {
  // TODO(hbos): When "AddTrack" is implemented we should iterate tracks to
  // find which streams exist, not iterate streams to find tracks.
  // crbug.com/659137
  // TODO(hbos): Return stats of detached tracks. We have to perform stats
  // gathering at the time of detachment to get accurate stats and timestamps.
  // crbug.com/659137
  if (!streams)
    return;
  for (size_t i = 0; i < streams->count(); ++i) {
    MediaStreamInterface* stream = streams->at(i);

    std::unique_ptr<RTCMediaStreamStats> stream_stats(
        new RTCMediaStreamStats(
            (is_local ? "RTCMediaStream_local_" : "RTCMediaStream_remote_") +
            stream->label(), timestamp_us));
    stream_stats->stream_identifier = stream->label();
    stream_stats->track_ids = std::vector<std::string>();
    // The track stats are per-attachment to the connection. There can be one
    // for receiving (remote) tracks and multiple attachments for sending
    // (local) tracks.
    if (is_local) {
      // Local Audio Tracks
      for (const rtc::scoped_refptr<AudioTrackInterface>& audio_track :
           stream->GetAudioTracks()) {
        const std::vector<cricket::VoiceSenderInfo*>* voice_sender_infos =
            track_media_info_map.GetVoiceSenderInfos(*audio_track);
        if (!voice_sender_infos) {
          continue;
        }
        for (const auto& voice_sender_info : *voice_sender_infos) {
          std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats =
              ProduceMediaStreamTrackStatsFromVoiceSenderInfo(
                  timestamp_us, *audio_track, *voice_sender_info);
          stream_stats->track_ids->push_back(audio_track_stats->id());
          report->AddStats(std::move(audio_track_stats));
        }
      }
      // Local Video Tracks
      for (const rtc::scoped_refptr<VideoTrackInterface>& video_track :
           stream->GetVideoTracks()) {
        const std::vector<cricket::VideoSenderInfo*>* video_sender_infos =
            track_media_info_map.GetVideoSenderInfos(*video_track);
        if (!video_sender_infos) {
          continue;
        }
        for (const auto& video_sender_info : *video_sender_infos) {
          std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats =
              ProduceMediaStreamTrackStatsFromVideoSenderInfo(
                  timestamp_us, *video_track, *video_sender_info);
          stream_stats->track_ids->push_back(video_track_stats->id());
          report->AddStats(std::move(video_track_stats));
        }
      }
    } else {
      // Remote Audio Tracks
      for (const rtc::scoped_refptr<AudioTrackInterface>& audio_track :
           stream->GetAudioTracks()) {
        const cricket::VoiceReceiverInfo* voice_receiver_info =
            track_media_info_map.GetVoiceReceiverInfo(*audio_track);
        if (!voice_receiver_info) {
          continue;
        }
        std::unique_ptr<RTCMediaStreamTrackStats> audio_track_stats =
            ProduceMediaStreamTrackStatsFromVoiceReceiverInfo(
                timestamp_us, *audio_track, *voice_receiver_info);
        stream_stats->track_ids->push_back(audio_track_stats->id());
        report->AddStats(std::move(audio_track_stats));
      }
      // Remote Video Tracks
      for (const rtc::scoped_refptr<VideoTrackInterface>& video_track :
           stream->GetVideoTracks()) {
        const cricket::VideoReceiverInfo* video_receiver_info =
            track_media_info_map.GetVideoReceiverInfo(*video_track);
        if (!video_receiver_info) {
          continue;
        }
        std::unique_ptr<RTCMediaStreamTrackStats> video_track_stats =
            ProduceMediaStreamTrackStatsFromVideoReceiverInfo(
                timestamp_us, *video_track, *video_receiver_info);
        stream_stats->track_ids->push_back(video_track_stats->id());
        report->AddStats(std::move(video_track_stats));
      }
    }
    report->AddStats(std::move(stream_stats));
  }
}

}  // namespace

rtc::scoped_refptr<RTCStatsCollector> RTCStatsCollector::Create(
    PeerConnection* pc, int64_t cache_lifetime_us) {
  return rtc::scoped_refptr<RTCStatsCollector>(
      new rtc::RefCountedObject<RTCStatsCollector>(pc, cache_lifetime_us));
}

RTCStatsCollector::RTCStatsCollector(PeerConnection* pc,
                                     int64_t cache_lifetime_us)
    : pc_(pc),
      signaling_thread_(pc->signaling_thread()),
      worker_thread_(pc->worker_thread()),
      network_thread_(pc->network_thread()),
      num_pending_partial_reports_(0),
      partial_report_timestamp_us_(0),
      cache_timestamp_us_(0),
      cache_lifetime_us_(cache_lifetime_us) {
  RTC_DCHECK(pc_);
  RTC_DCHECK(signaling_thread_);
  RTC_DCHECK(worker_thread_);
  RTC_DCHECK(network_thread_);
  RTC_DCHECK_GE(cache_lifetime_us_, 0);
  pc_->SignalDataChannelCreated.connect(
      this, &RTCStatsCollector::OnDataChannelCreated);
}

RTCStatsCollector::~RTCStatsCollector() {
  RTC_DCHECK_EQ(num_pending_partial_reports_, 0);
}

void RTCStatsCollector::GetStatsReport(
    rtc::scoped_refptr<RTCStatsCollectorCallback> callback) {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  RTC_DCHECK(callback);
  callbacks_.push_back(callback);

  // "Now" using a monotonically increasing timer.
  int64_t cache_now_us = rtc::TimeMicros();
  if (cached_report_ &&
      cache_now_us - cache_timestamp_us_ <= cache_lifetime_us_) {
    // We have a fresh cached report to deliver.
    DeliverCachedReport();
  } else if (!num_pending_partial_reports_) {
    // Only start gathering stats if we're not already gathering stats. In the
    // case of already gathering stats, |callback_| will be invoked when there
    // are no more pending partial reports.

    // "Now" using a system clock, relative to the UNIX epoch (Jan 1, 1970,
    // UTC), in microseconds. The system clock could be modified and is not
    // necessarily monotonically increasing.
    int64_t timestamp_us = rtc::TimeUTCMicros();

    num_pending_partial_reports_ = 2;
    partial_report_timestamp_us_ = cache_now_us;

    // Prepare |channel_name_pairs_| for use in
    // |ProducePartialResultsOnNetworkThread|.
    channel_name_pairs_.reset(new ChannelNamePairs());
    if (pc_->voice_channel()) {
      channel_name_pairs_->voice =
          ChannelNamePair(pc_->voice_channel()->content_name(),
                          pc_->voice_channel()->transport_name());
    }
    if (pc_->video_channel()) {
      channel_name_pairs_->video =
          ChannelNamePair(pc_->video_channel()->content_name(),
                          pc_->video_channel()->transport_name());
    }
    if (pc_->rtp_data_channel()) {
      channel_name_pairs_->data =
          ChannelNamePair(pc_->rtp_data_channel()->content_name(),
                          pc_->rtp_data_channel()->transport_name());
    }
    if (pc_->sctp_content_name()) {
      channel_name_pairs_->data = ChannelNamePair(*pc_->sctp_content_name(),
                                                  *pc_->sctp_transport_name());
    }
    // Prepare |track_media_info_map_| for use in
    // |ProducePartialResultsOnNetworkThread| and
    // |ProducePartialResultsOnSignalingThread|.
    track_media_info_map_.reset(PrepareTrackMediaInfoMap_s().release());
    // Prepare |track_to_id_| for use in |ProducePartialResultsOnNetworkThread|.
    // This avoids a possible deadlock if |MediaStreamTrackInterface::id| is
    // implemented to invoke on the signaling thread.
    track_to_id_ = PrepareTrackToID_s();

    // Prepare |call_stats_| here since GetCallStats() will hop to the worker
    // thread.
    // TODO(holmer): To avoid the hop we could move BWE and BWE stats to the
    // network thread, where it more naturally belongs.
    call_stats_ = pc_->GetCallStats();

    invoker_.AsyncInvoke<void>(
        RTC_FROM_HERE, network_thread_,
        rtc::Bind(&RTCStatsCollector::ProducePartialResultsOnNetworkThread,
                  rtc::scoped_refptr<RTCStatsCollector>(this), timestamp_us));
    ProducePartialResultsOnSignalingThread(timestamp_us);
  }
}

void RTCStatsCollector::ClearCachedStatsReport() {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  cached_report_ = nullptr;
}

void RTCStatsCollector::WaitForPendingRequest() {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  if (num_pending_partial_reports_) {
    rtc::Thread::Current()->ProcessMessages(0);
    while (num_pending_partial_reports_) {
      rtc::Thread::Current()->SleepMs(1);
      rtc::Thread::Current()->ProcessMessages(0);
    }
  }
}

void RTCStatsCollector::ProducePartialResultsOnSignalingThread(
    int64_t timestamp_us) {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
      timestamp_us);

  ProduceDataChannelStats_s(timestamp_us, report.get());
  ProduceMediaStreamAndTrackStats_s(timestamp_us, report.get());
  ProducePeerConnectionStats_s(timestamp_us, report.get());

  AddPartialResults(report);
}

void RTCStatsCollector::ProducePartialResultsOnNetworkThread(
    int64_t timestamp_us) {
  RTC_DCHECK(network_thread_->IsCurrent());
  rtc::scoped_refptr<RTCStatsReport> report = RTCStatsReport::Create(
      timestamp_us);

  std::unique_ptr<SessionStats> session_stats =
      pc_->GetSessionStats(*channel_name_pairs_);
  if (session_stats) {
    std::map<std::string, CertificateStatsPair> transport_cert_stats =
        PrepareTransportCertificateStats_n(*session_stats);

    ProduceCertificateStats_n(
        timestamp_us, transport_cert_stats, report.get());
    ProduceCodecStats_n(
        timestamp_us, *track_media_info_map_, report.get());
    ProduceIceCandidateAndPairStats_n(timestamp_us, *session_stats,
                                      track_media_info_map_->video_media_info(),
                                      call_stats_, report.get());
    ProduceRTPStreamStats_n(
        timestamp_us, *session_stats, *track_media_info_map_, report.get());
    ProduceTransportStats_n(
        timestamp_us, *session_stats, transport_cert_stats, report.get());
  }

  AddPartialResults(report);
}

void RTCStatsCollector::AddPartialResults(
    const rtc::scoped_refptr<RTCStatsReport>& partial_report) {
  if (!signaling_thread_->IsCurrent()) {
    invoker_.AsyncInvoke<void>(RTC_FROM_HERE, signaling_thread_,
        rtc::Bind(&RTCStatsCollector::AddPartialResults_s,
                  rtc::scoped_refptr<RTCStatsCollector>(this),
                  partial_report));
    return;
  }
  AddPartialResults_s(partial_report);
}

void RTCStatsCollector::AddPartialResults_s(
    rtc::scoped_refptr<RTCStatsReport> partial_report) {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  RTC_DCHECK_GT(num_pending_partial_reports_, 0);
  if (!partial_report_)
    partial_report_ = partial_report;
  else
    partial_report_->TakeMembersFrom(partial_report);
  --num_pending_partial_reports_;
  if (!num_pending_partial_reports_) {
    cache_timestamp_us_ = partial_report_timestamp_us_;
    cached_report_ = partial_report_;
    partial_report_ = nullptr;
    channel_name_pairs_.reset();
    track_media_info_map_.reset();
    track_to_id_.clear();
    // Trace WebRTC Stats when getStats is called on Javascript.
    // This allows access to WebRTC stats from trace logs. To enable them,
    // select the "webrtc_stats" category when recording traces.
    TRACE_EVENT_INSTANT1("webrtc_stats", "webrtc_stats", "report",
                         cached_report_->ToJson());
    DeliverCachedReport();
  }
}

void RTCStatsCollector::DeliverCachedReport() {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  RTC_DCHECK(!callbacks_.empty());
  RTC_DCHECK(cached_report_);
  for (const rtc::scoped_refptr<RTCStatsCollectorCallback>& callback :
       callbacks_) {
    callback->OnStatsDelivered(cached_report_);
  }
  callbacks_.clear();
}

void RTCStatsCollector::ProduceCertificateStats_n(
    int64_t timestamp_us,
    const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
    RTCStatsReport* report) const {
  RTC_DCHECK(network_thread_->IsCurrent());
  for (const auto& transport_cert_stats_pair : transport_cert_stats) {
    if (transport_cert_stats_pair.second.local) {
      ProduceCertificateStatsFromSSLCertificateStats(
          timestamp_us, *transport_cert_stats_pair.second.local.get(), report);
    }
    if (transport_cert_stats_pair.second.remote) {
      ProduceCertificateStatsFromSSLCertificateStats(
          timestamp_us, *transport_cert_stats_pair.second.remote.get(), report);
    }
  }
}

void RTCStatsCollector::ProduceCodecStats_n(
    int64_t timestamp_us, const TrackMediaInfoMap& track_media_info_map,
    RTCStatsReport* report) const {
  RTC_DCHECK(network_thread_->IsCurrent());
  // Audio
  if (track_media_info_map.voice_media_info()) {
    // Inbound
    for (const auto& pair :
         track_media_info_map.voice_media_info()->receive_codecs) {
      report->AddStats(CodecStatsFromRtpCodecParameters(
          timestamp_us, true, true, pair.second));
    }
    // Outbound
    for (const auto& pair :
         track_media_info_map.voice_media_info()->send_codecs) {
      report->AddStats(CodecStatsFromRtpCodecParameters(
          timestamp_us, false, true, pair.second));
    }
  }
  // Video
  if (track_media_info_map.video_media_info()) {
    // Inbound
    for (const auto& pair :
         track_media_info_map.video_media_info()->receive_codecs) {
      report->AddStats(CodecStatsFromRtpCodecParameters(
          timestamp_us, true, false, pair.second));
    }
    // Outbound
    for (const auto& pair :
         track_media_info_map.video_media_info()->send_codecs) {
      report->AddStats(CodecStatsFromRtpCodecParameters(
          timestamp_us, false, false, pair.second));
    }
  }
}

void RTCStatsCollector::ProduceDataChannelStats_s(
    int64_t timestamp_us, RTCStatsReport* report) const {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  for (const rtc::scoped_refptr<DataChannel>& data_channel :
       pc_->sctp_data_channels()) {
    std::unique_ptr<RTCDataChannelStats> data_channel_stats(
        new RTCDataChannelStats(
            "RTCDataChannel_" + rtc::ToString<>(data_channel->id()),
            timestamp_us));
    data_channel_stats->label = data_channel->label();
    data_channel_stats->protocol = data_channel->protocol();
    data_channel_stats->datachannelid = data_channel->id();
    data_channel_stats->state =
        DataStateToRTCDataChannelState(data_channel->state());
    data_channel_stats->messages_sent = data_channel->messages_sent();
    data_channel_stats->bytes_sent = data_channel->bytes_sent();
    data_channel_stats->messages_received = data_channel->messages_received();
    data_channel_stats->bytes_received = data_channel->bytes_received();
    report->AddStats(std::move(data_channel_stats));
  }
}

void RTCStatsCollector::ProduceIceCandidateAndPairStats_n(
    int64_t timestamp_us,
    const SessionStats& session_stats,
    const cricket::VideoMediaInfo* video_media_info,
    const Call::Stats& call_stats,
    RTCStatsReport* report) const {
  RTC_DCHECK(network_thread_->IsCurrent());
  for (const auto& transport_stats : session_stats.transport_stats) {
    for (const auto& channel_stats : transport_stats.second.channel_stats) {
      std::string transport_id = RTCTransportStatsIDFromTransportChannel(
          transport_stats.second.transport_name, channel_stats.component);
      for (const cricket::ConnectionInfo& info :
           channel_stats.connection_infos) {
        std::unique_ptr<RTCIceCandidatePairStats> candidate_pair_stats(
            new RTCIceCandidatePairStats(
                RTCIceCandidatePairStatsIDFromConnectionInfo(info),
                timestamp_us));

        candidate_pair_stats->transport_id = transport_id;
        // TODO(hbos): There could be other candidates that are not paired with
        // anything. We don't have a complete list. Local candidates come from
        // Port objects, and prflx candidates (both local and remote) are only
        // stored in candidate pairs. crbug.com/632723
        candidate_pair_stats->local_candidate_id = ProduceIceCandidateStats(
            timestamp_us, info.local_candidate, true, transport_id, report);
        candidate_pair_stats->remote_candidate_id = ProduceIceCandidateStats(
            timestamp_us, info.remote_candidate, false, transport_id, report);
        candidate_pair_stats->state =
            IceCandidatePairStateToRTCStatsIceCandidatePairState(info.state);
        candidate_pair_stats->priority = info.priority;
        candidate_pair_stats->nominated = info.nominated;
        // TODO(hbos): This writable is different than the spec. It goes to
        // false after a certain amount of time without a response passes.
        // crbug.com/633550
        candidate_pair_stats->writable = info.writable;
        candidate_pair_stats->bytes_sent =
            static_cast<uint64_t>(info.sent_total_bytes);
        candidate_pair_stats->bytes_received =
            static_cast<uint64_t>(info.recv_total_bytes);
        candidate_pair_stats->total_round_trip_time =
            static_cast<double>(info.total_round_trip_time_ms) /
            rtc::kNumMillisecsPerSec;
        if (info.current_round_trip_time_ms) {
          candidate_pair_stats->current_round_trip_time =
              static_cast<double>(*info.current_round_trip_time_ms) /
              rtc::kNumMillisecsPerSec;
        }
        if (info.best_connection) {
          // The bandwidth estimations we have are for the selected candidate
          // pair ("info.best_connection").
          RTC_DCHECK_GE(call_stats.send_bandwidth_bps, 0);
          RTC_DCHECK_GE(call_stats.recv_bandwidth_bps, 0);
          if (call_stats.send_bandwidth_bps > 0) {
            candidate_pair_stats->available_outgoing_bitrate =
                static_cast<double>(call_stats.send_bandwidth_bps);
          }
          if (call_stats.recv_bandwidth_bps > 0) {
            candidate_pair_stats->available_incoming_bitrate =
                static_cast<double>(call_stats.recv_bandwidth_bps);
          }
        }
        candidate_pair_stats->requests_received =
            static_cast<uint64_t>(info.recv_ping_requests);
        candidate_pair_stats->requests_sent = static_cast<uint64_t>(
            info.sent_ping_requests_before_first_response);
        candidate_pair_stats->responses_received =
            static_cast<uint64_t>(info.recv_ping_responses);
        candidate_pair_stats->responses_sent =
            static_cast<uint64_t>(info.sent_ping_responses);
        RTC_DCHECK_GE(info.sent_ping_requests_total,
                      info.sent_ping_requests_before_first_response);
        candidate_pair_stats->consent_requests_sent = static_cast<uint64_t>(
            info.sent_ping_requests_total -
            info.sent_ping_requests_before_first_response);

        report->AddStats(std::move(candidate_pair_stats));
      }
    }
  }
}

void RTCStatsCollector::ProduceMediaStreamAndTrackStats_s(
    int64_t timestamp_us, RTCStatsReport* report) const {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  RTC_DCHECK(track_media_info_map_);
  ProduceMediaStreamAndTrackStats(timestamp_us,
                                  *track_media_info_map_,
                                  pc_->local_streams(),
                                  true,
                                  report);
  ProduceMediaStreamAndTrackStats(timestamp_us,
                                  *track_media_info_map_,
                                  pc_->remote_streams(),
                                  false,
                                  report);
}

void RTCStatsCollector::ProducePeerConnectionStats_s(
    int64_t timestamp_us, RTCStatsReport* report) const {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  std::unique_ptr<RTCPeerConnectionStats> stats(
    new RTCPeerConnectionStats("RTCPeerConnection", timestamp_us));
  stats->data_channels_opened = internal_record_.data_channels_opened;
  stats->data_channels_closed = internal_record_.data_channels_closed;
  report->AddStats(std::move(stats));
}

void RTCStatsCollector::ProduceRTPStreamStats_n(
    int64_t timestamp_us, const SessionStats& session_stats,
    const TrackMediaInfoMap& track_media_info_map,
    RTCStatsReport* report) const {
  RTC_DCHECK(network_thread_->IsCurrent());

  // Audio
  if (track_media_info_map.voice_media_info()) {
    std::string transport_id = RTCTransportStatsIDFromBaseChannel(
        session_stats.proxy_to_transport, *pc_->voice_channel());
    RTC_DCHECK(!transport_id.empty());
    // Inbound
    for (const cricket::VoiceReceiverInfo& voice_receiver_info :
         track_media_info_map.voice_media_info()->receivers) {
      // TODO(nisse): SSRC == 0 currently means none. Delete check when that
      // is fixed.
      if (voice_receiver_info.ssrc() == 0)
        continue;
      std::unique_ptr<RTCInboundRTPStreamStats> inbound_audio(
          new RTCInboundRTPStreamStats(
              RTCInboundRTPStreamStatsIDFromSSRC(
                  true, voice_receiver_info.ssrc()),
              timestamp_us));
      SetInboundRTPStreamStatsFromVoiceReceiverInfo(
          voice_receiver_info, inbound_audio.get());
      rtc::scoped_refptr<AudioTrackInterface> audio_track =
          track_media_info_map_->GetAudioTrack(voice_receiver_info);
      if (audio_track) {
        RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
        inbound_audio->track_id =
            RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
                false,
                MediaStreamTrackInterface::kAudioKind,
                track_to_id_.find(audio_track.get())->second,
                voice_receiver_info.ssrc());
      }
      inbound_audio->transport_id = transport_id;
      report->AddStats(std::move(inbound_audio));
    }
    // Outbound
    for (const cricket::VoiceSenderInfo& voice_sender_info :
         track_media_info_map.voice_media_info()->senders) {
      // TODO(nisse): SSRC == 0 currently means none. Delete check when that
      // is fixed.
      if (voice_sender_info.ssrc() == 0)
        continue;
      std::unique_ptr<RTCOutboundRTPStreamStats> outbound_audio(
          new RTCOutboundRTPStreamStats(
              RTCOutboundRTPStreamStatsIDFromSSRC(
                  true, voice_sender_info.ssrc()),
              timestamp_us));
      SetOutboundRTPStreamStatsFromVoiceSenderInfo(
          voice_sender_info, outbound_audio.get());
      rtc::scoped_refptr<AudioTrackInterface> audio_track =
          track_media_info_map_->GetAudioTrack(voice_sender_info);
      if (audio_track) {
        RTC_DCHECK(track_to_id_.find(audio_track.get()) != track_to_id_.end());
        outbound_audio->track_id =
            RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
                true,
                MediaStreamTrackInterface::kAudioKind,
                track_to_id_.find(audio_track.get())->second,
                voice_sender_info.ssrc());
      }
      outbound_audio->transport_id = transport_id;
      report->AddStats(std::move(outbound_audio));
    }
  }
  // Video
  if (track_media_info_map.video_media_info()) {
    std::string transport_id = RTCTransportStatsIDFromBaseChannel(
        session_stats.proxy_to_transport, *pc_->video_channel());
    RTC_DCHECK(!transport_id.empty());
    // Inbound
    for (const cricket::VideoReceiverInfo& video_receiver_info :
         track_media_info_map.video_media_info()->receivers) {
      // TODO(nisse): SSRC == 0 currently means none. Delete check when that
      // is fixed.
      if (video_receiver_info.ssrc() == 0)
        continue;
      std::unique_ptr<RTCInboundRTPStreamStats> inbound_video(
          new RTCInboundRTPStreamStats(
              RTCInboundRTPStreamStatsIDFromSSRC(
                  false, video_receiver_info.ssrc()),
              timestamp_us));
      SetInboundRTPStreamStatsFromVideoReceiverInfo(
          video_receiver_info, inbound_video.get());
      rtc::scoped_refptr<VideoTrackInterface> video_track =
          track_media_info_map_->GetVideoTrack(video_receiver_info);
      if (video_track) {
        RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
        inbound_video->track_id =
            RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
                false,
                MediaStreamTrackInterface::kVideoKind,
                track_to_id_.find(video_track.get())->second,
                video_receiver_info.ssrc());
      }
      inbound_video->transport_id = transport_id;
      report->AddStats(std::move(inbound_video));
    }
    // Outbound
    for (const cricket::VideoSenderInfo& video_sender_info :
         track_media_info_map.video_media_info()->senders) {
      // TODO(nisse): SSRC == 0 currently means none. Delete check when that
      // is fixed.
      if (video_sender_info.ssrc() == 0)
        continue;
      std::unique_ptr<RTCOutboundRTPStreamStats> outbound_video(
          new RTCOutboundRTPStreamStats(
              RTCOutboundRTPStreamStatsIDFromSSRC(
                  false, video_sender_info.ssrc()),
              timestamp_us));
      SetOutboundRTPStreamStatsFromVideoSenderInfo(
          video_sender_info, outbound_video.get());
      rtc::scoped_refptr<VideoTrackInterface> video_track =
          track_media_info_map_->GetVideoTrack(video_sender_info);
      if (video_track) {
        RTC_DCHECK(track_to_id_.find(video_track.get()) != track_to_id_.end());
        outbound_video->track_id =
            RTCMediaStreamTrackStatsIDFromTrackKindIDAndSsrc(
                true,
                MediaStreamTrackInterface::kVideoKind,
                track_to_id_.find(video_track.get())->second,
                video_sender_info.ssrc());
      }
      outbound_video->transport_id = transport_id;
      report->AddStats(std::move(outbound_video));
    }
  }
}

void RTCStatsCollector::ProduceTransportStats_n(
    int64_t timestamp_us, const SessionStats& session_stats,
    const std::map<std::string, CertificateStatsPair>& transport_cert_stats,
    RTCStatsReport* report) const {
  RTC_DCHECK(network_thread_->IsCurrent());
  for (const auto& transport : session_stats.transport_stats) {
    // Get reference to RTCP channel, if it exists.
    std::string rtcp_transport_stats_id;
    for (const auto& channel_stats : transport.second.channel_stats) {
      if (channel_stats.component ==
          cricket::ICE_CANDIDATE_COMPONENT_RTCP) {
        rtcp_transport_stats_id = RTCTransportStatsIDFromTransportChannel(
            transport.second.transport_name, channel_stats.component);
        break;
      }
    }

    // Get reference to local and remote certificates of this transport, if they
    // exist.
    const auto& certificate_stats_it = transport_cert_stats.find(
        transport.second.transport_name);
    RTC_DCHECK(certificate_stats_it != transport_cert_stats.cend());
    std::string local_certificate_id;
    if (certificate_stats_it->second.local) {
      local_certificate_id = RTCCertificateIDFromFingerprint(
          certificate_stats_it->second.local->fingerprint);
    }
    std::string remote_certificate_id;
    if (certificate_stats_it->second.remote) {
      remote_certificate_id = RTCCertificateIDFromFingerprint(
          certificate_stats_it->second.remote->fingerprint);
    }

    // There is one transport stats for each channel.
    for (const auto& channel_stats : transport.second.channel_stats) {
      std::unique_ptr<RTCTransportStats> transport_stats(
          new RTCTransportStats(
              RTCTransportStatsIDFromTransportChannel(
                  transport.second.transport_name, channel_stats.component),
              timestamp_us));
      transport_stats->bytes_sent = 0;
      transport_stats->bytes_received = 0;
      transport_stats->dtls_state = DtlsTransportStateToRTCDtlsTransportState(
          channel_stats.dtls_state);
      for (const cricket::ConnectionInfo& info :
           channel_stats.connection_infos) {
        *transport_stats->bytes_sent += info.sent_total_bytes;
        *transport_stats->bytes_received += info.recv_total_bytes;
        if (info.best_connection) {
          transport_stats->selected_candidate_pair_id =
              RTCIceCandidatePairStatsIDFromConnectionInfo(info);
        }
      }
      if (channel_stats.component != cricket::ICE_CANDIDATE_COMPONENT_RTCP &&
          !rtcp_transport_stats_id.empty()) {
        transport_stats->rtcp_transport_stats_id = rtcp_transport_stats_id;
      }
      if (!local_certificate_id.empty())
        transport_stats->local_certificate_id = local_certificate_id;
      if (!remote_certificate_id.empty())
        transport_stats->remote_certificate_id = remote_certificate_id;
      report->AddStats(std::move(transport_stats));
    }
  }
}

std::map<std::string, RTCStatsCollector::CertificateStatsPair>
RTCStatsCollector::PrepareTransportCertificateStats_n(
    const SessionStats& session_stats) const {
  RTC_DCHECK(network_thread_->IsCurrent());
  std::map<std::string, CertificateStatsPair> transport_cert_stats;
  for (const auto& transport_stats : session_stats.transport_stats) {
    CertificateStatsPair certificate_stats_pair;
    rtc::scoped_refptr<rtc::RTCCertificate> local_certificate;
    if (pc_->GetLocalCertificate(transport_stats.second.transport_name,
                                 &local_certificate)) {
      certificate_stats_pair.local =
          local_certificate->ssl_certificate().GetStats();
    }
    std::unique_ptr<rtc::SSLCertificate> remote_certificate =
        pc_->GetRemoteSSLCertificate(transport_stats.second.transport_name);
    if (remote_certificate) {
      certificate_stats_pair.remote = remote_certificate->GetStats();
    }
    transport_cert_stats.insert(
        std::make_pair(transport_stats.second.transport_name,
                       std::move(certificate_stats_pair)));
  }
  return transport_cert_stats;
}

std::unique_ptr<TrackMediaInfoMap>
RTCStatsCollector::PrepareTrackMediaInfoMap_s() const {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  std::unique_ptr<cricket::VoiceMediaInfo> voice_media_info;
  if (pc_->voice_channel()) {
    voice_media_info.reset(new cricket::VoiceMediaInfo());
    if (!pc_->voice_channel()->GetStats(voice_media_info.get())) {
      voice_media_info.reset();
    }
  }
  std::unique_ptr<cricket::VideoMediaInfo> video_media_info;
  if (pc_->video_channel()) {
    video_media_info.reset(new cricket::VideoMediaInfo());
    if (!pc_->video_channel()->GetStats(video_media_info.get())) {
      video_media_info.reset();
    }
  }
  std::unique_ptr<TrackMediaInfoMap> track_media_info_map(
      new TrackMediaInfoMap(std::move(voice_media_info),
                            std::move(video_media_info),
                            pc_->GetSenders(),
                            pc_->GetReceivers()));
  return track_media_info_map;
}

std::map<MediaStreamTrackInterface*, std::string>
RTCStatsCollector::PrepareTrackToID_s() const {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  std::map<MediaStreamTrackInterface*, std::string> track_to_id;
  for (auto sender : pc_->GetSenders()) {
    auto track = sender->track();
    if (track)
      track_to_id[track.get()] = track->id();
  }
  for (auto receiver : pc_->GetReceivers()) {
    auto track = receiver->track();
    if (track)
      track_to_id[track.get()] = track->id();
  }
  return track_to_id;
}

void RTCStatsCollector::OnDataChannelCreated(DataChannel* channel) {
  channel->SignalOpened.connect(this, &RTCStatsCollector::OnDataChannelOpened);
  channel->SignalClosed.connect(this, &RTCStatsCollector::OnDataChannelClosed);
}

void RTCStatsCollector::OnDataChannelOpened(DataChannel* channel) {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  bool result = internal_record_.opened_data_channels.insert(
      reinterpret_cast<uintptr_t>(channel)).second;
  ++internal_record_.data_channels_opened;
  RTC_DCHECK(result);
}

void RTCStatsCollector::OnDataChannelClosed(DataChannel* channel) {
  RTC_DCHECK(signaling_thread_->IsCurrent());
  // Only channels that have been fully opened (and have increased the
  // |data_channels_opened_| counter) increase the closed counter.
  if (internal_record_.opened_data_channels.erase(
          reinterpret_cast<uintptr_t>(channel))) {
    ++internal_record_.data_channels_closed;
  }
}

const char* CandidateTypeToRTCIceCandidateTypeForTesting(
    const std::string& type) {
  return CandidateTypeToRTCIceCandidateType(type);
}

const char* DataStateToRTCDataChannelStateForTesting(
    DataChannelInterface::DataState state) {
  return DataStateToRTCDataChannelState(state);
}

}  // namespace webrtc
