/*
 *  Copyright 2019 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.
 */
#ifndef LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_H_
#define LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_H_

#include <iterator>
#include <limits>
#include <map>
#include <set>
#include <string>
#include <utility>  // pair
#include <vector>

#include "absl/base/attributes.h"
#include "api/rtc_event_log/rtc_event_log.h"
#include "call/video_receive_stream.h"
#include "call/video_send_stream.h"
#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_transport_state.h"
#include "logging/rtc_event_log/events/rtc_event_dtls_writable_state.h"
#include "logging/rtc_event_log/events/rtc_event_frame_decoded.h"
#include "logging/rtc_event_log/events/rtc_event_generic_ack_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_received.h"
#include "logging/rtc_event_log/events/rtc_event_generic_packet_sent.h"
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair.h"
#include "logging/rtc_event_log/events/rtc_event_ice_candidate_pair_config.h"
#include "logging/rtc_event_log/events/rtc_event_probe_cluster_created.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_failure.h"
#include "logging/rtc_event_log/events/rtc_event_probe_result_success.h"
#include "logging/rtc_event_log/events/rtc_event_remote_estimate.h"
#include "logging/rtc_event_log/events/rtc_event_route_change.h"
#include "logging/rtc_event_log/events/rtc_event_video_receive_stream_config.h"
#include "logging/rtc_event_log/events/rtc_event_video_send_stream_config.h"
#include "logging/rtc_event_log/logged_events.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"
#include "rtc_base/ignore_wundef.h"

// Files generated at build-time by the protobuf compiler.
RTC_PUSH_IGNORING_WUNDEF()
#ifdef WEBRTC_ANDROID_PLATFORM_BUILD
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log.pb.h"
#include "external/webrtc/webrtc/logging/rtc_event_log/rtc_event_log2.pb.h"
#else
#include "logging/rtc_event_log/rtc_event_log.pb.h"
#include "logging/rtc_event_log/rtc_event_log2.pb.h"
#endif
RTC_POP_IGNORING_WUNDEF()

namespace webrtc {

enum PacketDirection { kIncomingPacket = 0, kOutgoingPacket };

// This class is used to process lists of LoggedRtpPacketIncoming
// and LoggedRtpPacketOutgoing without duplicating the code.
// TODO(terelius): Remove this class. Instead use e.g. a vector of pointers
// to LoggedRtpPacket or templatize the surrounding code.
template <typename T>
class DereferencingVector {
 public:
  template <bool IsConst>
  class DereferencingIterator {
   public:
    // Standard iterator traits.
    using difference_type = std::ptrdiff_t;
    using value_type = T;
    using pointer = typename std::conditional_t<IsConst, const T*, T*>;
    using reference = typename std::conditional_t<IsConst, const T&, T&>;
    using iterator_category = std::bidirectional_iterator_tag;

    using representation =
        typename std::conditional_t<IsConst, const T* const*, T**>;

    explicit DereferencingIterator(representation ptr) : ptr_(ptr) {}

    DereferencingIterator(const DereferencingIterator& other)
        : ptr_(other.ptr_) {}
    DereferencingIterator(const DereferencingIterator&& other)
        : ptr_(other.ptr_) {}
    ~DereferencingIterator() = default;

    DereferencingIterator& operator=(const DereferencingIterator& other) {
      ptr_ = other.ptr_;
      return *this;
    }
    DereferencingIterator& operator=(const DereferencingIterator&& other) {
      ptr_ = other.ptr_;
      return *this;
    }

    bool operator==(const DereferencingIterator& other) const {
      return ptr_ == other.ptr_;
    }
    bool operator!=(const DereferencingIterator& other) const {
      return ptr_ != other.ptr_;
    }

    DereferencingIterator& operator++() {
      ++ptr_;
      return *this;
    }
    DereferencingIterator& operator--() {
      --ptr_;
      return *this;
    }
    DereferencingIterator operator++(int) {
      DereferencingIterator iter_copy(ptr_);
      ++ptr_;
      return iter_copy;
    }
    DereferencingIterator operator--(int) {
      DereferencingIterator iter_copy(ptr_);
      --ptr_;
      return iter_copy;
    }

