/*
 *  Copyright (c) 2015 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 <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "call/call.h"
#include "logging/rtc_event_log/rtc_event_log.h"
#include "logging/rtc_event_log/rtc_event_log_parser.h"
#include "logging/rtc_event_log/rtc_event_log_unittest_helper.h"
#include "logging/rtc_event_log/rtc_stream_config.h"
#include "modules/audio_coding/audio_network_adaptor/include/audio_network_adaptor.h"
#include "modules/remote_bitrate_estimator/include/bwe_defines.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtcp_packet.h"
#include "modules/rtp_rtcp/source/rtcp_packet/sender_report.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "modules/rtp_rtcp/source/rtp_packet_to_send.h"
#include "rtc_base/buffer.h"
#include "rtc_base/checks.h"
#include "rtc_base/fakeclock.h"
#include "rtc_base/random.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.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"
#else
#include "logging/rtc_event_log/rtc_event_log.pb.h"
#endif

namespace webrtc {

namespace {

const RTPExtensionType kExtensionTypes[] = {
    RTPExtensionType::kRtpExtensionTransmissionTimeOffset,
    RTPExtensionType::kRtpExtensionAudioLevel,
    RTPExtensionType::kRtpExtensionAbsoluteSendTime,
    RTPExtensionType::kRtpExtensionVideoRotation,
    RTPExtensionType::kRtpExtensionTransportSequenceNumber};
const char* kExtensionNames[] = {
    RtpExtension::kTimestampOffsetUri, RtpExtension::kAudioLevelUri,
    RtpExtension::kAbsSendTimeUri, RtpExtension::kVideoRotationUri,
    RtpExtension::kTransportSequenceNumberUri};
const size_t kNumExtensions = 5;

void PrintActualEvents(const ParsedRtcEventLog& parsed_log) {
  std::map<int, size_t> actual_event_counts;
  for (size_t i = 0; i < parsed_log.GetNumberOfEvents(); i++) {
    actual_event_counts[parsed_log.GetEventType(i)]++;
  }
  printf("Actual events: ");
  for (auto kv : actual_event_counts) {
    printf("%d_count = %zu, ", kv.first, kv.second);
  }
  printf("\n");
  for (size_t i = 0; i < parsed_log.GetNumberOfEvents(); i++) {
    printf("%4d ", parsed_log.GetEventType(i));
  }
  printf("\n");
}

void PrintExpectedEvents(size_t rtp_count,
                         size_t rtcp_count,
                         size_t playout_count,
                         size_t bwe_loss_count) {
  printf(
      "Expected events: rtp_count = %zu, rtcp_count = %zu,"
      "playout_count = %zu, bwe_loss_count = %zu\n",
      rtp_count, rtcp_count, playout_count, bwe_loss_count);
  size_t rtcp_index = 1, playout_index = 1, bwe_loss_index = 1;
  printf("strt  cfg  cfg ");
  for (size_t i = 1; i <= rtp_count; i++) {
    printf(" rtp ");
    if (i * rtcp_count >= rtcp_index * rtp_count) {
      printf("rtcp ");
      rtcp_index++;
    }
    if (i * playout_count >= playout_index * rtp_count) {
      printf("play ");
      playout_index++;
    }
    if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
      printf("loss ");
      bwe_loss_index++;
    }
  }
  printf("end \n");
}
}  // namespace

/*
 * Bit number i of extension_bitvector is set to indicate the
 * presence of extension number i from kExtensionTypes / kExtensionNames.
 * The least significant bit extension_bitvector has number 0.
 */
