/*
 *  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 "audio/audio_send_stream.h"

#include <memory>
#include <string>
#include <thread>
#include <utility>
#include <vector>

#include "api/task_queue/default_task_queue_factory.h"
#include "api/test/mock_frame_encryptor.h"
#include "audio/audio_state.h"
#include "audio/conversion.h"
#include "audio/mock_voe_channel_proxy.h"
#include "call/test/mock_rtp_transport_controller_send.h"
#include "logging/rtc_event_log/mock/mock_rtc_event_log.h"
#include "modules/audio_device/include/mock_audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
#include "modules/audio_mixer/sine_wave_generator.h"
#include "modules/audio_processing/include/audio_processing_statistics.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "modules/rtp_rtcp/mocks/mock_rtcp_bandwidth_observer.h"
#include "modules/rtp_rtcp/mocks/mock_rtcp_rtt_stats.h"
#include "modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
#include "rtc_base/task_queue_for_test.h"
#include "system_wrappers/include/clock.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/mock_audio_encoder.h"
#include "test/mock_audio_encoder_factory.h"

namespace webrtc {
namespace test {
namespace {

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Invoke;
using ::testing::Ne;
using ::testing::Return;
using ::testing::StrEq;

static const float kTolerance = 0.0001f;

const uint32_t kSsrc = 1234;
const char* kCName = "foo_name";
const int kAudioLevelId = 2;
const int kTransportSequenceNumberId = 4;
const int32_t kEchoDelayMedian = 254;
const int32_t kEchoDelayStdDev = -3;
const double kDivergentFilterFraction = 0.2f;
const double kEchoReturnLoss = -65;
const double kEchoReturnLossEnhancement = 101;
const double kResidualEchoLikelihood = -1.0f;
const double kResidualEchoLikelihoodMax = 23.0f;
const CallSendStatistics kCallStats = {112, 12, 13456, 17890};
const ReportBlock kReportBlock = {456, 780, 123, 567, 890, 132, 143, 13354};
const int kTelephoneEventPayloadType = 123;
const int kTelephoneEventPayloadFrequency = 65432;
const int kTelephoneEventCode = 45;
const int kTelephoneEventDuration = 6789;
constexpr int kIsacPayloadType = 103;
const SdpAudioFormat kIsacFormat = {"isac", 16000, 1};
const SdpAudioFormat kOpusFormat = {"opus", 48000, 2};
const SdpAudioFormat kG722Format = {"g722", 8000, 1};
const AudioCodecSpec kCodecSpecs[] = {
    {kIsacFormat, {16000, 1, 32000, 10000, 32000}},
    {kOpusFormat, {48000, 1, 32000, 6000, 510000}},
    {kG722Format, {16000, 1, 64000}}};

// TODO(dklee): This mirrors calculation in audio_send_stream.cc, which
// should be made more precise in the future. This can be changed when that
// logic is more accurate.
const DataSize kOverheadPerPacket = DataSize::bytes(20 + 8 + 10 + 12);
const TimeDelta kMinFrameLength = TimeDelta::ms(20);
const TimeDelta kMaxFrameLength = TimeDelta::ms(120);
const DataRate kMinOverheadRate = kOverheadPerPacket / kMaxFrameLength;
const DataRate kMaxOverheadRate = kOverheadPerPacket / kMinFrameLength;

class MockLimitObserver : public BitrateAllocator::LimitObserver {
 public:
  MOCK_METHOD1(OnAllocationLimitsChanged, void(BitrateAllocationLimits));
};

std::unique_ptr<MockAudioEncoder> SetupAudioEncoderMock(
    int payload_type,
    const SdpAudioFormat& format) {
  for (const auto& spec : kCodecSpecs) {
    if (format == spec.format) {
      std::unique_ptr<MockAudioEncoder> encoder(
          new ::testing::NiceMock<MockAudioEncoder>());
      ON_CALL(*encoder.get(), SampleRateHz())
          .WillByDefault(Return(spec.info.sample_rate_hz));
      ON_CALL(*encoder.get(), NumChannels())
          .WillByDefault(Return(spec.info.num_channels));
      ON_CALL(*encoder.get(), RtpTimestampRateHz())
          .WillByDefault(Return(spec.format.clockrate_hz));
      ON_CALL(*encoder.get(), GetFrameLengthRange())
          .WillByDefault(Return(absl::optional<std::pair<TimeDelta, TimeDelta>>{
              {TimeDelta::ms(20), TimeDelta::ms(120)}}));
      return encoder;
    }
  }
  return nullptr;
}

rtc::scoped_refptr<MockAudioEncoderFactory> SetupEncoderFactoryMock() {
  rtc::scoped_refptr<MockAudioEncoderFactory> factory =
      new rtc::RefCountedObject<MockAudioEncoderFactory>();
  ON_CALL(*factory.get(), GetSupportedEncoders())
      .WillByDefault(Return(std::vector<AudioCodecSpec>(
          std::begin(kCodecSpecs), std::end(kCodecSpecs))));
  ON_CALL(*factory.get(), QueryAudioEncoder(_))
      .WillByDefault(Invoke(
          [](const SdpAudioFormat& format) -> absl::optional<AudioCodecInfo> {
            for (const auto& spec : kCodecSpecs) {
              if (format == spec.format) {
                return spec.info;
              }
            }
            return absl::nullopt;
          }));
  ON_CALL(*factory.get(), MakeAudioEncoderMock(_, _, _, _))
      .WillByDefault(Invoke([](int payload_type, const SdpAudioFormat& format,
                               absl::optional<AudioCodecPairId> codec_pair_id,
                               std::unique_ptr<AudioEncoder>* return_value) {
        *return_value = SetupAudioEncoderMock(payload_type, format);
      }));
  return factory;
}

struct ConfigHelper {
  ConfigHelper(bool audio_bwe_enabled, bool expect_set_encoder_call)
      : clock_(1000000),
        task_queue_factory_(CreateDefaultTaskQueueFactory()),
        stream_config_(/*send_transport=*/nullptr),
        audio_processing_(new rtc::RefCountedObject<MockAudioProcessing>()),
        bitrate_allocator_(&limit_observer_),
        worker_queue_(task_queue_factory_->CreateTaskQueue(
            "ConfigHelper_worker_queue",
            TaskQueueFactory::Priority::NORMAL)),
        audio_encoder_(nullptr) {
    using ::testing::Invoke;

    AudioState::Config config;
    config.audio_mixer = AudioMixerImpl::Create();
    config.audio_processing = audio_processing_;
    config.audio_device_module =
        new rtc::RefCountedObject<MockAudioDeviceModule>();
    audio_state_ = AudioState::Create(config);

    SetupDefaultChannelSend(audio_bwe_enabled);
    SetupMockForSetupSendCodec(expect_set_encoder_call);

    // Use ISAC as default codec so as to prevent unnecessary |channel_proxy_|
    // calls from the default ctor behavior.
    stream_config_.send_codec_spec =
        AudioSendStream::Config::SendCodecSpec(kIsacPayloadType, kIsacFormat);
    stream_config_.rtp.ssrc = kSsrc;
    stream_config_.rtp.c_name = kCName;
    stream_config_.rtp.extensions.push_back(
        RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
    if (audio_bwe_enabled) {
      AddBweToConfig(&stream_config_);
    }
    stream_config_.encoder_factory = SetupEncoderFactoryMock();
    stream_config_.min_bitrate_bps = 10000;
    stream_config_.max_bitrate_bps = 65000;
  }

  std::unique_ptr<internal::AudioSendStream> CreateAudioSendStream() {
    EXPECT_CALL(rtp_transport_, GetWorkerQueue())
        .WillRepeatedly(Return(&worker_queue_));
    return std::unique_ptr<internal::AudioSendStream>(
        new internal::AudioSendStream(
            Clock::GetRealTimeClock(), stream_config_, audio_state_,
            task_queue_factory_.get(), &rtp_transport_, &bitrate_allocator_,
            &event_log_, &rtcp_rtt_stats_, absl::nullopt,
            std::unique_ptr<voe::ChannelSendInterface>(channel_send_)));
  }

  AudioSendStream::Config& config() { return stream_config_; }
  MockAudioEncoderFactory& mock_encoder_factory() {
    return *static_cast<MockAudioEncoderFactory*>(
        stream_config_.encoder_factory.get());
  }
  MockRtpRtcp* rtp_rtcp() { return &rtp_rtcp_; }
  MockChannelSend* channel_send() { return channel_send_; }
  RtpTransportControllerSendInterface* transport() { return &rtp_transport_; }

  static void AddBweToConfig(AudioSendStream::Config* config) {
    config->rtp.extensions.push_back(RtpExtension(
        RtpExtension::kTransportSequenceNumberUri, kTransportSequenceNumberId));
    config->send_codec_spec->transport_cc_enabled = true;
  }

  void SetupDefaultChannelSend(bool audio_bwe_enabled) {
    EXPECT_TRUE(channel_send_ == nullptr);
    channel_send_ = new ::testing::StrictMock<MockChannelSend>();
    EXPECT_CALL(*channel_send_, GetRtpRtcp()).WillRepeatedly(Invoke([this]() {
      return &this->rtp_rtcp_;
    }));
    EXPECT_CALL(rtp_rtcp_, SSRC).WillRepeatedly(Return(kSsrc));
    EXPECT_CALL(*channel_send_, SetRTCP_CNAME(StrEq(kCName))).Times(1);
    EXPECT_CALL(*channel_send_, SetFrameEncryptor(_)).Times(1);
    EXPECT_CALL(rtp_rtcp_, SetExtmapAllowMixed(false)).Times(1);
    EXPECT_CALL(*channel_send_,
                SetSendAudioLevelIndicationStatus(true, kAudioLevelId))
        .Times(1);
    EXPECT_CALL(rtp_transport_, GetBandwidthObserver())
        .WillRepeatedly(Return(&bandwidth_observer_));
    if (audio_bwe_enabled) {
      EXPECT_CALL(rtp_rtcp_,
                  RegisterRtpHeaderExtension(TransportSequenceNumber::kUri,
                                             kTransportSequenceNumberId))
          .Times(1);
      EXPECT_CALL(*channel_send_,
                  RegisterSenderCongestionControlObjects(
                      &rtp_transport_, Eq(&bandwidth_observer_)))
          .Times(1);
    } else {
      EXPECT_CALL(*channel_send_, RegisterSenderCongestionControlObjects(
                                      &rtp_transport_, Eq(nullptr)))
          .Times(1);
    }
    EXPECT_CALL(*channel_send_, ResetSenderCongestionControlObjects()).Times(1);
    EXPECT_CALL(rtp_rtcp_, SetRid(std::string())).Times(1);
  }

  void SetupMockForSetupSendCodec(bool expect_set_encoder_call) {
    if (expect_set_encoder_call) {
      EXPECT_CALL(*channel_send_, SetEncoderForMock(_, _))
          .WillOnce(Invoke(
              [this](int payload_type, std::unique_ptr<AudioEncoder>* encoder) {
                this->audio_encoder_ = std::move(*encoder);
                return true;
              }));
    }
  }

  void SetupMockForCallEncoder() {
    // Let ModifyEncoder to invoke mock audio encoder.
    EXPECT_CALL(*channel_send_, CallEncoder(_))
        .WillRepeatedly(
            [this](rtc::FunctionView<void(AudioEncoder*)> modifier) {
              if (this->audio_encoder_)
                modifier(this->audio_encoder_.get());
            });
  }

  void SetupMockForSendTelephoneEvent() {
    EXPECT_TRUE(channel_send_);
    EXPECT_CALL(*channel_send_, SetSendTelephoneEventPayloadType(
                                    kTelephoneEventPayloadType,
                                    kTelephoneEventPayloadFrequency));
    EXPECT_CALL(
        *channel_send_,
        SendTelephoneEventOutband(kTelephoneEventCode, kTelephoneEventDuration))
        .WillOnce(Return(true));
  }

  void SetupMockForGetStats() {
    using ::testing::DoAll;
    using ::testing::SetArgPointee;
    using ::testing::SetArgReferee;

    std::vector<ReportBlock> report_blocks;
    webrtc::ReportBlock block = kReportBlock;
    report_blocks.push_back(block);  // Has wrong SSRC.
    block.source_SSRC = kSsrc;
    report_blocks.push_back(block);  // Correct block.
    block.fraction_lost = 0;
    report_blocks.push_back(block);  // Duplicate SSRC, bad fraction_lost.

    EXPECT_TRUE(channel_send_);
    EXPECT_CALL(*channel_send_, GetRTCPStatistics())
        .WillRepeatedly(Return(kCallStats));
    EXPECT_CALL(*channel_send_, GetRemoteRTCPReportBlocks())
        .WillRepeatedly(Return(report_blocks));
    EXPECT_CALL(*channel_send_, GetANAStatistics())
        .WillRepeatedly(Return(ANAStats()));
    EXPECT_CALL(*channel_send_, GetBitrate()).WillRepeatedly(Return(0));

    audio_processing_stats_.echo_return_loss = kEchoReturnLoss;
    audio_processing_stats_.echo_return_loss_enhancement =
        kEchoReturnLossEnhancement;
    audio_processing_stats_.delay_median_ms = kEchoDelayMedian;
    audio_processing_stats_.delay_standard_deviation_ms = kEchoDelayStdDev;
    audio_processing_stats_.divergent_filter_fraction =
        kDivergentFilterFraction;
    audio_processing_stats_.residual_echo_likelihood = kResidualEchoLikelihood;
    audio_processing_stats_.residual_echo_likelihood_recent_max =
        kResidualEchoLikelihoodMax;

    EXPECT_CALL(*audio_processing_, GetStatistics(true))
        .WillRepeatedly(Return(audio_processing_stats_));
  }
  TaskQueueForTest* worker() { return &worker_queue_; }

 private:
  SimulatedClock clock_;
  std::unique_ptr<TaskQueueFactory> task_queue_factory_;
  rtc::scoped_refptr<AudioState> audio_state_;
  AudioSendStream::Config stream_config_;
  ::testing::StrictMock<MockChannelSend>* channel_send_ = nullptr;
  rtc::scoped_refptr<MockAudioProcessing> audio_processing_;
  AudioProcessingStats audio_processing_stats_;
  ::testing::StrictMock<MockRtcpBandwidthObserver> bandwidth_observer_;
  ::testing::NiceMock<MockRtcEventLog> event_log_;
  ::testing::NiceMock<MockRtpTransportControllerSend> rtp_transport_;
  ::testing::NiceMock<MockRtpRtcp> rtp_rtcp_;
  MockRtcpRttStats rtcp_rtt_stats_;
  ::testing::NiceMock<MockLimitObserver> limit_observer_;
  BitrateAllocator bitrate_allocator_;
  // |worker_queue| is defined last to ensure all pending tasks are cancelled
  // and deleted before any other members.
  TaskQueueForTest worker_queue_;
  std::unique_ptr<AudioEncoder> audio_encoder_;
};

