/*
 *  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 <vector>

#include "absl/base/attributes.h"
#include "absl/strings/string_view.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/logged_rtp_rtcp.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_begin_log.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_end_log.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_neteq_set_minimum_delay.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_rtcp_packet_incoming.h"
#include "logging/rtc_event_log/events/rtc_event_rtcp_packet_outgoing.h"
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_incoming.h"
#include "logging/rtc_event_log/events/rtc_event_rtp_packet_outgoing.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 "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtcp_packet/common_header.h"

// Files generated at build-time by the protobuf compiler.
#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

namespace webrtc {

enum PacketDirection { kIncomingPacket = 0, kOutgoingPacket };

enum class LoggedMediaType : uint8_t { kUnknown, kAudio, kVideo };

struct LoggedPacketInfo {
  static LoggedPacketInfo CreateEmptyForTesting() { return LoggedPacketInfo(); }

  LoggedPacketInfo(const LoggedRtpPacket& rtp,
                   LoggedMediaType media_type,
                   bool rtx,
                   Timestamp capture_time);
  LoggedPacketInfo(const LoggedPacketInfo&);
  ~LoggedPacketInfo();

  int64_t log_time_ms() const { return log_packet_time.ms(); }
  int64_t log_time_us() const { return log_packet_time.us(); }
  uint32_t ssrc;
  uint16_t stream_seq_no;
  uint16_t size;
  uint16_t payload_size;
  uint16_t padding_size;
  uint16_t overhead = 0;
  uint8_t payload_type;
  LoggedMediaType media_type = LoggedMediaType::kUnknown;
  bool rtx = false;
  bool marker_bit = false;
  bool has_transport_seq_no = false;
  bool last_in_feedback = false;
  uint16_t transport_seq_no = 0;
  // The RTP header timestamp unwrapped and converted from tick count to seconds
  // based timestamp.
  Timestamp capture_time;
  // The time the packet was logged. This is the receive time for incoming
  // packets and send time for outgoing.
  Timestamp log_packet_time;
  // Send time as reported by abs-send-time extension, For outgoing packets this
  // corresponds to log_packet_time, but might be measured using another clock.
  Timestamp reported_send_time;
  // The receive time that was reported in feedback. For incoming packets this
  // corresponds to log_packet_time, but might be measured using another clock.
  // PlusInfinity indicates that the packet was lost.
  Timestamp reported_recv_time = Timestamp::MinusInfinity();
  // The time feedback message was logged. This is the feedback send time for
  // incoming packets and feedback receive time for outgoing.
  // PlusInfinity indicates that feedback was expected but not received.
  Timestamp log_feedback_time = Timestamp::MinusInfinity();
  // The delay betweeen receiving an RTP packet and sending feedback for
  // incoming packets. For outgoing packets we don't know the feedback send
  // time, and this is instead calculated as the difference in reported receive
  // time between this packet and the last packet in the same feedback message.
  TimeDelta feedback_hold_duration = TimeDelta::MinusInfinity();

 private:
  LoggedPacketInfo()
      : capture_time(Timestamp::MinusInfinity()),
        log_packet_time(Timestamp::MinusInfinity()),
        reported_send_time(Timestamp::MinusInfinity()) {}
};

struct InferredRouteChangeEvent {
  int64_t log_time_ms() const { return log_time.ms(); }
  int64_t log_time_us() const { return log_time.us(); }
  uint32_t route_id;
  Timestamp log_time = Timestamp::MinusInfinity();
  uint16_t send_overhead;
  uint16_t return_overhead;
};

enum class LoggedIceEventType {
  kAdded,
  kUpdated,
  kDestroyed,
  kSelected,
  kCheckSent,
  kCheckReceived,
  kCheckResponseSent,
  kCheckResponseReceived,
};

struct LoggedIceEvent {
  uint32_t candidate_pair_id;
  Timestamp log_time;
  LoggedIceEventType event_type;
};

// 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
  };

  using ParseStatus = RtcEventLogParseStatus;

  template <typename T>
  using ParseStatusOr = RtcEventLogParseStatusOr<T>;

  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(absl::string_view file_name);

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

  // Reads an RtcEventLog from an string and returns success if successful.
  ParseStatus ParseStream(absl::string_view 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::map<uint32_t, std::vector<LoggedNetEqSetMinimumDelayEvent>>&
  neteq_set_minimum_delay_events() const {
    return neteq_set_minimum_delay_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_;
  }

  Timestamp first_timestamp() const { return first_timestamp_; }
  Timestamp 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 ParseStreamInternalV3(absl::string_view s);

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

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

  // 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(bool incoming,
                                                        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;

  ParsedRtcEventLog::ParseStatusOr<LoggedRemoteEstimateEvent>
  GetRemoteEstimateEvent(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 StoreNetEqSetMinimumDelay(
      const rtclog2::NetEqSetMinimumDelay& 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::map<uint32_t, std::vector<LoggedNetEqSetMinimumDelayEvent>>
      neteq_set_minimum_delay_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_;

  Timestamp first_timestamp_ = Timestamp::PlusInfinity();
  Timestamp last_timestamp_ = Timestamp::MinusInfinity();

  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_