RtpPacketToSend GenerateRtpPacket(const RtpHeaderExtensionMap* extensions,
                                  uint32_t csrcs_count,
                                  size_t packet_size,
                                  Random* prng) {
  RTC_CHECK_GE(packet_size, 16 + 4 * csrcs_count + 4 * kNumExtensions);

  std::vector<uint32_t> csrcs;
  for (unsigned i = 0; i < csrcs_count; i++) {
    csrcs.push_back(prng->Rand<uint32_t>());
  }

  RtpPacketToSend rtp_packet(extensions, packet_size);
  rtp_packet.SetPayloadType(prng->Rand(127));
  rtp_packet.SetMarker(prng->Rand<bool>());
  rtp_packet.SetSequenceNumber(prng->Rand<uint16_t>());
  rtp_packet.SetSsrc(prng->Rand<uint32_t>());
  rtp_packet.SetTimestamp(prng->Rand<uint32_t>());
  rtp_packet.SetCsrcs(csrcs);

  rtp_packet.SetExtension<TransmissionOffset>(prng->Rand(0x00ffffff));
  rtp_packet.SetExtension<AudioLevel>(prng->Rand<bool>(), prng->Rand(127));
  rtp_packet.SetExtension<AbsoluteSendTime>(prng->Rand(0x00ffffff));
  rtp_packet.SetExtension<VideoOrientation>(prng->Rand(2));
  rtp_packet.SetExtension<TransportSequenceNumber>(prng->Rand<uint16_t>());

  size_t payload_size = packet_size - rtp_packet.headers_size();
  uint8_t* payload = rtp_packet.AllocatePayload(payload_size);
  for (size_t i = 0; i < payload_size; i++) {
    payload[i] = prng->Rand<uint8_t>();
  }
  return rtp_packet;
}

rtc::Buffer GenerateRtcpPacket(Random* prng) {
  rtcp::ReportBlock report_block;
  report_block.SetMediaSsrc(prng->Rand<uint32_t>());  // Remote SSRC.
  report_block.SetFractionLost(prng->Rand(50));

  rtcp::SenderReport sender_report;
  sender_report.SetSenderSsrc(prng->Rand<uint32_t>());
  sender_report.SetNtp(NtpTime(prng->Rand<uint32_t>(), prng->Rand<uint32_t>()));
  sender_report.SetPacketCount(prng->Rand<uint32_t>());
  sender_report.AddReportBlock(report_block);

  return sender_report.Build();
}

void GenerateVideoReceiveConfig(uint32_t extensions_bitvector,
                                rtclog::StreamConfig* config,
                                Random* prng) {
  // Add SSRCs for the stream.
  config->remote_ssrc = prng->Rand<uint32_t>();
  config->local_ssrc = prng->Rand<uint32_t>();
  // Add extensions and settings for RTCP.
  config->rtcp_mode =
      prng->Rand<bool>() ? RtcpMode::kCompound : RtcpMode::kReducedSize;
  config->remb = prng->Rand<bool>();
  config->rtx_ssrc = prng->Rand<uint32_t>();
  config->codecs.emplace_back(prng->Rand<bool>() ? "VP8" : "H264",
                              prng->Rand(1, 127), prng->Rand(1, 127));
  // Add header extensions.
  for (unsigned i = 0; i < kNumExtensions; i++) {
    if (extensions_bitvector & (1u << i)) {
      config->rtp_extensions.emplace_back(kExtensionNames[i],
                                          prng->Rand<int>());
    }
  }
}

void GenerateVideoSendConfig(uint32_t extensions_bitvector,
                             rtclog::StreamConfig* config,
                             Random* prng) {
  config->codecs.emplace_back(prng->Rand<bool>() ? "VP8" : "H264",
                              prng->Rand(1, 127), prng->Rand(1, 127));
  config->local_ssrc = prng->Rand<uint32_t>();
  config->rtx_ssrc = prng->Rand<uint32_t>();
  // Add header extensions.
  for (unsigned i = 0; i < kNumExtensions; i++) {
    if (extensions_bitvector & (1u << i)) {
      config->rtp_extensions.push_back(
          RtpExtension(kExtensionNames[i], prng->Rand<int>()));
    }
  }
}

void GenerateAudioReceiveConfig(uint32_t extensions_bitvector,
                                rtclog::StreamConfig* config,
                                Random* prng) {
  // Add SSRCs for the stream.
  config->remote_ssrc = prng->Rand<uint32_t>();
  config->local_ssrc = prng->Rand<uint32_t>();
  // Add header extensions.
  for (unsigned i = 0; i < kNumExtensions; i++) {
    if (extensions_bitvector & (1u << i)) {
      config->rtp_extensions.push_back(
          RtpExtension(kExtensionNames[i], prng->Rand<int>()));
    }
  }
}

void GenerateAudioSendConfig(uint32_t extensions_bitvector,
                             rtclog::StreamConfig* config,
                             Random* prng) {
  // Add SSRC to the stream.
  config->local_ssrc = prng->Rand<uint32_t>();
  // Add header extensions.
  for (unsigned i = 0; i < kNumExtensions; i++) {
    if (extensions_bitvector & (1u << i)) {
      config->rtp_extensions.push_back(
          RtpExtension(kExtensionNames[i], prng->Rand<int>()));
    }
  }
}