// The audio level ranges linearly [0,32767].
std::unique_ptr<AudioFrame> CreateAudioFrame1kHzSineWave(int16_t audio_level,
                                                         int duration_ms,
                                                         int sample_rate_hz,
                                                         size_t num_channels) {
  size_t samples_per_channel = sample_rate_hz / (1000 / duration_ms);
  std::vector<int16_t> audio_data(samples_per_channel * num_channels, 0);
  std::unique_ptr<AudioFrame> audio_frame = std::make_unique<AudioFrame>();
  audio_frame->UpdateFrame(0 /* RTP timestamp */, &audio_data[0],
                           samples_per_channel, sample_rate_hz,
                           AudioFrame::SpeechType::kNormalSpeech,
                           AudioFrame::VADActivity::kVadUnknown, num_channels);
  SineWaveGenerator wave_generator(1000.0, audio_level);
  wave_generator.GenerateNextFrame(audio_frame.get());
  return audio_frame;
}

}  // namespace

TEST(AudioSendStreamTest, ConfigToString) {
  AudioSendStream::Config config(/*send_transport=*/nullptr);
  config.rtp.ssrc = kSsrc;
  config.rtp.c_name = kCName;
  config.min_bitrate_bps = 12000;
  config.max_bitrate_bps = 34000;
  config.send_codec_spec =
      AudioSendStream::Config::SendCodecSpec(kIsacPayloadType, kIsacFormat);
  config.send_codec_spec->nack_enabled = true;
  config.send_codec_spec->transport_cc_enabled = false;
  config.send_codec_spec->cng_payload_type = 42;
  config.encoder_factory = MockAudioEncoderFactory::CreateUnusedFactory();
  config.rtp.extmap_allow_mixed = true;
  config.rtp.extensions.push_back(
      RtpExtension(RtpExtension::kAudioLevelUri, kAudioLevelId));
  config.rtcp_report_interval_ms = 2500;
  EXPECT_EQ(
      "{rtp: {ssrc: 1234, extmap-allow-mixed: true, extensions: [{uri: "
      "urn:ietf:params:rtp-hdrext:ssrc-audio-level, id: 2}], "
      "c_name: foo_name}, rtcp_report_interval_ms: 2500, "
      "send_transport: null, "
      "min_bitrate_bps: 12000, max_bitrate_bps: 34000, "
      "send_codec_spec: {nack_enabled: true, transport_cc_enabled: false, "
      "cng_payload_type: 42, payload_type: 103, "
      "format: {name: isac, clockrate_hz: 16000, num_channels: 1, "
      "parameters: {}}}}",
      config.ToString());
}

