/*
 *  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 <deque>
#include <limits>
#include <string>

#include "absl/memory/memory.h"
#include "logging/rtc_event_log/encoder/rtc_event_log_encoder_legacy.h"
#include "logging/rtc_event_log/events/rtc_event_alr_state.h"
#include "logging/rtc_event_log/events/rtc_event_audio_network_adaptation.h"
#include "logging/rtc_event_log/events/rtc_event_audio_playout.h"
#include "logging/rtc_event_log/events/rtc_event_audio_receive_stream_config.h"
#include "logging/rtc_event_log/events/rtc_event_audio_send_stream_config.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_delay_based.h"
#include "logging/rtc_event_log/events/rtc_event_bwe_update_loss_based.h"
#include "logging/rtc_event_log/events/rtc_event_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_new.h"
#include "logging/rtc_event_log/rtc_event_log_unittest_helper.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/rtp_header_extensions.h"
#include "rtc_base/random.h"
#include "test/gtest.h"

namespace webrtc {


class RtcEventLogEncoderTest : public testing::TestWithParam<int> {
 protected:
  RtcEventLogEncoderTest()
      : encoder_(new RtcEventLogEncoderLegacy),
        seed_(GetParam()),
        prng_(seed_),
        gen_(seed_ * 880001UL) {}
  ~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);

  std::deque<std::unique_ptr<RtcEvent>> history_;
  // TODO(eladalon): Once we have more than one possible encoder, parameterize
  // encoder selection.
  std::unique_ptr<RtcEventLogEncoder> encoder_;
  ParsedRtcEventLogNew parsed_log_;
  const uint64_t seed_;
  Random prng_;
  test::EventGenerator gen_;
};

TEST_P(RtcEventLogEncoderTest, RtcEventAlrState) {
  std::unique_ptr<RtcEventAlrState> event = gen_.NewAlrState();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& alr_state_events = parsed_log_.alr_state_events();

  ASSERT_EQ(alr_state_events.size(), 1u);
  test::VerifyLoggedAlrStateEvent(*event, alr_state_events[0]);
}

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 = absl::make_unique<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));
  const auto& ana_configs = parsed_log_.audio_network_adaptation_events();
  ASSERT_EQ(ana_configs.size(), 1u);

  EXPECT_EQ(ana_configs[0].timestamp_us, timestamp_us);
  EXPECT_EQ(ana_configs[0].config, original_runtime_config);
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationBitrate) {
  auto runtime_config = absl::make_unique<AudioEncoderRuntimeConfig>();
  const int bitrate_bps = rtc::checked_cast<int>(
      prng_.Rand(0, std::numeric_limits<int32_t>::max()));
  runtime_config->bitrate_bps = bitrate_bps;
  TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationFrameLength) {
  auto runtime_config = absl::make_unique<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 = absl::make_unique<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 = absl::make_unique<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 = absl::make_unique<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 = absl::make_unique<AudioEncoderRuntimeConfig>();
    runtime_config->num_channels = channels;
    TestRtcEventAudioNetworkAdaptation(std::move(runtime_config));
  }
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioNetworkAdaptationAll) {
  const int bitrate_bps = rtc::checked_cast<int>(
      prng_.Rand(0, std::numeric_limits<int32_t>::max()));
  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 = absl::make_unique<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) {
  uint32_t ssrc = prng_.Rand<uint32_t>();
  std::unique_ptr<RtcEventAudioPlayout> event = gen_.NewAudioPlayout(ssrc);
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));

  const auto& playout_events = parsed_log_.audio_playout_events();
  ASSERT_EQ(playout_events.size(), 1u);
  const auto playout_stream = playout_events.find(ssrc);
  ASSERT_TRUE(playout_stream != playout_events.end());
  ASSERT_EQ(playout_stream->second.size(), 1u);
  LoggedAudioPlayoutEvent playout_event = playout_stream->second[0];
  test::VerifyLoggedAudioPlayoutEvent(*event, playout_event);
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioReceiveStreamConfig) {
  uint32_t ssrc = prng_.Rand<uint32_t>();
  RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
  std::unique_ptr<RtcEventAudioReceiveStreamConfig> event =
      gen_.NewAudioReceiveStreamConfig(ssrc, extensions);
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& audio_recv_configs = parsed_log_.audio_recv_configs();

  ASSERT_EQ(audio_recv_configs.size(), 1u);
  test::VerifyLoggedAudioRecvConfig(*event, audio_recv_configs[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventAudioSendStreamConfig) {
  uint32_t ssrc = prng_.Rand<uint32_t>();
  RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
  std::unique_ptr<RtcEventAudioSendStreamConfig> event =
      gen_.NewAudioSendStreamConfig(ssrc, extensions);
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& audio_send_configs = parsed_log_.audio_send_configs();

  ASSERT_EQ(audio_send_configs.size(), 1u);
  test::VerifyLoggedAudioSendConfig(*event, audio_send_configs[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateDelayBased) {
  std::unique_ptr<RtcEventBweUpdateDelayBased> event =
      gen_.NewBweUpdateDelayBased();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& bwe_delay_updates = parsed_log_.bwe_delay_updates();

  ASSERT_EQ(bwe_delay_updates.size(), 1u);
  test::VerifyLoggedBweDelayBasedUpdate(*event, bwe_delay_updates[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventBweUpdateLossBased) {
  std::unique_ptr<RtcEventBweUpdateLossBased> event =
      gen_.NewBweUpdateLossBased();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& bwe_loss_updates = parsed_log_.bwe_loss_updates();

  ASSERT_EQ(bwe_loss_updates.size(), 1u);

  test::VerifyLoggedBweLossBasedUpdate(*event, bwe_loss_updates[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePairConfig) {
  std::unique_ptr<RtcEventIceCandidatePairConfig> event =
      gen_.NewIceCandidatePairConfig();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& ice_candidate_pair_configs =
      parsed_log_.ice_candidate_pair_configs();

  ASSERT_EQ(ice_candidate_pair_configs.size(), 1u);
  test::VerifyLoggedIceCandidatePairConfig(*event,
                                           ice_candidate_pair_configs[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventIceCandidatePair) {
  std::unique_ptr<RtcEventIceCandidatePair> event = gen_.NewIceCandidatePair();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& ice_candidate_pair_events =
      parsed_log_.ice_candidate_pair_events();

  ASSERT_EQ(ice_candidate_pair_events.size(), 1u);
  test::VerifyLoggedIceCandidatePairEvent(*event, ice_candidate_pair_events[0]);
}

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

  ASSERT_TRUE(parsed_log_.ParseString(encoder_->EncodeLogStart(timestamp_us)));
  const auto& start_log_events = parsed_log_.start_log_events();

  ASSERT_EQ(start_log_events.size(), 1u);
  EXPECT_EQ(start_log_events[0].timestamp_us, timestamp_us);
}

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

  ASSERT_TRUE(parsed_log_.ParseString(encoder_->EncodeLogEnd(timestamp_us)));
  const auto& stop_log_events = parsed_log_.stop_log_events();

  ASSERT_EQ(stop_log_events.size(), 1u);
  EXPECT_EQ(stop_log_events[0].timestamp_us, timestamp_us);
}

TEST_P(RtcEventLogEncoderTest, RtcEventProbeClusterCreated) {
  std::unique_ptr<RtcEventProbeClusterCreated> event =
      gen_.NewProbeClusterCreated();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& bwe_probe_cluster_created_events =
      parsed_log_.bwe_probe_cluster_created_events();

  ASSERT_EQ(bwe_probe_cluster_created_events.size(), 1u);
  test::VerifyLoggedBweProbeClusterCreatedEvent(
      *event, bwe_probe_cluster_created_events[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultFailure) {
  std::unique_ptr<RtcEventProbeResultFailure> event =
      gen_.NewProbeResultFailure();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& bwe_probe_failure_events = parsed_log_.bwe_probe_failure_events();

  ASSERT_EQ(bwe_probe_failure_events.size(), 1u);
  test::VerifyLoggedBweProbeFailureEvent(*event, bwe_probe_failure_events[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventProbeResultSuccess) {
  std::unique_ptr<RtcEventProbeResultSuccess> event =
      gen_.NewProbeResultSuccess();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& bwe_probe_success_events = parsed_log_.bwe_probe_success_events();

  ASSERT_EQ(bwe_probe_success_events.size(), 1u);
  test::VerifyLoggedBweProbeSuccessEvent(*event, bwe_probe_success_events[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketIncoming) {
  std::unique_ptr<RtcEventRtcpPacketIncoming> event =
      gen_.NewRtcpPacketIncoming();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& incoming_rtcp_packets = parsed_log_.incoming_rtcp_packets();

  ASSERT_EQ(incoming_rtcp_packets.size(), 1u);

  test::VerifyLoggedRtcpPacketIncoming(*event, incoming_rtcp_packets[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtcpPacketOutgoing) {
  std::unique_ptr<RtcEventRtcpPacketOutgoing> event =
      gen_.NewRtcpPacketOutgoing();
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& outgoing_rtcp_packets = parsed_log_.outgoing_rtcp_packets();

  ASSERT_EQ(outgoing_rtcp_packets.size(), 1u);

  test::VerifyLoggedRtcpPacketOutgoing(*event, outgoing_rtcp_packets[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketIncoming) {
  uint32_t ssrc = prng_.Rand<uint32_t>();
  RtpHeaderExtensionMap extension_map;  // TODO(terelius): Test extensions too.
  std::unique_ptr<RtcEventRtpPacketIncoming> event =
      gen_.NewRtpPacketIncoming(ssrc, extension_map);
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& incoming_rtp_packets_by_ssrc =
      parsed_log_.incoming_rtp_packets_by_ssrc();

  ASSERT_EQ(incoming_rtp_packets_by_ssrc.size(), 1u);
  const auto& stream = incoming_rtp_packets_by_ssrc[0];
  EXPECT_EQ(stream.ssrc, ssrc);
  ASSERT_EQ(stream.incoming_packets.size(), 1u);

  test::VerifyLoggedRtpPacketIncoming(*event, stream.incoming_packets[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventRtpPacketOutgoing) {
  uint32_t ssrc = prng_.Rand<uint32_t>();
  RtpHeaderExtensionMap extension_map;  // TODO(terelius): Test extensions too.
  std::unique_ptr<RtcEventRtpPacketOutgoing> event =
      gen_.NewRtpPacketOutgoing(ssrc, extension_map);
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& outgoing_rtp_packets_by_ssrc =
      parsed_log_.outgoing_rtp_packets_by_ssrc();

  ASSERT_EQ(outgoing_rtp_packets_by_ssrc.size(), 1u);
  const auto& stream = outgoing_rtp_packets_by_ssrc[0];
  EXPECT_EQ(stream.ssrc, ssrc);
  ASSERT_EQ(stream.outgoing_packets.size(), 1u);

  test::VerifyLoggedRtpPacketOutgoing(*event, stream.outgoing_packets[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventVideoReceiveStreamConfig) {
  uint32_t ssrc = prng_.Rand<uint32_t>();
  RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
  std::unique_ptr<RtcEventVideoReceiveStreamConfig> event =
      gen_.NewVideoReceiveStreamConfig(ssrc, extensions);
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& video_recv_configs = parsed_log_.video_recv_configs();

  ASSERT_EQ(video_recv_configs.size(), 1u);
  test::VerifyLoggedVideoRecvConfig(*event, video_recv_configs[0]);
}

TEST_P(RtcEventLogEncoderTest, RtcEventVideoSendStreamConfig) {
  uint32_t ssrc = prng_.Rand<uint32_t>();
  RtpHeaderExtensionMap extensions = gen_.NewRtpHeaderExtensionMap();
  std::unique_ptr<RtcEventVideoSendStreamConfig> event =
      gen_.NewVideoSendStreamConfig(ssrc, extensions);
  history_.push_back(event->Copy());

  std::string encoded = encoder_->EncodeBatch(history_.begin(), history_.end());
  ASSERT_TRUE(parsed_log_.ParseString(encoded));
  const auto& video_send_configs = parsed_log_.video_send_configs();

  ASSERT_EQ(video_send_configs.size(), 1u);
  test::VerifyLoggedVideoSendConfig(*event, video_send_configs[0]);
}

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

}  // namespace webrtc