void GenerateAudioNetworkAdaptation(uint32_t extensions_bitvector,
                                    AudioEncoderRuntimeConfig* config,
                                    Random* prng) {
  config->bitrate_bps = rtc::Optional<int>(prng->Rand(0, 3000000));
  config->enable_fec = rtc::Optional<bool>(prng->Rand<bool>());
  config->enable_dtx = rtc::Optional<bool>(prng->Rand<bool>());
  config->frame_length_ms = rtc::Optional<int>(prng->Rand(10, 120));
  config->num_channels = rtc::Optional<size_t>(prng->Rand(1, 2));
  config->uplink_packet_loss_fraction =
      rtc::Optional<float>(prng->Rand<float>());
}

// Test for the RtcEventLog class. Dumps some RTP packets and other events
// to disk, then reads them back to see if they match.
void LogSessionAndReadBack(size_t rtp_count,
                           size_t rtcp_count,
                           size_t playout_count,
                           size_t bwe_loss_count,
                           uint32_t extensions_bitvector,
                           uint32_t csrcs_count,
                           unsigned int random_seed) {
  ASSERT_LE(rtcp_count, rtp_count);
  ASSERT_LE(playout_count, rtp_count);
  ASSERT_LE(bwe_loss_count, rtp_count);
  std::vector<RtpPacketToSend> rtp_packets;
  std::vector<rtc::Buffer> rtcp_packets;
  std::vector<uint32_t> playout_ssrcs;
  std::vector<std::pair<int32_t, uint8_t> > bwe_loss_updates;

  rtclog::StreamConfig receiver_config;
  rtclog::StreamConfig sender_config;

  Random prng(random_seed);

  // Initialize rtp header extensions to be used in generated rtp packets.
  RtpHeaderExtensionMap extensions;
  for (unsigned i = 0; i < kNumExtensions; i++) {
    if (extensions_bitvector & (1u << i)) {
      extensions.Register(kExtensionTypes[i], i + 1);
    }
  }
  // Create rtp_count RTP packets containing random data.
  for (size_t i = 0; i < rtp_count; i++) {
    size_t packet_size = prng.Rand(1000, 1100);
    rtp_packets.push_back(
        GenerateRtpPacket(&extensions, csrcs_count, packet_size, &prng));
  }
  // Create rtcp_count RTCP packets containing random data.
  for (size_t i = 0; i < rtcp_count; i++) {
    rtcp_packets.push_back(GenerateRtcpPacket(&prng));
  }
  // Create playout_count random SSRCs to use when logging AudioPlayout events.
  for (size_t i = 0; i < playout_count; i++) {
    playout_ssrcs.push_back(prng.Rand<uint32_t>());
  }
  // Create bwe_loss_count random bitrate updates for LossBasedBwe.
  for (size_t i = 0; i < bwe_loss_count; i++) {
    bwe_loss_updates.push_back(
        std::make_pair(prng.Rand<int32_t>(), prng.Rand<uint8_t>()));
  }
  // Create configurations for the video streams.
  GenerateVideoReceiveConfig(extensions_bitvector, &receiver_config, &prng);
  GenerateVideoSendConfig(extensions_bitvector, &sender_config, &prng);
  const int config_count = 2;

  // Find the name of the current test, in order to use it as a temporary
  // filename.
  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  const std::string temp_filename =
      test::OutputPath() + test_info->test_case_name() + test_info->name();

  // When log_dumper goes out of scope, it causes the log file to be flushed
  // to disk.
  {
    rtc::ScopedFakeClock fake_clock;
    fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
    std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
    log_dumper->LogVideoReceiveStreamConfig(receiver_config);
    fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
    log_dumper->LogVideoSendStreamConfig(sender_config);
    fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
    size_t rtcp_index = 1;
    size_t playout_index = 1;
    size_t bwe_loss_index = 1;
    for (size_t i = 1; i <= rtp_count; i++) {
      log_dumper->LogRtpHeader(
          (i % 2 == 0) ? kIncomingPacket : kOutgoingPacket,
          rtp_packets[i - 1].data(), rtp_packets[i - 1].size());
      fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
      if (i * rtcp_count >= rtcp_index * rtp_count) {
        log_dumper->LogRtcpPacket(
            (rtcp_index % 2 == 0) ? kIncomingPacket : kOutgoingPacket,
            rtcp_packets[rtcp_index - 1].data(),
            rtcp_packets[rtcp_index - 1].size());
        rtcp_index++;
        fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
      }
      if (i * playout_count >= playout_index * rtp_count) {
        log_dumper->LogAudioPlayout(playout_ssrcs[playout_index - 1]);
        playout_index++;
        fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
      }
      if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
        log_dumper->LogLossBasedBweUpdate(
            bwe_loss_updates[bwe_loss_index - 1].first,
            bwe_loss_updates[bwe_loss_index - 1].second, i);
        bwe_loss_index++;
        fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
      }
      if (i == rtp_count / 2) {
        log_dumper->StartLogging(temp_filename, 10000000);
        fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
      }
    }
    log_dumper->StopLogging();
  }

  // Read the generated file from disk.
  ParsedRtcEventLog parsed_log;

  ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

  // Verify that what we read back from the event log is the same as
  // what we wrote down. For RTCP we log the full packets, but for
  // RTP we should only log the header.
  const size_t event_count = config_count + playout_count + bwe_loss_count +
                             rtcp_count + rtp_count + 2;
  EXPECT_GE(1000u, event_count);  // The events must fit in the message queue.
  EXPECT_EQ(event_count, parsed_log.GetNumberOfEvents());
  if (event_count != parsed_log.GetNumberOfEvents()) {
    // Print the expected and actual event types for easier debugging.
    PrintActualEvents(parsed_log);
    PrintExpectedEvents(rtp_count, rtcp_count, playout_count, bwe_loss_count);
  }
  RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
  RtcEventLogTestHelper::VerifyVideoReceiveStreamConfig(parsed_log, 1,
                                                        receiver_config);
  RtcEventLogTestHelper::VerifyVideoSendStreamConfig(parsed_log, 2,
                                                     sender_config);
  size_t event_index = config_count + 1;
  size_t rtcp_index = 1;
  size_t playout_index = 1;
  size_t bwe_loss_index = 1;
  for (size_t i = 1; i <= rtp_count; i++) {
    RtcEventLogTestHelper::VerifyRtpEvent(
        parsed_log, event_index,
        (i % 2 == 0) ? kIncomingPacket : kOutgoingPacket,
        rtp_packets[i - 1].data(), rtp_packets[i - 1].headers_size(),
        rtp_packets[i - 1].size());
    event_index++;
    if (i * rtcp_count >= rtcp_index * rtp_count) {
      RtcEventLogTestHelper::VerifyRtcpEvent(
          parsed_log, event_index,
          rtcp_index % 2 == 0 ? kIncomingPacket : kOutgoingPacket,
          rtcp_packets[rtcp_index - 1].data(),
          rtcp_packets[rtcp_index - 1].size());
      event_index++;
      rtcp_index++;
    }
    if (i * playout_count >= playout_index * rtp_count) {
      RtcEventLogTestHelper::VerifyPlayoutEvent(
          parsed_log, event_index, playout_ssrcs[playout_index - 1]);
      event_index++;
      playout_index++;
    }
    if (i * bwe_loss_count >= bwe_loss_index * rtp_count) {
      RtcEventLogTestHelper::VerifyBweLossEvent(
          parsed_log, event_index, bwe_loss_updates[bwe_loss_index - 1].first,
          bwe_loss_updates[bwe_loss_index - 1].second, i);
      event_index++;
      bwe_loss_index++;
    }
  }

  // Clean up temporary file - can be pretty slow.
  remove(temp_filename.c_str());
}