    template <bool _IsConst = IsConst>
    std::enable_if_t<!_IsConst, reference> operator*() {
      return **ptr_;
    }

    template <bool _IsConst = IsConst>
    std::enable_if_t<_IsConst, reference> operator*() const {
      return **ptr_;
    }

    template <bool _IsConst = IsConst>
    std::enable_if_t<!_IsConst, pointer> operator->() {
      return *ptr_;
    }

    template <bool _IsConst = IsConst>
    std::enable_if_t<_IsConst, pointer> operator->() const {
      return *ptr_;
    }

   private:
    representation ptr_;
  };

  using value_type = T;
  using reference = value_type&;
  using const_reference = const value_type&;

  using iterator = DereferencingIterator<false>;
  using const_iterator = DereferencingIterator<true>;
  using reverse_iterator = std::reverse_iterator<iterator>;
  using const_reverse_iterator = std::reverse_iterator<const_iterator>;

  iterator begin() { return iterator(elems_.data()); }
  iterator end() { return iterator(elems_.data() + elems_.size()); }

  const_iterator begin() const { return const_iterator(elems_.data()); }
  const_iterator end() const {
    return const_iterator(elems_.data() + elems_.size());
  }

  reverse_iterator rbegin() { return reverse_iterator(end()); }
  reverse_iterator rend() { return reverse_iterator(begin()); }

  const_reverse_iterator rbegin() const {
    return const_reverse_iterator(end());
  }
  const_reverse_iterator rend() const {
    return const_reverse_iterator(begin());
  }

  size_t size() const { return elems_.size(); }

  bool empty() const { return elems_.empty(); }

  T& operator[](size_t i) {
    RTC_DCHECK_LT(i, elems_.size());
    return *elems_[i];
  }

  const T& operator[](size_t i) const {
    RTC_DCHECK_LT(i, elems_.size());
    return *elems_[i];
  }

  void push_back(T* elem) {
    RTC_DCHECK(elem != nullptr);
    elems_.push_back(elem);
  }

 private:
  std::vector<T*> elems_;
};

// Conversion functions for version 2 of the wire format.
BandwidthUsage GetRuntimeDetectorState(
    rtclog2::DelayBasedBweUpdates::DetectorState detector_state);

ProbeFailureReason GetRuntimeProbeFailureReason(
    rtclog2::BweProbeResultFailure::FailureReason failure);

DtlsTransportState GetRuntimeDtlsTransportState(
    rtclog2::DtlsTransportStateEvent::DtlsTransportState state);

IceCandidatePairConfigType GetRuntimeIceCandidatePairConfigType(
    rtclog2::IceCandidatePairConfig::IceCandidatePairConfigType type);

IceCandidateType GetRuntimeIceCandidateType(
    rtclog2::IceCandidatePairConfig::IceCandidateType type);

IceCandidatePairProtocol GetRuntimeIceCandidatePairProtocol(
    rtclog2::IceCandidatePairConfig::Protocol protocol);

IceCandidatePairAddressFamily GetRuntimeIceCandidatePairAddressFamily(
    rtclog2::IceCandidatePairConfig::AddressFamily address_family);

IceCandidateNetworkType GetRuntimeIceCandidateNetworkType(
    rtclog2::IceCandidatePairConfig::NetworkType network_type);

IceCandidatePairEventType GetRuntimeIceCandidatePairEventType(
    rtclog2::IceCandidatePairEvent::IceCandidatePairEventType type);

std::vector<RtpExtension> GetRuntimeRtpHeaderExtensionConfig(
    const rtclog2::RtpHeaderExtensionConfig& proto_header_extensions);
// End of conversion functions.

class ParsedRtcEventLog {
 public:
  enum class MediaType { ANY, AUDIO, VIDEO, DATA };
  enum class UnconfiguredHeaderExtensions {
    kDontParse,
    kAttemptWebrtcDefaultConfig
  };
  class ParseStatus {
   public:
    static ParseStatus Success() { return ParseStatus(); }
    static ParseStatus Error(std::string error, std::string file, int line) {
      return ParseStatus(error, file, line);
    }

    bool ok() const { return error_.empty() && file_.empty() && line_ == 0; }
    std::string message() const {
      return error_ + " failed at " + file_ + " line " + std::to_string(line_);
    }