TEST(AudioSendStreamTest, ConstructDestruct) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
}

TEST(AudioSendStreamTest, SendTelephoneEvent) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  helper.SetupMockForSendTelephoneEvent();
  EXPECT_TRUE(send_stream->SendTelephoneEvent(
      kTelephoneEventPayloadType, kTelephoneEventPayloadFrequency,
      kTelephoneEventCode, kTelephoneEventDuration));
}

TEST(AudioSendStreamTest, SetMuted) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(*helper.channel_send(), SetInputMute(true));
  send_stream->SetMuted(true);
}

TEST(AudioSendStreamTest, AudioBweCorrectObjectsOnChannelProxy) {
  ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
  ConfigHelper helper(true, true);
  auto send_stream = helper.CreateAudioSendStream();
}

TEST(AudioSendStreamTest, NoAudioBweCorrectObjectsOnChannelProxy) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
}

TEST(AudioSendStreamTest, GetStats) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  helper.SetupMockForGetStats();
  AudioSendStream::Stats stats = send_stream->GetStats(true);
  EXPECT_EQ(kSsrc, stats.local_ssrc);
  EXPECT_EQ(kCallStats.payload_bytes_sent, stats.payload_bytes_sent);
  EXPECT_EQ(kCallStats.header_and_padding_bytes_sent,
            stats.header_and_padding_bytes_sent);
  EXPECT_EQ(kCallStats.packetsSent, stats.packets_sent);
  EXPECT_EQ(kReportBlock.cumulative_num_packets_lost, stats.packets_lost);
  EXPECT_EQ(Q8ToFloat(kReportBlock.fraction_lost), stats.fraction_lost);
  EXPECT_EQ(kIsacFormat.name, stats.codec_name);
  EXPECT_EQ(static_cast<int32_t>(kReportBlock.interarrival_jitter /
                                 (kIsacFormat.clockrate_hz / 1000)),
            stats.jitter_ms);
  EXPECT_EQ(kCallStats.rttMs, stats.rtt_ms);
  EXPECT_EQ(0, stats.audio_level);
  EXPECT_EQ(0, stats.total_input_energy);
  EXPECT_EQ(0, stats.total_input_duration);
  EXPECT_EQ(kEchoDelayMedian, stats.apm_statistics.delay_median_ms);
  EXPECT_EQ(kEchoDelayStdDev, stats.apm_statistics.delay_standard_deviation_ms);
  EXPECT_EQ(kEchoReturnLoss, stats.apm_statistics.echo_return_loss);
  EXPECT_EQ(kEchoReturnLossEnhancement,
            stats.apm_statistics.echo_return_loss_enhancement);
  EXPECT_EQ(kDivergentFilterFraction,
            stats.apm_statistics.divergent_filter_fraction);
  EXPECT_EQ(kResidualEchoLikelihood,
            stats.apm_statistics.residual_echo_likelihood);
  EXPECT_EQ(kResidualEchoLikelihoodMax,
            stats.apm_statistics.residual_echo_likelihood_recent_max);
  EXPECT_FALSE(stats.typing_noise_detected);
}