TEST(RtcEventLogTest, LogSessionAndReadBack) {
  // Log 5 RTP, 2 RTCP, 0 playout events and 0 BWE events
  // with no header extensions or CSRCS.
  LogSessionAndReadBack(5, 2, 0, 0, 0, 0, 321);

  // Enable AbsSendTime and TransportSequenceNumbers.
  uint32_t extensions = 0;
  for (uint32_t i = 0; i < kNumExtensions; i++) {
    if (kExtensionTypes[i] == RTPExtensionType::kRtpExtensionAbsoluteSendTime ||
        kExtensionTypes[i] ==
            RTPExtensionType::kRtpExtensionTransportSequenceNumber) {
      extensions |= 1u << i;
    }
  }
  LogSessionAndReadBack(8, 2, 0, 0, extensions, 0, 3141592653u);

  extensions = (1u << kNumExtensions) - 1;  // Enable all header extensions.
  LogSessionAndReadBack(9, 2, 3, 2, extensions, 2, 2718281828u);

  // Try all combinations of header extensions and up to 2 CSRCS.
  for (extensions = 0; extensions < (1u << kNumExtensions); extensions++) {
    for (uint32_t csrcs_count = 0; csrcs_count < 3; csrcs_count++) {
      LogSessionAndReadBack(5 + extensions,   // Number of RTP packets.
                            2 + csrcs_count,  // Number of RTCP packets.
                            3 + csrcs_count,  // Number of playout events.
                            1 + csrcs_count,  // Number of BWE loss events.
                            extensions,       // Bit vector choosing extensions.
                            csrcs_count,      // Number of contributing sources.
                            extensions * 3 + csrcs_count + 1);  // Random seed.
    }
  }
}