    ABSL_DEPRECATED("Use ok() instead") operator bool() const { return ok(); }

   private:
    ParseStatus() : error_(), file_(), line_(0) {}
    ParseStatus(std::string error, std::string file, int line)
        : error_(error), file_(file), line_(line) {}
    std::string error_;
    std::string file_;
    int line_;
  };

  template <typename T>
  class ParseStatusOr {
   public:
    ParseStatusOr(const ParseStatus& error)  // NOLINT
        : status_(error), value_() {}
    ParseStatusOr(const T& value)  // NOLINT
        : status_(ParseStatus::Success()), value_(value) {}
    bool ok() const { return status_.ok(); }
    const T& value() const& {
      RTC_DCHECK(status_.ok());
      return value_;
    }
    std::string message() const { return status_.message(); }
    const ParseStatus& status() const { return status_; }

   private:
    ParseStatus status_;
    T value_;
  };

  struct LoggedRtpStreamIncoming {
    LoggedRtpStreamIncoming();
    LoggedRtpStreamIncoming(const LoggedRtpStreamIncoming&);
    ~LoggedRtpStreamIncoming();
    uint32_t ssrc;
    std::vector<LoggedRtpPacketIncoming> incoming_packets;
  };

  struct LoggedRtpStreamOutgoing {
    LoggedRtpStreamOutgoing();
    LoggedRtpStreamOutgoing(const LoggedRtpStreamOutgoing&);
    ~LoggedRtpStreamOutgoing();
    uint32_t ssrc;
    std::vector<LoggedRtpPacketOutgoing> outgoing_packets;
  };

  struct LoggedRtpStreamView {
    LoggedRtpStreamView(uint32_t ssrc,
                        const std::vector<LoggedRtpPacketIncoming>& packets);
    LoggedRtpStreamView(uint32_t ssrc,
                        const std::vector<LoggedRtpPacketOutgoing>& packets);
    LoggedRtpStreamView(const LoggedRtpStreamView&);
    uint32_t ssrc;
    DereferencingVector<const LoggedRtpPacket> packet_view;
  };

  class LogSegment {
   public:
    LogSegment(int64_t start_time_us, int64_t stop_time_us)
        : start_time_us_(start_time_us), stop_time_us_(stop_time_us) {}
    int64_t start_time_ms() const { return start_time_us_ / 1000; }
    int64_t start_time_us() const { return start_time_us_; }
    int64_t stop_time_ms() const { return stop_time_us_ / 1000; }
    int64_t stop_time_us() const { return stop_time_us_; }

   private:
    int64_t start_time_us_;
    int64_t stop_time_us_;
  };

  static webrtc::RtpHeaderExtensionMap GetDefaultHeaderExtensionMap();

  explicit ParsedRtcEventLog(
      UnconfiguredHeaderExtensions parse_unconfigured_header_extensions =
          UnconfiguredHeaderExtensions::kDontParse,
      bool allow_incomplete_log = false);

  ~ParsedRtcEventLog();

  // Clears previously parsed events and resets the ParsedRtcEventLogNew to an
  // empty state.
  void Clear();

  // Reads an RtcEventLog file and returns success if parsing was successful.
  ParseStatus ParseFile(const std::string& file_name);

  // Reads an RtcEventLog from a string and returns success if successful.
  ParseStatus ParseString(const std::string& s);

  // Reads an RtcEventLog from an string and returns success if successful.
  ParseStatus ParseStream(const std::string& s);

  MediaType GetMediaType(uint32_t ssrc, PacketDirection direction) const;

  // Configured SSRCs.
  const std::set<uint32_t>& incoming_rtx_ssrcs() const {
    return incoming_rtx_ssrcs_;
  }

  const std::set<uint32_t>& incoming_video_ssrcs() const {
    return incoming_video_ssrcs_;
  }

  const std::set<uint32_t>& incoming_audio_ssrcs() const {
    return incoming_audio_ssrcs_;
  }

  const std::set<uint32_t>& outgoing_rtx_ssrcs() const {
    return outgoing_rtx_ssrcs_;
  }

  const std::set<uint32_t>& outgoing_video_ssrcs() const {
    return outgoing_video_ssrcs_;
  }