TEST(AudioSendStreamTest, GetStatsAudioLevel) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  helper.SetupMockForGetStats();
  EXPECT_CALL(*helper.channel_send(), ProcessAndEncodeAudioForMock(_))
      .Times(AnyNumber());

  constexpr int kSampleRateHz = 48000;
  constexpr size_t kNumChannels = 1;

  constexpr int16_t kSilentAudioLevel = 0;
  constexpr int16_t kMaxAudioLevel = 32767;  // Audio level is [0,32767].
  constexpr int kAudioFrameDurationMs = 10;

  // Process 10 audio frames (100 ms) of silence. After this, on the next
  // (11-th) frame, the audio level will be updated with the maximum audio level
  // of the first 11 frames. See AudioLevel.
  for (size_t i = 0; i < 10; ++i) {
    send_stream->SendAudioData(CreateAudioFrame1kHzSineWave(
        kSilentAudioLevel, kAudioFrameDurationMs, kSampleRateHz, kNumChannels));
  }
  AudioSendStream::Stats stats = send_stream->GetStats();
  EXPECT_EQ(kSilentAudioLevel, stats.audio_level);
  EXPECT_NEAR(0.0f, stats.total_input_energy, kTolerance);
  EXPECT_NEAR(0.1f, stats.total_input_duration, kTolerance);  // 100 ms = 0.1 s

  // Process 10 audio frames (100 ms) of maximum audio level.
  // Note that AudioLevel updates the audio level every 11th frame, processing
  // 10 frames above was needed to see a non-zero audio level here.
  for (size_t i = 0; i < 10; ++i) {
    send_stream->SendAudioData(CreateAudioFrame1kHzSineWave(
        kMaxAudioLevel, kAudioFrameDurationMs, kSampleRateHz, kNumChannels));
  }
  stats = send_stream->GetStats();
  EXPECT_EQ(kMaxAudioLevel, stats.audio_level);
  // Energy increases by energy*duration, where energy is audio level in [0,1].
  EXPECT_NEAR(0.1f, stats.total_input_energy, kTolerance);    // 0.1 s of max
  EXPECT_NEAR(0.2f, stats.total_input_duration, kTolerance);  // 200 ms = 0.2 s
}