TEST(RtcEventLogTest, LogEventAndReadBack) {
  Random prng(987654321);

  // Create one RTP and one RTCP packet containing random data.
  size_t packet_size = prng.Rand(1000, 1100);
  RtpPacketToSend rtp_packet =
      GenerateRtpPacket(nullptr, 0, packet_size, &prng);
  rtc::Buffer rtcp_packet = GenerateRtcpPacket(&prng);

  // Find the name of the current test, in order to use it as a temporary
  // filename.
  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  const std::string temp_filename =
      test::OutputPath() + test_info->test_case_name() + test_info->name();

  // Add RTP, start logging, add RTCP and then stop logging
  rtc::ScopedFakeClock fake_clock;
  fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
  std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());

  log_dumper->LogRtpHeader(kIncomingPacket, rtp_packet.data(),
                           rtp_packet.size());
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));

  log_dumper->StartLogging(temp_filename, 10000000);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));

  log_dumper->LogRtcpPacket(kOutgoingPacket, rtcp_packet.data(),
                            rtcp_packet.size());
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));

  log_dumper->StopLogging();

  // Read the generated file from disk.
  ParsedRtcEventLog parsed_log;
  ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

  // Verify that what we read back from the event log is the same as
  // what we wrote down.
  EXPECT_EQ(4u, parsed_log.GetNumberOfEvents());

  RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);

  RtcEventLogTestHelper::VerifyRtpEvent(
      parsed_log, 1, kIncomingPacket, rtp_packet.data(),
      rtp_packet.headers_size(), rtp_packet.size());

  RtcEventLogTestHelper::VerifyRtcpEvent(
      parsed_log, 2, kOutgoingPacket, rtcp_packet.data(), rtcp_packet.size());

  RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 3);

  // Clean up temporary file - can be pretty slow.
  remove(temp_filename.c_str());
}

TEST(RtcEventLogTest, LogLossBasedBweUpdateAndReadBack) {
  Random prng(1234);

  // Generate a random packet loss event.
  int32_t bitrate = prng.Rand(0, 10000000);
  uint8_t fraction_lost = prng.Rand<uint8_t>();
  int32_t total_packets = prng.Rand(1, 1000);

  // Find the name of the current test, in order to use it as a temporary
  // filename.
  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  const std::string temp_filename =
      test::OutputPath() + test_info->test_case_name() + test_info->name();

  // Start logging, add the packet loss event and then stop logging.
  rtc::ScopedFakeClock fake_clock;
  fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
  std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
  log_dumper->StartLogging(temp_filename, 10000000);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogLossBasedBweUpdate(bitrate, fraction_lost, total_packets);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->StopLogging();

  // Read the generated file from disk.
  ParsedRtcEventLog parsed_log;
  ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

  // Verify that what we read back from the event log is the same as
  // what we wrote down.
  EXPECT_EQ(3u, parsed_log.GetNumberOfEvents());
  RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
  RtcEventLogTestHelper::VerifyBweLossEvent(parsed_log, 1, bitrate,
                                            fraction_lost, total_packets);
  RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 2);

  // Clean up temporary file - can be pretty slow.
  remove(temp_filename.c_str());
}