  const std::set<uint32_t>& outgoing_audio_ssrcs() const {
    return outgoing_audio_ssrcs_;
  }

  // Stream configurations.
  const std::vector<LoggedAudioRecvConfig>& audio_recv_configs() const {
    return audio_recv_configs_;
  }

  const std::vector<LoggedAudioSendConfig>& audio_send_configs() const {
    return audio_send_configs_;
  }

  const std::vector<LoggedVideoRecvConfig>& video_recv_configs() const {
    return video_recv_configs_;
  }

  const std::vector<LoggedVideoSendConfig>& video_send_configs() const {
    return video_send_configs_;
  }

  // Beginning and end of log segments.
  const std::vector<LoggedStartEvent>& start_log_events() const {
    return start_log_events_;
  }

  const std::vector<LoggedStopEvent>& stop_log_events() const {
    return stop_log_events_;
  }

  const std::vector<LoggedAlrStateEvent>& alr_state_events() const {
    return alr_state_events_;
  }

  // Audio
  const std::map<uint32_t, std::vector<LoggedAudioPlayoutEvent>>&
  audio_playout_events() const {
    return audio_playout_events_;
  }

  const std::vector<LoggedAudioNetworkAdaptationEvent>&
  audio_network_adaptation_events() const {
    return audio_network_adaptation_events_;
  }

  // Bandwidth estimation
  const std::vector<LoggedBweProbeClusterCreatedEvent>&
  bwe_probe_cluster_created_events() const {
    return bwe_probe_cluster_created_events_;
  }

  const std::vector<LoggedBweProbeFailureEvent>& bwe_probe_failure_events()
      const {
    return bwe_probe_failure_events_;
  }

  const std::vector<LoggedBweProbeSuccessEvent>& bwe_probe_success_events()
      const {
    return bwe_probe_success_events_;
  }

  const std::vector<LoggedBweDelayBasedUpdate>& bwe_delay_updates() const {
    return bwe_delay_updates_;
  }

  const std::vector<LoggedBweLossBasedUpdate>& bwe_loss_updates() const {
    return bwe_loss_updates_;
  }

  // DTLS
  const std::vector<LoggedDtlsTransportState>& dtls_transport_states() const {
    return dtls_transport_states_;
  }

  const std::vector<LoggedDtlsWritableState>& dtls_writable_states() const {
    return dtls_writable_states_;
  }

  // ICE events
  const std::vector<LoggedIceCandidatePairConfig>& ice_candidate_pair_configs()
      const {
    return ice_candidate_pair_configs_;
  }

  const std::vector<LoggedIceCandidatePairEvent>& ice_candidate_pair_events()
      const {
    return ice_candidate_pair_events_;
  }

  const std::vector<LoggedRouteChangeEvent>& route_change_events() const {
    return route_change_events_;
  }

  const std::vector<LoggedRemoteEstimateEvent>& remote_estimate_events() const {
    return remote_estimate_events_;
  }

  // RTP
  const std::vector<LoggedRtpStreamIncoming>& incoming_rtp_packets_by_ssrc()
      const {
    return incoming_rtp_packets_by_ssrc_;
  }

  const std::vector<LoggedRtpStreamOutgoing>& outgoing_rtp_packets_by_ssrc()
      const {
    return outgoing_rtp_packets_by_ssrc_;
  }

  const std::vector<LoggedRtpStreamView>& rtp_packets_by_ssrc(
      PacketDirection direction) const {
    if (direction == kIncomingPacket)
      return incoming_rtp_packet_views_by_ssrc_;
    else
      return outgoing_rtp_packet_views_by_ssrc_;
  }

  // RTCP
  const std::vector<LoggedRtcpPacketIncoming>& incoming_rtcp_packets() const {
    return incoming_rtcp_packets_;
  }

  const std::vector<LoggedRtcpPacketOutgoing>& outgoing_rtcp_packets() const {
    return outgoing_rtcp_packets_;
  }

  const std::vector<LoggedRtcpPacketReceiverReport>& receiver_reports(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_rr_;
    } else {
      return outgoing_rr_;
    }
  }