TEST(AudioSendStreamTest, SendCodecAppliesAudioNetworkAdaptor) {
  ConfigHelper helper(false, true);
  helper.config().send_codec_spec =
      AudioSendStream::Config::SendCodecSpec(0, kOpusFormat);
  const std::string kAnaConfigString = "abcde";
  const std::string kAnaReconfigString = "12345";

  helper.config().audio_network_adaptor_config = kAnaConfigString;

  EXPECT_CALL(helper.mock_encoder_factory(), MakeAudioEncoderMock(_, _, _, _))
      .WillOnce(Invoke([&kAnaConfigString, &kAnaReconfigString](
                           int payload_type, const SdpAudioFormat& format,
                           absl::optional<AudioCodecPairId> codec_pair_id,
                           std::unique_ptr<AudioEncoder>* return_value) {
        auto mock_encoder = SetupAudioEncoderMock(payload_type, format);
        EXPECT_CALL(*mock_encoder,
                    EnableAudioNetworkAdaptor(StrEq(kAnaConfigString), _))
            .WillOnce(Return(true));
        EXPECT_CALL(*mock_encoder,
                    EnableAudioNetworkAdaptor(StrEq(kAnaReconfigString), _))
            .WillOnce(Return(true));
        *return_value = std::move(mock_encoder);
      }));

  auto send_stream = helper.CreateAudioSendStream();

  auto stream_config = helper.config();
  stream_config.audio_network_adaptor_config = kAnaReconfigString;

  helper.SetupMockForCallEncoder();
  send_stream->Reconfigure(stream_config);
}