TEST(RtcEventLogTest, LogDelayBasedBweUpdateAndReadBack) {
  Random prng(1234);

  // Generate 3 random packet delay event.
  int32_t bitrate1 = prng.Rand(0, 10000000);
  int32_t bitrate2 = prng.Rand(0, 10000000);
  int32_t bitrate3 = prng.Rand(0, 10000000);

  // Find the name of the current test, in order to use it as a temporary
  // filename.
  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  const std::string temp_filename =
      test::OutputPath() + test_info->test_case_name() + test_info->name();

  // Start logging, add the packet delay events and then stop logging.
  rtc::ScopedFakeClock fake_clock;
  fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
  std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());
  log_dumper->StartLogging(temp_filename, 10000000);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogDelayBasedBweUpdate(bitrate1, BandwidthUsage::kBwNormal);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogDelayBasedBweUpdate(bitrate2, BandwidthUsage::kBwOverusing);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogDelayBasedBweUpdate(bitrate3, BandwidthUsage::kBwUnderusing);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->StopLogging();

  // Read the generated file from disk.
  ParsedRtcEventLog parsed_log;
  ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

  // Verify that what we read back from the event log is the same as
  // what we wrote down.
  EXPECT_EQ(5u, parsed_log.GetNumberOfEvents());
  RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
  RtcEventLogTestHelper::VerifyBweDelayEvent(parsed_log, 1, bitrate1,
                                             BandwidthUsage::kBwNormal);
  RtcEventLogTestHelper::VerifyBweDelayEvent(parsed_log, 2, bitrate2,
                                             BandwidthUsage::kBwOverusing);
  RtcEventLogTestHelper::VerifyBweDelayEvent(parsed_log, 3, bitrate3,
                                             BandwidthUsage::kBwUnderusing);
  RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);

  // Clean up temporary file - can be pretty slow.
  remove(temp_filename.c_str());
}

TEST(RtcEventLogTest, LogProbeClusterCreatedAndReadBack) {
  Random prng(794613);

  int bitrate_bps0 = prng.Rand(0, 10000000);
  int bitrate_bps1 = prng.Rand(0, 10000000);
  int bitrate_bps2 = prng.Rand(0, 10000000);
  int min_probes0 = prng.Rand(0, 100);
  int min_probes1 = prng.Rand(0, 100);
  int min_probes2 = prng.Rand(0, 100);
  int min_bytes0 = prng.Rand(0, 10000);
  int min_bytes1 = prng.Rand(0, 10000);
  int min_bytes2 = prng.Rand(0, 10000);

  // Find the name of the current test, in order to use it as a temporary
  // filename.
  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  const std::string temp_filename =
      test::OutputPath() + test_info->test_case_name() + test_info->name();

  rtc::ScopedFakeClock fake_clock;
  fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
  std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());

  log_dumper->StartLogging(temp_filename, 10000000);
  log_dumper->LogProbeClusterCreated(0, bitrate_bps0, min_probes0, min_bytes0);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogProbeClusterCreated(1, bitrate_bps1, min_probes1, min_bytes1);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogProbeClusterCreated(2, bitrate_bps2, min_probes2, min_bytes2);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->StopLogging();

  // Read the generated file from disk.
  ParsedRtcEventLog parsed_log;
  ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

  // Verify that what we read back from the event log is the same as
  // what we wrote down.
  EXPECT_EQ(5u, parsed_log.GetNumberOfEvents());
  RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
  RtcEventLogTestHelper::VerifyBweProbeCluster(parsed_log, 1, 0, bitrate_bps0,
                                               min_probes0, min_bytes0);
  RtcEventLogTestHelper::VerifyBweProbeCluster(parsed_log, 2, 1, bitrate_bps1,
                                               min_probes1, min_bytes1);
  RtcEventLogTestHelper::VerifyBweProbeCluster(parsed_log, 3, 2, bitrate_bps2,
                                               min_probes2, min_bytes2);
  RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);

  // Clean up temporary file - can be pretty slow.
  remove(temp_filename.c_str());
}

