/*
 *  Copyright (c) 2020 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 "audio/voip/audio_egress.h"

#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/call/transport.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "modules/audio_mixer/sine_wave_generator.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_rtcp_impl2.h"
#include "rtc_base/event.h"
#include "rtc_base/logging.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/mock_transport.h"
#include "test/run_loop.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {
namespace {

using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Unused;

std::unique_ptr<ModuleRtpRtcpImpl2> CreateRtpStack(const Environment& env,
                                                   Transport* transport,
                                                   uint32_t remote_ssrc) {
  RtpRtcpInterface::Configuration rtp_config;
  rtp_config.audio = true;
  rtp_config.rtcp_report_interval_ms = 5000;
  rtp_config.outgoing_transport = transport;
  rtp_config.local_media_ssrc = remote_ssrc;
  auto rtp_rtcp = std::make_unique<ModuleRtpRtcpImpl2>(env, rtp_config);
  rtp_rtcp->SetSendingMediaStatus(false);
  rtp_rtcp->SetRTCPStatus(RtcpMode::kCompound);
  return rtp_rtcp;
}

constexpr int16_t kAudioLevel = 3004;  // Used for sine wave level.

// AudioEgressTest configures audio egress by using Rtp Stack, fake clock,
// and task queue factory.  Encoder factory is needed to create codec and
// configure the RTP stack in audio egress.
class AudioEgressTest : public ::testing::Test {
 public:
  static constexpr uint16_t kSeqNum = 12345;
  static constexpr uint64_t kStartTime = 123456789;
  static constexpr uint32_t kRemoteSsrc = 0xDEADBEEF;
  const SdpAudioFormat kPcmuFormat = {"pcmu", 8000, 1};

  AudioEgressTest() : wave_generator_(1000.0, kAudioLevel) {
    encoder_factory_ = CreateBuiltinAudioEncoderFactory();
  }

  // Prepare test on audio egress by using PCMu codec with specific
  // sequence number and its status to be running.
  void SetUp() override {
    rtp_rtcp_ = CreateRtpStack(env_, &transport_, kRemoteSsrc);
    egress_ = std::make_unique<AudioEgress>(env_, rtp_rtcp_.get());
    constexpr int kPcmuPayload = 0;
    egress_->SetEncoder(kPcmuPayload, kPcmuFormat,
                        encoder_factory_->Create(
                            env_, kPcmuFormat, {.payload_type = kPcmuPayload}));
    egress_->StartSend();
    rtp_rtcp_->SetSequenceNumber(kSeqNum);
    rtp_rtcp_->SetSendingStatus(true);
  }

  // Make sure we have shut down rtp stack and reset egress for each test.
  void TearDown() override {
    egress_->StopSend();
    rtp_rtcp_->SetSendingStatus(false);
    egress_.reset();
    rtp_rtcp_.reset();
  }

  // Create an audio frame prepared for pcmu encoding. Timestamp is
  // increased per RTP specification which is the number of samples it contains.
  // Wave generator writes sine wave which has expected high level set
  // by kAudioLevel.
  std::unique_ptr<AudioFrame> GetAudioFrame(int order) {
    auto frame = std::make_unique<AudioFrame>();
    frame->sample_rate_hz_ = kPcmuFormat.clockrate_hz;
    frame->samples_per_channel_ = kPcmuFormat.clockrate_hz / 100;  // 10 ms.
    frame->num_channels_ = kPcmuFormat.num_channels;
    frame->timestamp_ = frame->samples_per_channel_ * order;
    wave_generator_.GenerateNextFrame(frame.get());
    return frame;
  }

  GlobalSimulatedTimeController time_controller_{Timestamp::Micros(kStartTime)};
  const Environment env_ =
      CreateEnvironment(time_controller_.GetClock(),
                        time_controller_.GetTaskQueueFactory());
  NiceMock<MockTransport> transport_;
  SineWaveGenerator wave_generator_;
  std::unique_ptr<ModuleRtpRtcpImpl2> rtp_rtcp_;
  rtc::scoped_refptr<AudioEncoderFactory> encoder_factory_;
  std::unique_ptr<AudioEgress> egress_;
};

TEST_F(AudioEgressTest, SendingStatusAfterStartAndStop) {
  EXPECT_TRUE(egress_->IsSending());
  egress_->StopSend();
  EXPECT_FALSE(egress_->IsSending());
}

TEST_F(AudioEgressTest, ProcessAudioWithMute) {
  constexpr int kExpected = 10;
  rtc::Event event;
  int rtp_count = 0;
  RtpPacketReceived rtp;
  auto rtp_sent = [&](rtc::ArrayView<const uint8_t> packet, Unused) {
    rtp.Parse(packet);
    if (++rtp_count == kExpected) {
      event.Set();
    }
    return true;
  };

  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(rtp_sent));

  egress_->SetMute(true);

  // Two 10 ms audio frames will result in rtp packet with ptime 20.
  for (size_t i = 0; i < kExpected * 2; i++) {
    egress_->SendAudioData(GetAudioFrame(i));
    time_controller_.AdvanceTime(TimeDelta::Millis(10));
  }

  event.Wait(TimeDelta::Seconds(1));
  EXPECT_EQ(rtp_count, kExpected);

  // we expect on pcmu payload to result in 255 for silenced payload
  RTPHeader header;
  rtp.GetHeader(&header);
  size_t packet_length = rtp.size();
  size_t payload_length = packet_length - header.headerLength;
  size_t payload_data_length = payload_length - header.paddingLength;
  const uint8_t* payload = rtp.data() + header.headerLength;
  for (size_t i = 0; i < payload_data_length; ++i) {
    EXPECT_EQ(*payload++, 255);
  }
}

TEST_F(AudioEgressTest, ProcessAudioWithSineWave) {
  constexpr int kExpected = 10;
  rtc::Event event;
  int rtp_count = 0;
  RtpPacketReceived rtp;
  auto rtp_sent = [&](rtc::ArrayView<const uint8_t> packet, Unused) {
    rtp.Parse(packet);
    if (++rtp_count == kExpected) {
      event.Set();
    }
    return true;
  };

  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(rtp_sent));

  // Two 10 ms audio frames will result in rtp packet with ptime 20.
  for (size_t i = 0; i < kExpected * 2; i++) {
    egress_->SendAudioData(GetAudioFrame(i));
    time_controller_.AdvanceTime(TimeDelta::Millis(10));
  }

  event.Wait(TimeDelta::Seconds(1));
  EXPECT_EQ(rtp_count, kExpected);

  // we expect on pcmu to result in < 255 for payload with sine wave
  RTPHeader header;
  rtp.GetHeader(&header);
  size_t packet_length = rtp.size();
  size_t payload_length = packet_length - header.headerLength;
  size_t payload_data_length = payload_length - header.paddingLength;
  const uint8_t* payload = rtp.data() + header.headerLength;
  for (size_t i = 0; i < payload_data_length; ++i) {
    EXPECT_NE(*payload++, 255);
  }
}

TEST_F(AudioEgressTest, SkipAudioEncodingAfterStopSend) {
  constexpr int kExpected = 10;
  rtc::Event event;
  int rtp_count = 0;
  auto rtp_sent = [&](rtc::ArrayView<const uint8_t> packet, Unused) {
    if (++rtp_count == kExpected) {
      event.Set();
    }
    return true;
  };

  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(rtp_sent));

  // Two 10 ms audio frames will result in rtp packet with ptime 20.
  for (size_t i = 0; i < kExpected * 2; i++) {
    egress_->SendAudioData(GetAudioFrame(i));
    time_controller_.AdvanceTime(TimeDelta::Millis(10));
  }

  event.Wait(TimeDelta::Seconds(1));
  EXPECT_EQ(rtp_count, kExpected);

  // Now stop send and yet feed more data.
  egress_->StopSend();

  // It should be safe to exit the test case while encoder_queue_ has
  // outstanding data to process. We are making sure that this doesn't
  // result in crashes or sanitizer errors due to remaining data.
  for (size_t i = 0; i < kExpected * 2; i++) {
    egress_->SendAudioData(GetAudioFrame(i));
    time_controller_.AdvanceTime(TimeDelta::Millis(10));
  }
}

TEST_F(AudioEgressTest, ChangeEncoderFromPcmuToOpus) {
  std::optional<SdpAudioFormat> pcmu = egress_->GetEncoderFormat();
  EXPECT_TRUE(pcmu);
  EXPECT_EQ(pcmu->clockrate_hz, kPcmuFormat.clockrate_hz);
  EXPECT_EQ(pcmu->num_channels, kPcmuFormat.num_channels);

  constexpr int kOpusPayload = 120;
  const SdpAudioFormat kOpusFormat = {"opus", 48000, 2};

  egress_->SetEncoder(kOpusPayload, kOpusFormat,
                      encoder_factory_->Create(env_, kOpusFormat,
                                               {.payload_type = kOpusPayload}));

  std::optional<SdpAudioFormat> opus = egress_->GetEncoderFormat();
  EXPECT_TRUE(opus);
  EXPECT_EQ(opus->clockrate_hz, kOpusFormat.clockrate_hz);
  EXPECT_EQ(opus->num_channels, kOpusFormat.num_channels);
}

TEST_F(AudioEgressTest, SendDTMF) {
  constexpr int kExpected = 7;
  constexpr int kPayloadType = 100;
  constexpr int kDurationMs = 100;
  constexpr int kSampleRate = 8000;
  constexpr int kEvent = 3;

  egress_->RegisterTelephoneEventType(kPayloadType, kSampleRate);
  // 100 ms duration will produce total 7 DTMF
  // 1 @ 20 ms, 2 @ 40 ms, 3 @ 60 ms, 4 @ 80 ms
  // 5, 6, 7 @ 100 ms (last one sends 3 dtmf)
  egress_->SendTelephoneEvent(kEvent, kDurationMs);

  rtc::Event event;
  int dtmf_count = 0;
  auto is_dtmf = [&](RtpPacketReceived& rtp) {
    return (rtp.PayloadType() == kPayloadType &&
            rtp.SequenceNumber() == kSeqNum + dtmf_count &&
            rtp.padding_size() == 0 && rtp.Marker() == (dtmf_count == 0) &&
            rtp.Ssrc() == kRemoteSsrc);
  };

  // It's possible that we may have actual audio RTP packets along with
  // DTMF packtets.  We are only interested in the exact number of DTMF
  // packets rtp stack is emitting.
  auto rtp_sent = [&](rtc::ArrayView<const uint8_t> packet, Unused) {
    RtpPacketReceived rtp;
    rtp.Parse(packet);
    if (is_dtmf(rtp) && ++dtmf_count == kExpected) {
      event.Set();
    }
    return true;
  };

  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(rtp_sent));

  // Two 10 ms audio frames will result in rtp packet with ptime 20.
  for (size_t i = 0; i < kExpected * 2; i++) {
    egress_->SendAudioData(GetAudioFrame(i));
    time_controller_.AdvanceTime(TimeDelta::Millis(10));
  }

  event.Wait(TimeDelta::Seconds(1));
  EXPECT_EQ(dtmf_count, kExpected);
}

TEST_F(AudioEgressTest, TestAudioInputLevelAndEnergyDuration) {
  // Per audio_level's kUpdateFrequency, we need more than 10 audio samples to
  // get audio level from input source.
  constexpr int kExpected = 6;
  rtc::Event event;
  int rtp_count = 0;
  auto rtp_sent = [&](rtc::ArrayView<const uint8_t> packet, Unused) {
    if (++rtp_count == kExpected) {
      event.Set();
    }
    return true;
  };

  EXPECT_CALL(transport_, SendRtp).WillRepeatedly(Invoke(rtp_sent));

  // Two 10 ms audio frames will result in rtp packet with ptime 20.
  for (size_t i = 0; i < kExpected * 2; i++) {
    egress_->SendAudioData(GetAudioFrame(i));
    time_controller_.AdvanceTime(TimeDelta::Millis(10));
  }

  event.Wait(/*give_up_after=*/TimeDelta::Seconds(1));
  EXPECT_EQ(rtp_count, kExpected);

  constexpr double kExpectedEnergy = 0.00016809565587789564;
  constexpr double kExpectedDuration = 0.11999999999999998;

  EXPECT_EQ(egress_->GetInputAudioLevel(), kAudioLevel);
  EXPECT_DOUBLE_EQ(egress_->GetInputTotalEnergy(), kExpectedEnergy);
  EXPECT_DOUBLE_EQ(egress_->GetInputTotalDuration(), kExpectedDuration);
}

}  // namespace
}  // namespace webrtc