// VAD is applied when codec is mono and the CNG frequency matches the codec
// clock rate.
TEST(AudioSendStreamTest, SendCodecCanApplyVad) {
  ConfigHelper helper(false, false);
  helper.config().send_codec_spec =
      AudioSendStream::Config::SendCodecSpec(9, kG722Format);
  helper.config().send_codec_spec->cng_payload_type = 105;
  using ::testing::Invoke;
  std::unique_ptr<AudioEncoder> stolen_encoder;
  EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
      .WillOnce(
          Invoke([&stolen_encoder](int payload_type,
                                   std::unique_ptr<AudioEncoder>* encoder) {
            stolen_encoder = std::move(*encoder);
            return true;
          }));
  EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));

  auto send_stream = helper.CreateAudioSendStream();

  // We cannot truly determine if the encoder created is an AudioEncoderCng.  It
  // is the only reasonable implementation that will return something from
  // ReclaimContainedEncoders, though.
  ASSERT_TRUE(stolen_encoder);
  EXPECT_FALSE(stolen_encoder->ReclaimContainedEncoders().empty());
}

TEST(AudioSendStreamTest, DoesNotPassHigherBitrateThanMaxBitrate) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(*helper.channel_send(),
              OnBitrateAllocation(
                  Field(&BitrateAllocationUpdate::target_bitrate,
                        Eq(DataRate::bps(helper.config().max_bitrate_bps)))));
  BitrateAllocationUpdate update;
  update.target_bitrate = DataRate::bps(helper.config().max_bitrate_bps + 5000);
  update.packet_loss_ratio = 0;
  update.round_trip_time = TimeDelta::ms(50);
  update.bwe_period = TimeDelta::ms(6000);
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