TEST(RtcEventLogTest, LogProbeResultSuccessAndReadBack) {
  Random prng(192837);

  int bitrate_bps0 = prng.Rand(0, 10000000);
  int bitrate_bps1 = prng.Rand(0, 10000000);
  int bitrate_bps2 = prng.Rand(0, 10000000);

  // Find the name of the current test, in order to use it as a temporary
  // filename.
  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  const std::string temp_filename =
      test::OutputPath() + test_info->test_case_name() + test_info->name();

  rtc::ScopedFakeClock fake_clock;
  fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
  std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());

  log_dumper->StartLogging(temp_filename, 10000000);
  log_dumper->LogProbeResultSuccess(0, bitrate_bps0);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogProbeResultSuccess(1, bitrate_bps1);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogProbeResultSuccess(2, bitrate_bps2);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->StopLogging();

  // Read the generated file from disk.
  ParsedRtcEventLog parsed_log;
  ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

  // Verify that what we read back from the event log is the same as
  // what we wrote down.
  EXPECT_EQ(5u, parsed_log.GetNumberOfEvents());
  RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
  RtcEventLogTestHelper::VerifyProbeResultSuccess(parsed_log, 1, 0,
                                                  bitrate_bps0);
  RtcEventLogTestHelper::VerifyProbeResultSuccess(parsed_log, 2, 1,
                                                  bitrate_bps1);
  RtcEventLogTestHelper::VerifyProbeResultSuccess(parsed_log, 3, 2,
                                                  bitrate_bps2);
  RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);

  // Clean up temporary file - can be pretty slow.
  remove(temp_filename.c_str());
}

TEST(RtcEventLogTest, LogProbeResultFailureAndReadBack) {
  Random prng(192837);

  // Find the name of the current test, in order to use it as a temporary
  // filename.
  auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
  const std::string temp_filename =
      test::OutputPath() + test_info->test_case_name() + test_info->name();

  rtc::ScopedFakeClock fake_clock;
  fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
  std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());

  log_dumper->StartLogging(temp_filename, 10000000);
  log_dumper->LogProbeResultFailure(
      0, ProbeFailureReason::kInvalidSendReceiveInterval);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogProbeResultFailure(
      1, ProbeFailureReason::kInvalidSendReceiveRatio);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->LogProbeResultFailure(2, ProbeFailureReason::kTimeout);
  fake_clock.AdvanceTimeMicros(prng.Rand(1, 1000));
  log_dumper->StopLogging();

  // Read the generated file from disk.
  ParsedRtcEventLog parsed_log;
  ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

  // Verify that what we read back from the event log is the same as
  // what we wrote down.
  EXPECT_EQ(5u, parsed_log.GetNumberOfEvents());
  RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);
  RtcEventLogTestHelper::VerifyProbeResultFailure(
      parsed_log, 1, 0, ProbeFailureReason::kInvalidSendReceiveInterval);
  RtcEventLogTestHelper::VerifyProbeResultFailure(
      parsed_log, 2, 1, ProbeFailureReason::kInvalidSendReceiveRatio);
  RtcEventLogTestHelper::VerifyProbeResultFailure(parsed_log, 3, 2,
                                                  ProbeFailureReason::kTimeout);
  RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 4);

  // Clean up temporary file - can be pretty slow.
  remove(temp_filename.c_str());
}

class ConfigReadWriteTest {
 public:
  ConfigReadWriteTest() : prng(987654321) {}
  virtual ~ConfigReadWriteTest() {}
  virtual void GenerateConfig(uint32_t extensions_bitvector) = 0;
  virtual void VerifyConfig(const ParsedRtcEventLog& parsed_log,
                            size_t index) = 0;
  virtual void LogConfig(RtcEventLog* event_log) = 0;

  void DoTest() {
    // Find the name of the current test, in order to use it as a temporary
    // filename.
    auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
    const std::string temp_filename =
        test::OutputPath() + test_info->test_case_name() + test_info->name();

    // Use all extensions.
    uint32_t extensions_bitvector = (1u << kNumExtensions) - 1;
    GenerateConfig(extensions_bitvector);

    // Log a single config event and stop logging.
    rtc::ScopedFakeClock fake_clock;
    fake_clock.SetTimeMicros(prng.Rand<uint32_t>());
    std::unique_ptr<RtcEventLog> log_dumper(RtcEventLog::Create());

    log_dumper->StartLogging(temp_filename, 10000000);
    LogConfig(log_dumper.get());
    log_dumper->StopLogging();

    // Read the generated file from disk.
    ParsedRtcEventLog parsed_log;
    ASSERT_TRUE(parsed_log.ParseFile(temp_filename));

    // Check the generated number of events.
    EXPECT_EQ(3u, parsed_log.GetNumberOfEvents());

    RtcEventLogTestHelper::VerifyLogStartEvent(parsed_log, 0);

    // Verify that the parsed config struct matches the one that was logged.
    VerifyConfig(parsed_log, 1);

    RtcEventLogTestHelper::VerifyLogEndEvent(parsed_log, 2);

    // Clean up temporary file - can be pretty slow.
    remove(temp_filename.c_str());
  }
  Random prng;
};

