/*
 *  Copyright (c) 2017 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 <cmath>
#include <deque>
#include <limits>
#include <memory>
#include <string>
#include <utility>

#include "api/rtpparameters.h"  // RtpExtension
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.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_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_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 "logging/rtc_event_log/rtc_event_log_parser.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor_config.h"
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "modules/rtp_rtcp/source/rtcp_packet/bye.h"  // Arbitrary RTCP message.
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "rtc_base/arraysize.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/ptr_util.h"
#include "rtc_base/random.h"
#include "test/gtest.h"

namespace webrtc {

namespace {
struct ExtensionInfo {
  RTPExtensionType type;
  const char* uri;
};

template <typename Extension>
constexpr ExtensionInfo CreateExtensionInfo() {
  return {Extension::kId, Extension::kUri};
}

constexpr ExtensionInfo kExtensions[] = {
    CreateExtensionInfo<TransmissionOffset>(),
    CreateExtensionInfo<AudioLevel>(),
    CreateExtensionInfo<AbsoluteSendTime>(),
    CreateExtensionInfo<VideoOrientation>(),
    CreateExtensionInfo<TransportSequenceNumber>(),
    CreateExtensionInfo<PlayoutDelayLimits>(),
    CreateExtensionInfo<VideoContentTypeExtension>(),
    CreateExtensionInfo<VideoTimingExtension>(),
    CreateExtensionInfo<RtpStreamId>(),
    CreateExtensionInfo<RepairedRtpStreamId>(),
    CreateExtensionInfo<RtpMid>(),
};
}  // namespace

class RtcEventLogEncoderTest : public testing::TestWithParam<int> {
 protected:
  RtcEventLogEncoderTest()
      : encoder_(new RtcEventLogEncoderLegacy), prng_(GetParam()) {}
  ~RtcEventLogEncoderTest() override = default;

  // ANA events have some optional fields, so we want to make sure that we get
  // correct behavior both when all of the values are there, as well as when
  // only some.
  void TestRtcEventAudioNetworkAdaptation(
      std::unique_ptr<AudioEncoderRuntimeConfig> runtime_config);

  // These help prevent code duplication between incoming/outgoing variants.
  void TestRtcEventRtcpPacket(PacketDirection direction);
  void TestRtcEventRtpPacket(PacketDirection direction);

  int RandomInt() {
    // Don't run this on a SNES.
    static_assert(8 * sizeof(int) >= 32, "Don't run this on a SNES.");
    int32_t rand = prng_.Rand(0, std::numeric_limits<int32_t>::max());
    return rtc::saturated_cast<int>(rand);
  }

  int RandomPositiveInt() {
    int32_t rand = prng_.Rand(1, std::numeric_limits<int32_t>::max());
    return rtc::saturated_cast<int>(rand);
  }

  uint32_t RandomSsrc() {
    return prng_.Rand(std::numeric_limits<uint32_t>::max());
  }

  std::vector<RtpExtension> RandomRtpExtensions() {
    RTC_DCHECK(arraysize(kExtensions) >= 2);
    size_t id_1 = prng_.Rand(0u, arraysize(kExtensions) - 1);
    size_t id_2 = prng_.Rand(0u, arraysize(kExtensions) - 2);
    if (id_2 == id_1)
      id_2 = arraysize(kExtensions) - 1;
    return std::vector<RtpExtension>{
        RtpExtension(kExtensions[id_1].uri, kExtensions[id_1].type),
        RtpExtension(kExtensions[id_2].uri, kExtensions[id_2].type)};
  }

  int RandomBitrate() { return RandomInt(); }

  std::deque<std::unique_ptr<RtcEvent>> history_;
  // TODO(eladalon): Once we have more than once possible encoder, parameterize
  // encoder selection.
  std::unique_ptr<RtcEventLogEncoder> encoder_;
  ParsedRtcEventLog parsed_log_;
  Random prng_;
};

void RtcEventLogEncoderTest::TestRtcEventAudioNetworkAdaptation(
    std::unique_ptr<AudioEncoderRuntimeConfig> runtime_config) {
  // This function is called repeatedly. Clear state between calls.
  history_.clear();
  auto original_runtime_config = *runtime_config;
  auto event = rtc::MakeUnique<RtcEventAudioNetworkAdaptation>(
      std::move(runtime_config));
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::AUDIO_NETWORK_ADAPTATION_EVENT);

  AudioEncoderRuntimeConfig parsed_runtime_config;
  parsed_log_.GetAudioNetworkAdaptation(0, &parsed_runtime_config);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_runtime_config, original_runtime_config);
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationBitrate) {
  auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
  const int bitrate_bps = RandomBitrate();
  runtime_config->bitrate_bps = bitrate_bps;
  TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFrameLength) {
  auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
  const int frame_length_ms = prng_.Rand(1, 1000);
  runtime_config->frame_length_ms = frame_length_ms;
  TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationPacketLoss) {
  // To simplify the test, we just check powers of two.
  const float plr = std::pow(0.5f, prng_.Rand(1, 8));
  auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
  runtime_config->uplink_packet_loss_fraction = plr;
  TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFec) {
  // The test might be trivially passing for one of the two boolean values, so
  // for safety's sake, we test both.
  for (bool fec_enabled : {false, true}) {
    auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
    runtime_config->enable_fec = fec_enabled;
    TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
  }
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationDtx) {
  // The test might be trivially passing for one of the two boolean values, so
  // for safety's sake, we test both.
  for (bool dtx_enabled : {false, true}) {
    auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
    runtime_config->enable_dtx = dtx_enabled;
    TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
  }
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationChannels) {
  // The test might be trivially passing for one of the two possible values, so
  // for safety's sake, we test both.
  for (size_t channels : {1, 2}) {
    auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
    runtime_config->num_channels = channels;
    TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
  }
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationAll) {
  const int bitrate_bps = RandomBitrate();
  const int frame_length_ms = prng_.Rand(1, 1000);
  const float plr = std::pow(0.5f, prng_.Rand(1, 8));
  for (bool fec_enabled : {false, true}) {
    for (bool dtx_enabled : {false, true}) {
      for (size_t channels : {1, 2}) {
        auto runtime_config = rtc::MakeUnique<AudioEncoderRuntimeConfig>();
        runtime_config->bitrate_bps = bitrate_bps;
        runtime_config->frame_length_ms = frame_length_ms;
        runtime_config->uplink_packet_loss_fraction = plr;
        runtime_config->enable_fec = fec_enabled;
        runtime_config->enable_dtx = dtx_enabled;
        runtime_config->num_channels = channels;

        TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
      }
    }
  }
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioPlayout) {
  const uint32_t ssrc = RandomSsrc();
  auto event = rtc::MakeUnique<RtcEventAudioPlayout>(ssrc);
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::AUDIO_PLAYOUT_EVENT);

  uint32_t parsed_ssrc;
  parsed_log_.GetAudioPlayout(0, &parsed_ssrc);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_ssrc, ssrc);
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) {
  auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
  stream_config->local_ssrc = RandomSsrc();
  stream_config->remote_ssrc = RandomSsrc();
  // TODO(eladalon): Verify that the extensions are used correctly when
  // parsing RTP packets headers. Here and elsewhere.
  std::vector<RtpExtension> extensions = RandomRtpExtensions();
  for (const auto& extension : extensions)
    stream_config->rtp_extensions.push_back(extension);

  auto original_stream_config = *stream_config;

  auto event = rtc::MakeUnique<RtcEventAudioReceiveStreamConfig>(
      std::move(stream_config));
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::AUDIO_RECEIVER_CONFIG_EVENT);

  auto parsed_event = parsed_log_.GetAudioReceiveConfig(0);
  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_event, original_stream_config);
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioSendStreamConfig) {
  auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
  stream_config->local_ssrc = RandomSsrc();
  std::vector<RtpExtension> extensions = RandomRtpExtensions();
  for (const auto& extension : extensions)
    stream_config->rtp_extensions.push_back(extension);

  auto original_stream_config = *stream_config;

  auto event =
      rtc::MakeUnique<RtcEventAudioSendStreamConfig>(std::move(stream_config));
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::AUDIO_SENDER_CONFIG_EVENT);

  auto parsed_event = parsed_log_.GetAudioSendConfig(0);
  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_event, original_stream_config);
}

TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) {
  const int32_t bitrate_bps = RandomBitrate();
  const BandwidthUsage detector_state = static_cast<BandwidthUsage>(
      prng_.Rand(0, static_cast<int32_t>(BandwidthUsage::kLast) - 1));
  auto event =
      rtc::MakeUnique<RtcEventBweUpdateDelayBased>(bitrate_bps, detector_state);
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::DELAY_BASED_BWE_UPDATE);

  auto parsed_event = parsed_log_.GetDelayBasedBweUpdate(0);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_event.bitrate_bps, bitrate_bps);
  EXPECT_EQ(parsed_event.detector_state, detector_state);
}

TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) {
  const int32_t bitrate_bps = RandomBitrate();
  const uint8_t fraction_loss = rtc::dchecked_cast<uint8_t>(
      prng_.Rand(0, std::numeric_limits<uint8_t>::max()));
  const int32_t total_packets = RandomInt();

  auto event = rtc::MakeUnique<RtcEventBweUpdateLossBased>(
      bitrate_bps, fraction_loss, total_packets);
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::LOSS_BASED_BWE_UPDATE);

  int32_t parsed_bitrate_bps;
  uint8_t parsed_fraction_loss;
  int32_t parsed_total_packets;
  parsed_log_.GetLossBasedBweUpdate(
      0, &parsed_bitrate_bps, &parsed_fraction_loss, &parsed_total_packets);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_bitrate_bps, bitrate_bps);
  EXPECT_EQ(parsed_fraction_loss, fraction_loss);
  EXPECT_EQ(parsed_total_packets, total_packets);
}

TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStarted) {
  const int64_t timestamp_us = rtc::TimeMicros();

  ASSERT_TRUE(parsed_log_.ParseString(encoder_->EncodeLogStart(timestamp_us)));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::LOG_START);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
}

TEST_P(RtcEventLogEncoderTest, RtcEventLoggingStopped) {
  const int64_t timestamp_us = rtc::TimeMicros();

  ASSERT_TRUE(parsed_log_.ParseString(encoder_->EncodeLogEnd(timestamp_us)));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::LOG_END);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
}

TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) {
  const int id = RandomPositiveInt();
  const int bitrate_bps = RandomBitrate();
  const int min_probes = RandomPositiveInt();
  const int min_bytes = RandomPositiveInt();

  auto event = rtc::MakeUnique<RtcEventProbeClusterCreated>(
      id, bitrate_bps, min_probes, min_bytes);
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::BWE_PROBE_CLUSTER_CREATED_EVENT);

  auto parsed_event = parsed_log_.GetBweProbeClusterCreated(0);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.id), id);
  EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.bitrate_bps), bitrate_bps);
  EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.min_packets), min_probes);
  EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.min_bytes), min_bytes);
}

TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultFailure) {
  const int id = RandomPositiveInt();
  const ProbeFailureReason failure_reason = static_cast<ProbeFailureReason>(
      prng_.Rand(0, static_cast<int32_t>(ProbeFailureReason::kLast) - 1));

  auto event = rtc::MakeUnique<RtcEventProbeResultFailure>(id, failure_reason);
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT);

  auto parsed_event = parsed_log_.GetBweProbeResult(0);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.id), id);
  ASSERT_FALSE(parsed_event.bitrate_bps);
  ASSERT_TRUE(parsed_event.failure_reason);
  EXPECT_EQ(parsed_event.failure_reason, failure_reason);
}

TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultSuccess) {
  const int id = RandomPositiveInt();
  const int bitrate_bps = RandomBitrate();

  auto event = rtc::MakeUnique<RtcEventProbeResultSuccess>(id, bitrate_bps);
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::BWE_PROBE_RESULT_EVENT);

  auto parsed_event = parsed_log_.GetBweProbeResult(0);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(rtc::dchecked_cast<int>(parsed_event.id), id);
  ASSERT_TRUE(parsed_event.bitrate_bps);
  EXPECT_EQ(parsed_event.bitrate_bps, bitrate_bps);
  ASSERT_FALSE(parsed_event.failure_reason);
}

void RtcEventLogEncoderTest::TestRtcEventRtcpPacket(PacketDirection direction) {
  rtcp::Bye bye_packet;  // Arbitrarily chosen RTCP packet type.
  bye_packet.SetReason("a man's reach should exceed his grasp");
  auto rtcp_packet = bye_packet.Build();

  std::unique_ptr<RtcEvent> event;
  if (direction == PacketDirection::kIncomingPacket) {
    event = rtc::MakeUnique<RtcEventRtcpPacketIncoming>(rtcp_packet);
  } else {
    event = rtc::MakeUnique<RtcEventRtcpPacketOutgoing>(rtcp_packet);
  }
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::RTCP_EVENT);

  PacketDirection parsed_direction;
  uint8_t parsed_packet[IP_PACKET_SIZE];  // "Parsed" = after event-encoding.
  size_t parsed_packet_length;
  parsed_log_.GetRtcpPacket(0, &parsed_direction, parsed_packet,
                            &parsed_packet_length);

  EXPECT_EQ(parsed_direction, direction);
  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  ASSERT_EQ(parsed_packet_length, rtcp_packet.size());
  ASSERT_EQ(memcmp(parsed_packet, rtcp_packet.data(), parsed_packet_length), 0);
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) {
  TestRtcEventRtcpPacket(PacketDirection::kIncomingPacket);
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketOutgoing) {
  TestRtcEventRtcpPacket(PacketDirection::kOutgoingPacket);
}

void RtcEventLogEncoderTest::TestRtcEventRtpPacket(PacketDirection direction) {
  const int probe_cluster_id = RandomPositiveInt();

  std::unique_ptr<RtpPacketReceived> packet_received;
  std::unique_ptr<RtpPacketToSend> packet_to_send;
  RtpPacket* packet;
  if (direction == PacketDirection::kIncomingPacket) {
    packet_received = rtc::MakeUnique<RtpPacketReceived>();
    packet = packet_received.get();
  } else {
    packet_to_send = rtc::MakeUnique<RtpPacketToSend>(nullptr);
    packet = packet_to_send.get();
  }
  packet->SetSsrc(RandomSsrc());
  packet->SetSequenceNumber(static_cast<uint16_t>(RandomInt()));
  packet->SetPayloadSize(prng_.Rand(0u, 1000u));
  // TODO(terelius): Add marker bit, capture timestamp, CSRCs, and header
  // extensions.

  std::unique_ptr<RtcEvent> event;
  if (direction == PacketDirection::kIncomingPacket) {
    event = rtc::MakeUnique<RtcEventRtpPacketIncoming>(*packet_received);
  } else {
    event = rtc::MakeUnique<RtcEventRtpPacketOutgoing>(*packet_to_send,
                                                       probe_cluster_id);
  }
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0), ParsedRtcEventLog::RTP_EVENT);

  PacketDirection parsed_direction;
  uint8_t parsed_rtp_header[IP_PACKET_SIZE];
  size_t parsed_header_length;
  size_t parsed_total_length;
  int parsed_probe_cluster_id;
  parsed_log_.GetRtpHeader(0, &parsed_direction, parsed_rtp_header,
                           &parsed_header_length, &parsed_total_length,
                           &parsed_probe_cluster_id);

  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_direction, direction);
  if (parsed_direction == PacketDirection::kOutgoingPacket) {
    EXPECT_EQ(parsed_probe_cluster_id, probe_cluster_id);
  }
  EXPECT_EQ(memcmp(parsed_rtp_header, packet->data(), parsed_header_length), 0);
  EXPECT_EQ(parsed_header_length, packet->headers_size());
  EXPECT_EQ(parsed_total_length, packet->size());
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) {
  TestRtcEventRtpPacket(PacketDirection::kIncomingPacket);
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoing) {
  TestRtcEventRtpPacket(PacketDirection::kOutgoingPacket);
}

TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) {
  auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
  stream_config->local_ssrc = RandomSsrc();
  stream_config->remote_ssrc = RandomSsrc();
  stream_config->rtcp_mode = RtcpMode::kCompound;
  stream_config->remb = prng_.Rand<bool>();
  std::vector<RtpExtension> extensions = RandomRtpExtensions();
  for (const auto& extension : extensions)
    stream_config->rtp_extensions.push_back(extension);
  stream_config->codecs.emplace_back("CODEC", 122, 7);

  auto original_stream_config = *stream_config;

  auto event = rtc::MakeUnique<RtcEventVideoReceiveStreamConfig>(
      std::move(stream_config));
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::VIDEO_RECEIVER_CONFIG_EVENT);

  auto parsed_event = parsed_log_.GetVideoReceiveConfig(0);
  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_event, original_stream_config);
}

TEST_P(RtcEventLogEncoderTest, RtcEventVideoSendStreamConfig) {
  auto stream_config = rtc::MakeUnique<rtclog::StreamConfig>();
  stream_config->local_ssrc = RandomSsrc();
  std::vector<RtpExtension> extensions = RandomRtpExtensions();
  for (const auto& extension : extensions)
    stream_config->rtp_extensions.push_back(extension);
  stream_config->codecs.emplace_back("CODEC", 120, 3);

  auto original_stream_config = *stream_config;

  auto event =
      rtc::MakeUnique<RtcEventVideoSendStreamConfig>(std::move(stream_config));
  const int64_t timestamp_us = event->timestamp_us_;
  history_.push_back(std::move(event));

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  ASSERT_EQ(parsed_log_.GetNumberOfEvents(), 1u);
  ASSERT_EQ(parsed_log_.GetEventType(0),
            ParsedRtcEventLog::VIDEO_SENDER_CONFIG_EVENT);

  auto parsed_event = parsed_log_.GetVideoSendConfig(0)[0];
  EXPECT_EQ(parsed_log_.GetTimestamp(0), timestamp_us);
  EXPECT_EQ(parsed_event, original_stream_config);
}

INSTANTIATE_TEST_CASE_P(RandomSeeds,
                        RtcEventLogEncoderTest,
                        ::testing::Values(1, 2, 3, 4, 5));

}  // namespace webrtc