TEST(AudioSendStreamTest, SSBweTargetInRangeRespected) {
  ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
  ConfigHelper helper(true, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(*helper.channel_send(),
              OnBitrateAllocation(Field(
                  &BitrateAllocationUpdate::target_bitrate,
                  Eq(DataRate::bps(helper.config().max_bitrate_bps - 5000)))));
  BitrateAllocationUpdate update;
  update.target_bitrate = DataRate::bps(helper.config().max_bitrate_bps - 5000);
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

TEST(AudioSendStreamTest, SSBweFieldTrialMinRespected) {
  ScopedFieldTrials field_trials(
      "WebRTC-Audio-SendSideBwe/Enabled/"
      "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
  ConfigHelper helper(true, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(
      *helper.channel_send(),
      OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
                                Eq(DataRate::kbps(6)))));
  BitrateAllocationUpdate update;
  update.target_bitrate = DataRate::kbps(1);
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

TEST(AudioSendStreamTest, SSBweFieldTrialMaxRespected) {
  ScopedFieldTrials field_trials(
      "WebRTC-Audio-SendSideBwe/Enabled/"
      "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
  ConfigHelper helper(true, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(
      *helper.channel_send(),
      OnBitrateAllocation(Field(&BitrateAllocationUpdate::target_bitrate,
                                Eq(DataRate::kbps(64)))));
  BitrateAllocationUpdate update;
  update.target_bitrate = DataRate::kbps(128);
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

TEST(AudioSendStreamTest, SSBweWithOverhead) {
  ScopedFieldTrials field_trials(
      "WebRTC-Audio-SendSideBwe/Enabled/"
      "WebRTC-SendSideBwe-WithOverhead/Enabled/"
      "WebRTC-Audio-LegacyOverhead/Disabled/");
  ConfigHelper helper(true, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
  send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
  const DataRate bitrate =
      DataRate::bps(helper.config().max_bitrate_bps) + kMaxOverheadRate;
  EXPECT_CALL(*helper.channel_send(),
              OnBitrateAllocation(Field(
                  &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
  BitrateAllocationUpdate update;
  update.target_bitrate = bitrate;
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

TEST(AudioSendStreamTest, SSBweWithOverheadMinRespected) {
  ScopedFieldTrials field_trials(
      "WebRTC-Audio-SendSideBwe/Enabled/"
      "WebRTC-SendSideBwe-WithOverhead/Enabled/"
      "WebRTC-Audio-LegacyOverhead/Disabled/"
      "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
  ConfigHelper helper(true, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
  send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
  const DataRate bitrate = DataRate::kbps(6) + kMinOverheadRate;
  EXPECT_CALL(*helper.channel_send(),
              OnBitrateAllocation(Field(
                  &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
  BitrateAllocationUpdate update;
  update.target_bitrate = DataRate::kbps(1);
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

TEST(AudioSendStreamTest, SSBweWithOverheadMaxRespected) {
  ScopedFieldTrials field_trials(
      "WebRTC-Audio-SendSideBwe/Enabled/"
      "WebRTC-SendSideBwe-WithOverhead/Enabled/"
      "WebRTC-Audio-LegacyOverhead/Disabled/"
      "WebRTC-Audio-Allocation/min:6kbps,max:64kbps/");
  ConfigHelper helper(true, true);
  auto send_stream = helper.CreateAudioSendStream();
  EXPECT_CALL(*helper.channel_send(), CallEncoder(_)).Times(1);
  send_stream->OnOverheadChanged(kOverheadPerPacket.bytes<size_t>());
  const DataRate bitrate = DataRate::kbps(64) + kMaxOverheadRate;
  EXPECT_CALL(*helper.channel_send(),
              OnBitrateAllocation(Field(
                  &BitrateAllocationUpdate::target_bitrate, Eq(bitrate))));
  BitrateAllocationUpdate update;
  update.target_bitrate = DataRate::kbps(128);
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

TEST(AudioSendStreamTest, ProbingIntervalOnBitrateUpdated) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();

  EXPECT_CALL(*helper.channel_send(),
              OnBitrateAllocation(Field(&BitrateAllocationUpdate::bwe_period,
                                        Eq(TimeDelta::ms(5000)))));
  BitrateAllocationUpdate update;
  update.target_bitrate = DataRate::bps(helper.config().max_bitrate_bps + 5000);
  update.packet_loss_ratio = 0;
  update.round_trip_time = TimeDelta::ms(50);
  update.bwe_period = TimeDelta::ms(5000);
  helper.worker()->SendTask([&] { send_stream->OnBitrateUpdated(update); },
                            RTC_FROM_HERE);
}

// Test that AudioSendStream doesn't recreate the encoder unnecessarily.
TEST(AudioSendStreamTest, DontRecreateEncoder) {
  ConfigHelper helper(false, false);
  // WillOnce is (currently) the default used by ConfigHelper if asked to set an
  // expectation for SetEncoder. Since this behavior is essential for this test
  // to be correct, it's instead set-up manually here. Otherwise a simple change
  // to ConfigHelper (say to WillRepeatedly) would silently make this test
  // useless.
  EXPECT_CALL(*helper.channel_send(), SetEncoderForMock(_, _))
      .WillOnce(Return());

  EXPECT_CALL(*helper.channel_send(), RegisterCngPayloadType(105, 8000));

  helper.config().send_codec_spec =
      AudioSendStream::Config::SendCodecSpec(9, kG722Format);
  helper.config().send_codec_spec->cng_payload_type = 105;
  auto send_stream = helper.CreateAudioSendStream();
  send_stream->Reconfigure(helper.config());
}

TEST(AudioSendStreamTest, ReconfigureTransportCcResetsFirst) {
  ScopedFieldTrials field_trials("WebRTC-Audio-SendSideBwe/Enabled/");
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  auto new_config = helper.config();
  ConfigHelper::AddBweToConfig(&new_config);

  EXPECT_CALL(*helper.rtp_rtcp(),
              RegisterRtpHeaderExtension(TransportSequenceNumber::kUri,
                                         kTransportSequenceNumberId))
      .Times(1);
  {
    ::testing::InSequence seq;
    EXPECT_CALL(*helper.channel_send(), ResetSenderCongestionControlObjects())
        .Times(1);
    EXPECT_CALL(*helper.channel_send(), RegisterSenderCongestionControlObjects(
                                            helper.transport(), Ne(nullptr)))
        .Times(1);
  }

  send_stream->Reconfigure(new_config);
}

TEST(AudioSendStreamTest, OnTransportOverheadChanged) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  auto new_config = helper.config();

  // CallEncoder will be called on overhead change.
  EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(1);

  const size_t transport_overhead_per_packet_bytes = 333;
  send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);

  EXPECT_EQ(transport_overhead_per_packet_bytes,
            send_stream->TestOnlyGetPerPacketOverheadBytes());
}

TEST(AudioSendStreamTest, OnAudioOverheadChanged) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  auto new_config = helper.config();

  // CallEncoder will be called on overhead change.
  EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(1);

  const size_t audio_overhead_per_packet_bytes = 555;
  send_stream->OnOverheadChanged(audio_overhead_per_packet_bytes);
  EXPECT_EQ(audio_overhead_per_packet_bytes,
            send_stream->TestOnlyGetPerPacketOverheadBytes());
}

TEST(AudioSendStreamTest, OnAudioAndTransportOverheadChanged) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  auto new_config = helper.config();

  // CallEncoder will be called when each of overhead changes.
  EXPECT_CALL(*helper.channel_send(), CallEncoder(::testing::_)).Times(2);

  const size_t transport_overhead_per_packet_bytes = 333;
  send_stream->SetTransportOverhead(transport_overhead_per_packet_bytes);

  const size_t audio_overhead_per_packet_bytes = 555;
  send_stream->OnOverheadChanged(audio_overhead_per_packet_bytes);

  EXPECT_EQ(
      transport_overhead_per_packet_bytes + audio_overhead_per_packet_bytes,
      send_stream->TestOnlyGetPerPacketOverheadBytes());
}

// Validates that reconfiguring the AudioSendStream with a Frame encryptor
// correctly reconfigures on the object without crashing.
TEST(AudioSendStreamTest, ReconfigureWithFrameEncryptor) {
  ConfigHelper helper(false, true);
  auto send_stream = helper.CreateAudioSendStream();
  auto new_config = helper.config();

  rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_0(
      new rtc::RefCountedObject<MockFrameEncryptor>());
  new_config.frame_encryptor = mock_frame_encryptor_0;
  EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr))).Times(1);
  send_stream->Reconfigure(new_config);

  // Not updating the frame encryptor shouldn't force it to reconfigure.
  EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(_)).Times(0);
  send_stream->Reconfigure(new_config);

  // Updating frame encryptor to a new object should force a call to the proxy.
  rtc::scoped_refptr<FrameEncryptorInterface> mock_frame_encryptor_1(
      new rtc::RefCountedObject<MockFrameEncryptor>());
  new_config.frame_encryptor = mock_frame_encryptor_1;
  new_config.crypto_options.sframe.require_frame_encryption = true;
  EXPECT_CALL(*helper.channel_send(), SetFrameEncryptor(Ne(nullptr))).Times(1);
  send_stream->Reconfigure(new_config);
}
}  // namespace test
}  // namespace webrtc