class AudioReceiveConfigReadWriteTest : public ConfigReadWriteTest {
 public:
  void GenerateConfig(uint32_t extensions_bitvector) override {
    GenerateAudioReceiveConfig(extensions_bitvector, &config, &prng);
  }
  void LogConfig(RtcEventLog* event_log) override {
    event_log->LogAudioReceiveStreamConfig(config);
  }
  void VerifyConfig(const ParsedRtcEventLog& parsed_log,
                    size_t index) override {
    RtcEventLogTestHelper::VerifyAudioReceiveStreamConfig(parsed_log, index,
                                                          config);
  }
  rtclog::StreamConfig config;
};

class AudioSendConfigReadWriteTest : public ConfigReadWriteTest {
 public:
  AudioSendConfigReadWriteTest() {}
  void GenerateConfig(uint32_t extensions_bitvector) override {
    GenerateAudioSendConfig(extensions_bitvector, &config, &prng);
  }
  void LogConfig(RtcEventLog* event_log) override {
    event_log->LogAudioSendStreamConfig(config);
  }
  void VerifyConfig(const ParsedRtcEventLog& parsed_log,
                    size_t index) override {
    RtcEventLogTestHelper::VerifyAudioSendStreamConfig(parsed_log, index,
                                                       config);
  }
  rtclog::StreamConfig config;
};

class VideoReceiveConfigReadWriteTest : public ConfigReadWriteTest {
 public:
  VideoReceiveConfigReadWriteTest() {}
  void GenerateConfig(uint32_t extensions_bitvector) override {
    GenerateVideoReceiveConfig(extensions_bitvector, &config, &prng);
  }
  void LogConfig(RtcEventLog* event_log) override {
    event_log->LogVideoReceiveStreamConfig(config);
  }
  void VerifyConfig(const ParsedRtcEventLog& parsed_log,
                    size_t index) override {
    RtcEventLogTestHelper::VerifyVideoReceiveStreamConfig(parsed_log, index,
                                                          config);
  }
  rtclog::StreamConfig config;
};

class VideoSendConfigReadWriteTest : public ConfigReadWriteTest {
 public:
  VideoSendConfigReadWriteTest() {}
  void GenerateConfig(uint32_t extensions_bitvector) override {
    GenerateVideoSendConfig(extensions_bitvector, &config, &prng);
  }
  void LogConfig(RtcEventLog* event_log) override {
    event_log->LogVideoSendStreamConfig(config);
  }
  void VerifyConfig(const ParsedRtcEventLog& parsed_log,
                    size_t index) override {
    RtcEventLogTestHelper::VerifyVideoSendStreamConfig(parsed_log, index,
                                                       config);
  }
  rtclog::StreamConfig config;
};

class AudioNetworkAdaptationReadWriteTest : public ConfigReadWriteTest {
 public:
  void GenerateConfig(uint32_t extensions_bitvector) override {
    GenerateAudioNetworkAdaptation(extensions_bitvector, &config, &prng);
  }
  void LogConfig(RtcEventLog* event_log) override {
    event_log->LogAudioNetworkAdaptation(config);
  }
  void VerifyConfig(const ParsedRtcEventLog& parsed_log,
                    size_t index) override {
    RtcEventLogTestHelper::VerifyAudioNetworkAdaptation(parsed_log, index,
                                                        config);
  }
  AudioEncoderRuntimeConfig config;
};

TEST(RtcEventLogTest, LogAudioReceiveConfig) {
  AudioReceiveConfigReadWriteTest test;
  test.DoTest();
}

TEST(RtcEventLogTest, LogAudioSendConfig) {
  AudioSendConfigReadWriteTest test;
  test.DoTest();
}

TEST(RtcEventLogTest, LogVideoReceiveConfig) {
  VideoReceiveConfigReadWriteTest test;
  test.DoTest();
}

TEST(RtcEventLogTest, LogVideoSendConfig) {
  VideoSendConfigReadWriteTest test;
  test.DoTest();
}

TEST(RtcEventLogTest, LogAudioNetworkAdaptation) {
  AudioNetworkAdaptationReadWriteTest test;
  test.DoTest();
}

}  // namespace webrtc