  const std::vector<LoggedRtcpPacketSenderReport>& sender_reports(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_sr_;
    } else {
      return outgoing_sr_;
    }
  }

  const std::vector<LoggedRtcpPacketExtendedReports>& extended_reports(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_xr_;
    } else {
      return outgoing_xr_;
    }
  }

  const std::vector<LoggedRtcpPacketNack>& nacks(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_nack_;
    } else {
      return outgoing_nack_;
    }
  }

  const std::vector<LoggedRtcpPacketRemb>& rembs(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_remb_;
    } else {
      return outgoing_remb_;
    }
  }

  const std::vector<LoggedRtcpPacketFir>& firs(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_fir_;
    } else {
      return outgoing_fir_;
    }
  }

  const std::vector<LoggedRtcpPacketPli>& plis(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_pli_;
    } else {
      return outgoing_pli_;
    }
  }

  const std::vector<LoggedRtcpPacketBye>& byes(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_bye_;
    } else {
      return outgoing_bye_;
    }
  }

  const std::vector<LoggedRtcpPacketTransportFeedback>& transport_feedbacks(
      PacketDirection direction) const {
    if (direction == kIncomingPacket) {
      return incoming_transport_feedback_;
    } else {
      return outgoing_transport_feedback_;
    }
  }

  const std::vector<LoggedRtcpPacketLossNotification>& loss_notifications(
      PacketDirection direction) {
    if (direction == kIncomingPacket) {
      return incoming_loss_notification_;
    } else {
      return outgoing_loss_notification_;
    }
  }

  const std::vector<LoggedGenericPacketReceived>& generic_packets_received()
      const {
    return generic_packets_received_;
  }
  const std::vector<LoggedGenericPacketSent>& generic_packets_sent() const {
    return generic_packets_sent_;
  }

  const std::vector<LoggedGenericAckReceived>& generic_acks_received() const {
    return generic_acks_received_;
  }

  // Media
  const std::map<uint32_t, std::vector<LoggedFrameDecoded>>& decoded_frames()
      const {
    return decoded_frames_;
  }

  int64_t first_timestamp() const { return first_timestamp_; }
  int64_t last_timestamp() const { return last_timestamp_; }

  const LogSegment& first_log_segment() const { return first_log_segment_; }

  std::vector<LoggedPacketInfo> GetPacketInfos(PacketDirection direction) const;
  std::vector<LoggedPacketInfo> GetIncomingPacketInfos() const {
    return GetPacketInfos(kIncomingPacket);
  }
  std::vector<LoggedPacketInfo> GetOutgoingPacketInfos() const {
    return GetPacketInfos(kOutgoingPacket);
  }
  std::vector<LoggedIceCandidatePairConfig> GetIceCandidates() const;
  std::vector<LoggedIceEvent> GetIceEvents() const;

  std::vector<InferredRouteChangeEvent> GetRouteChanges() const;

 private:
  ABSL_MUST_USE_RESULT ParseStatus ParseStreamInternal(absl::string_view s);

  ABSL_MUST_USE_RESULT ParseStatus
  StoreParsedLegacyEvent(const rtclog::Event& event);

  template <typename T>
  void StoreFirstAndLastTimestamp(const std::vector<T>& v);

  // Reads the header, direction, header length and packet length from the RTP
  // event at |index|, and stores the values in the corresponding output
  // parameters. Each output parameter can be set to nullptr if that value
  // isn't needed.
  // NB: The header must have space for at least IP_PACKET_SIZE bytes.
  ParseStatus GetRtpHeader(const rtclog::Event& event,
                           PacketDirection* incoming,
                           uint8_t* header,
                           size_t* header_length,
                           size_t* total_length,
                           int* probe_cluster_id) const;

  // Returns: a pointer to a header extensions map acquired from parsing
  // corresponding Audio/Video Sender/Receiver config events.
  // Warning: if the same SSRC is reused by both video and audio streams during
  // call, extensions maps may be incorrect (the last one would be returned).
  const RtpHeaderExtensionMap* GetRtpHeaderExtensionMap(
      PacketDirection direction,
      uint32_t ssrc);

  // Reads packet, direction and packet length from the RTCP event at |index|,
  // and stores the values in the corresponding output parameters.
  // Each output parameter can be set to nullptr if that value isn't needed.
  // NB: The packet must have space for at least IP_PACKET_SIZE bytes.
  ParseStatus GetRtcpPacket(const rtclog::Event& event,
                            PacketDirection* incoming,
                            std::vector<uint8_t>* packet) const;

  ParseStatusOr<rtclog::StreamConfig> GetVideoReceiveConfig(
      const rtclog::Event& event) const;
  ParseStatusOr<rtclog::StreamConfig> GetVideoSendConfig(
      const rtclog::Event& event) const;
  ParseStatusOr<rtclog::StreamConfig> GetAudioReceiveConfig(
      const rtclog::Event& event) const;
  ParseStatusOr<rtclog::StreamConfig> GetAudioSendConfig(
      const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedAudioPlayoutEvent> GetAudioPlayout(
      const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedBweLossBasedUpdate>
  GetLossBasedBweUpdate(const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedBweDelayBasedUpdate>
  GetDelayBasedBweUpdate(const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedAudioNetworkAdaptationEvent>
  GetAudioNetworkAdaptation(const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeClusterCreatedEvent>
  GetBweProbeClusterCreated(const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeFailureEvent>
  GetBweProbeFailure(const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedBweProbeSuccessEvent>
  GetBweProbeSuccess(const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedAlrStateEvent> GetAlrState(
      const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairConfig>
  GetIceCandidatePairConfig(const rtclog::Event& event) const;

  ParsedRtcEventLog::ParseStatusOr<LoggedIceCandidatePairEvent>
  GetIceCandidatePairEvent(const rtclog::Event& event) const;

  // Parsing functions for new format.
  ParseStatus StoreAlrStateEvent(const rtclog2::AlrState& proto);
  ParseStatus StoreAudioNetworkAdaptationEvent(
      const rtclog2::AudioNetworkAdaptations& proto);
  ParseStatus StoreAudioPlayoutEvent(const rtclog2::AudioPlayoutEvents& proto);
  ParseStatus StoreAudioRecvConfig(const rtclog2::AudioRecvStreamConfig& proto);
  ParseStatus StoreAudioSendConfig(const rtclog2::AudioSendStreamConfig& proto);
  ParseStatus StoreBweDelayBasedUpdate(
      const rtclog2::DelayBasedBweUpdates& proto);
  ParseStatus StoreBweLossBasedUpdate(
      const rtclog2::LossBasedBweUpdates& proto);
  ParseStatus StoreBweProbeClusterCreated(
      const rtclog2::BweProbeCluster& proto);
  ParseStatus StoreBweProbeFailureEvent(
      const rtclog2::BweProbeResultFailure& proto);
  ParseStatus StoreBweProbeSuccessEvent(
      const rtclog2::BweProbeResultSuccess& proto);
  ParseStatus StoreDtlsTransportState(
      const rtclog2::DtlsTransportStateEvent& proto);
  ParseStatus StoreDtlsWritableState(const rtclog2::DtlsWritableState& proto);
  ParsedRtcEventLog::ParseStatus StoreFrameDecodedEvents(
      const rtclog2::FrameDecodedEvents& proto);
  ParseStatus StoreGenericAckReceivedEvent(
      const rtclog2::GenericAckReceived& proto);
  ParseStatus StoreGenericPacketReceivedEvent(
      const rtclog2::GenericPacketReceived& proto);
  ParseStatus StoreGenericPacketSentEvent(
      const rtclog2::GenericPacketSent& proto);
  ParseStatus StoreIceCandidateEvent(
      const rtclog2::IceCandidatePairEvent& proto);
  ParseStatus StoreIceCandidatePairConfig(
      const rtclog2::IceCandidatePairConfig& proto);
  ParseStatus StoreIncomingRtcpPackets(
      const rtclog2::IncomingRtcpPackets& proto);
  ParseStatus StoreIncomingRtpPackets(const rtclog2::IncomingRtpPackets& proto);
  ParseStatus StoreOutgoingRtcpPackets(
      const rtclog2::OutgoingRtcpPackets& proto);
  ParseStatus StoreOutgoingRtpPackets(const rtclog2::OutgoingRtpPackets& proto);
  ParseStatus StoreParsedNewFormatEvent(const rtclog2::EventStream& event);
  ParseStatus StoreRouteChangeEvent(const rtclog2::RouteChange& proto);
  ParseStatus StoreRemoteEstimateEvent(const rtclog2::RemoteEstimates& proto);
  ParseStatus StoreStartEvent(const rtclog2::BeginLogEvent& proto);
  ParseStatus StoreStopEvent(const rtclog2::EndLogEvent& proto);
  ParseStatus StoreVideoRecvConfig(const rtclog2::VideoRecvStreamConfig& proto);
  ParseStatus StoreVideoSendConfig(const rtclog2::VideoSendStreamConfig& proto);
  // End of new parsing functions.

  struct Stream {
    Stream(uint32_t ssrc,
           MediaType media_type,
           PacketDirection direction,
           webrtc::RtpHeaderExtensionMap map)
        : ssrc(ssrc),
          media_type(media_type),
          direction(direction),
          rtp_extensions_map(map) {}
    uint32_t ssrc;
    MediaType media_type;
    PacketDirection direction;
    webrtc::RtpHeaderExtensionMap rtp_extensions_map;
  };

  const UnconfiguredHeaderExtensions parse_unconfigured_header_extensions_;
  const bool allow_incomplete_logs_;

  // Make a default extension map for streams without configuration information.
  // TODO(ivoc): Once configuration of audio streams is stored in the event log,
  //             this can be removed. Tracking bug: webrtc:6399
  RtpHeaderExtensionMap default_extension_map_;

  // Tracks what each stream is configured for. Note that a single SSRC can be
  // in several sets. For example, the SSRC used for sending video over RTX
  // will appear in both video_ssrcs_ and rtx_ssrcs_. In the unlikely case that
  // an SSRC is reconfigured to a different media type mid-call, it will also
  // appear in multiple sets.
  std::set<uint32_t> incoming_rtx_ssrcs_;
  std::set<uint32_t> incoming_video_ssrcs_;
  std::set<uint32_t> incoming_audio_ssrcs_;
  std::set<uint32_t> outgoing_rtx_ssrcs_;
  std::set<uint32_t> outgoing_video_ssrcs_;
  std::set<uint32_t> outgoing_audio_ssrcs_;

  // Maps an SSRC to the parsed  RTP headers in that stream. Header extensions
  // are parsed if the stream has been configured. This is only used for
  // grouping the events by SSRC during parsing; the events are moved to
  // incoming_rtp_packets_by_ssrc_ once the parsing is done.
  std::map<uint32_t, std::vector<LoggedRtpPacketIncoming>>
      incoming_rtp_packets_map_;
  std::map<uint32_t, std::vector<LoggedRtpPacketOutgoing>>
      outgoing_rtp_packets_map_;

  // RTP headers.
  std::vector<LoggedRtpStreamIncoming> incoming_rtp_packets_by_ssrc_;
  std::vector<LoggedRtpStreamOutgoing> outgoing_rtp_packets_by_ssrc_;
  std::vector<LoggedRtpStreamView> incoming_rtp_packet_views_by_ssrc_;
  std::vector<LoggedRtpStreamView> outgoing_rtp_packet_views_by_ssrc_;

  // Raw RTCP packets.
  std::vector<LoggedRtcpPacketIncoming> incoming_rtcp_packets_;
  std::vector<LoggedRtcpPacketOutgoing> outgoing_rtcp_packets_;

  // Parsed RTCP messages. Currently not separated based on SSRC.
  std::vector<LoggedRtcpPacketReceiverReport> incoming_rr_;
  std::vector<LoggedRtcpPacketReceiverReport> outgoing_rr_;
  std::vector<LoggedRtcpPacketSenderReport> incoming_sr_;
  std::vector<LoggedRtcpPacketSenderReport> outgoing_sr_;
  std::vector<LoggedRtcpPacketExtendedReports> incoming_xr_;
  std::vector<LoggedRtcpPacketExtendedReports> outgoing_xr_;
  std::vector<LoggedRtcpPacketNack> incoming_nack_;
  std::vector<LoggedRtcpPacketNack> outgoing_nack_;
  std::vector<LoggedRtcpPacketRemb> incoming_remb_;
  std::vector<LoggedRtcpPacketRemb> outgoing_remb_;
  std::vector<LoggedRtcpPacketFir> incoming_fir_;
  std::vector<LoggedRtcpPacketFir> outgoing_fir_;
  std::vector<LoggedRtcpPacketPli> incoming_pli_;
  std::vector<LoggedRtcpPacketPli> outgoing_pli_;
  std::vector<LoggedRtcpPacketBye> incoming_bye_;
  std::vector<LoggedRtcpPacketBye> outgoing_bye_;
  std::vector<LoggedRtcpPacketTransportFeedback> incoming_transport_feedback_;
  std::vector<LoggedRtcpPacketTransportFeedback> outgoing_transport_feedback_;
  std::vector<LoggedRtcpPacketLossNotification> incoming_loss_notification_;
  std::vector<LoggedRtcpPacketLossNotification> outgoing_loss_notification_;

  std::vector<LoggedStartEvent> start_log_events_;
  std::vector<LoggedStopEvent> stop_log_events_;

  std::vector<LoggedAlrStateEvent> alr_state_events_;

  std::map<uint32_t, std::vector<LoggedAudioPlayoutEvent>>
      audio_playout_events_;

  std::vector<LoggedAudioNetworkAdaptationEvent>
      audio_network_adaptation_events_;

  std::vector<LoggedBweProbeClusterCreatedEvent>
      bwe_probe_cluster_created_events_;

  std::vector<LoggedBweProbeFailureEvent> bwe_probe_failure_events_;
  std::vector<LoggedBweProbeSuccessEvent> bwe_probe_success_events_;

  std::vector<LoggedBweDelayBasedUpdate> bwe_delay_updates_;
  std::vector<LoggedBweLossBasedUpdate> bwe_loss_updates_;

  std::vector<LoggedDtlsTransportState> dtls_transport_states_;
  std::vector<LoggedDtlsWritableState> dtls_writable_states_;

  std::map<uint32_t, std::vector<LoggedFrameDecoded>> decoded_frames_;

  std::vector<LoggedIceCandidatePairConfig> ice_candidate_pair_configs_;
  std::vector<LoggedIceCandidatePairEvent> ice_candidate_pair_events_;

  std::vector<LoggedAudioRecvConfig> audio_recv_configs_;
  std::vector<LoggedAudioSendConfig> audio_send_configs_;
  std::vector<LoggedVideoRecvConfig> video_recv_configs_;
  std::vector<LoggedVideoSendConfig> video_send_configs_;

  std::vector<LoggedGenericPacketReceived> generic_packets_received_;
  std::vector<LoggedGenericPacketSent> generic_packets_sent_;
  std::vector<LoggedGenericAckReceived> generic_acks_received_;

  std::vector<LoggedRouteChangeEvent> route_change_events_;
  std::vector<LoggedRemoteEstimateEvent> remote_estimate_events_;

  std::vector<uint8_t> last_incoming_rtcp_packet_;

  int64_t first_timestamp_;
  int64_t last_timestamp_;

  LogSegment first_log_segment_ =
      LogSegment(0, std::numeric_limits<int64_t>::max());

  // The extension maps are mutable to allow us to insert the default
  // configuration when parsing an RTP header for an unconfigured stream.
  // TODO(terelius): This is only used for the legacy format. Remove once we've
  // fully transitioned to the new format.
  mutable std::map<uint32_t, webrtc::RtpHeaderExtensionMap>
      incoming_rtp_extensions_maps_;
  mutable std::map<uint32_t, webrtc::RtpHeaderExtensionMap>
      outgoing_rtp_extensions_maps_;
};

struct MatchedSendArrivalTimes {
  static constexpr int64_t kNotReceived = -1;

  MatchedSendArrivalTimes(int64_t fb, int64_t tx, int64_t rx, int64_t ps)
      : feedback_arrival_time_ms(fb),
        send_time_ms(tx),
        arrival_time_ms(rx),
        payload_size(ps) {}

  int64_t feedback_arrival_time_ms;
  int64_t send_time_ms;
  int64_t arrival_time_ms;  // kNotReceived for lost packets.
  int64_t payload_size;
};
const std::vector<MatchedSendArrivalTimes> GetNetworkTrace(
    const ParsedRtcEventLog& parsed_log);

}  // namespace webrtc

#endif  // LOGGING_RTC_EVENT_LOG_RTC_EVENT_LOG_PARSER_H_
