/*
 *  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 <list>
#include <map>
#include <memory>
#include <utility>

#include "api/test/mock_audio_mixer.h"
#include "call/audio_state.h"
#include "call/call.h"
#include "call/fake_rtp_transport_controller_send.h"
#include "logging/rtc_event_log/rtc_event_log.h"
#include "modules/audio_device/include/mock_audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
#include "modules/congestion_controller/include/mock/mock_send_side_congestion_controller.h"
#include "modules/pacing/mock/mock_paced_sender.h"
#include "modules/rtp_rtcp/include/rtp_rtcp.h"
#include "rtc_base/ptr_util.h"
#include "test/fake_encoder.h"
#include "test/gtest.h"
#include "test/mock_audio_decoder_factory.h"
#include "test/mock_transport.h"
#include "test/mock_voice_engine.h"

namespace {

struct CallHelper {
  explicit CallHelper(
      rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory = nullptr)
      : voice_engine_(decoder_factory) {
    webrtc::AudioState::Config audio_state_config;
    audio_state_config.voice_engine = &voice_engine_;
    audio_state_config.audio_mixer = webrtc::AudioMixerImpl::Create();
    audio_state_config.audio_processing = webrtc::AudioProcessing::Create();
    EXPECT_CALL(voice_engine_, audio_device_module());
    EXPECT_CALL(voice_engine_, audio_transport());
    webrtc::Call::Config config(&event_log_);
    config.audio_state = webrtc::AudioState::Create(audio_state_config);
    call_.reset(webrtc::Call::Create(config));
  }

  webrtc::Call* operator->() { return call_.get(); }
  webrtc::test::MockVoiceEngine* voice_engine() { return &voice_engine_; }

 private:
  testing::NiceMock<webrtc::test::MockVoiceEngine> voice_engine_;
  webrtc::RtcEventLogNullImpl event_log_;
  std::unique_ptr<webrtc::Call> call_;
};
}  // namespace

namespace webrtc {

TEST(CallTest, ConstructDestruct) {
  CallHelper call;
}

TEST(CallTest, CreateDestroy_AudioSendStream) {
  CallHelper call;
  AudioSendStream::Config config(nullptr);
  config.rtp.ssrc = 42;
  config.voe_channel_id = 123;
  AudioSendStream* stream = call->CreateAudioSendStream(config);
  EXPECT_NE(stream, nullptr);
  call->DestroyAudioSendStream(stream);
}

TEST(CallTest, CreateDestroy_AudioReceiveStream) {
  rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
      new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
  CallHelper call(decoder_factory);
  AudioReceiveStream::Config config;
  config.rtp.remote_ssrc = 42;
  config.voe_channel_id = 123;
  config.decoder_factory = decoder_factory;
  AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
  EXPECT_NE(stream, nullptr);
  call->DestroyAudioReceiveStream(stream);
}

TEST(CallTest, CreateDestroy_AudioSendStreams) {
  CallHelper call;
  AudioSendStream::Config config(nullptr);
  config.voe_channel_id = 123;
  std::list<AudioSendStream*> streams;
  for (int i = 0; i < 2; ++i) {
    for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
      config.rtp.ssrc = ssrc;
      AudioSendStream* stream = call->CreateAudioSendStream(config);
      EXPECT_NE(stream, nullptr);
      if (ssrc & 1) {
        streams.push_back(stream);
      } else {
        streams.push_front(stream);
      }
    }
    for (auto s : streams) {
      call->DestroyAudioSendStream(s);
    }
    streams.clear();
  }
}

TEST(CallTest, CreateDestroy_AudioReceiveStreams) {
  rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
      new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
  CallHelper call(decoder_factory);
  AudioReceiveStream::Config config;
  config.voe_channel_id = 123;
  config.decoder_factory = decoder_factory;
  std::list<AudioReceiveStream*> streams;
  for (int i = 0; i < 2; ++i) {
    for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
      config.rtp.remote_ssrc = ssrc;
      AudioReceiveStream* stream = call->CreateAudioReceiveStream(config);
      EXPECT_NE(stream, nullptr);
      if (ssrc & 1) {
        streams.push_back(stream);
      } else {
        streams.push_front(stream);
      }
    }
    for (auto s : streams) {
      call->DestroyAudioReceiveStream(s);
    }
    streams.clear();
  }
}

TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_RecvFirst) {
  rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
      new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
  CallHelper call(decoder_factory);
  ::testing::NiceMock<MockRtpRtcp> mock_rtp_rtcp;

  constexpr int kRecvChannelId = 101;

  // Set up the mock to create a channel proxy which we know of, so that we can
  // add our expectations to it.
  test::MockVoEChannelProxy* recv_channel_proxy = nullptr;
  EXPECT_CALL(*call.voice_engine(), ChannelProxyFactory(testing::_))
      .WillRepeatedly(testing::Invoke([&](int channel_id) {
        test::MockVoEChannelProxy* channel_proxy =
            new testing::NiceMock<test::MockVoEChannelProxy>();
        EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
            .WillRepeatedly(testing::ReturnRef(decoder_factory));
        EXPECT_CALL(*channel_proxy, SetReceiveCodecs(testing::_))
            .WillRepeatedly(testing::Invoke(
                [](const std::map<int, SdpAudioFormat>& codecs) {
                  EXPECT_THAT(codecs, testing::IsEmpty());
                }));
        EXPECT_CALL(*channel_proxy, GetRtpRtcp(testing::_, testing::_))
            .WillRepeatedly(testing::SetArgPointee<0>(&mock_rtp_rtcp));
        // If being called for the send channel, save a pointer to the channel
        // proxy for later.
        if (channel_id == kRecvChannelId) {
          EXPECT_FALSE(recv_channel_proxy);
          recv_channel_proxy = channel_proxy;
        }
        return channel_proxy;
      }));

  AudioReceiveStream::Config recv_config;
  recv_config.rtp.remote_ssrc = 42;
  recv_config.rtp.local_ssrc = 777;
  recv_config.voe_channel_id = kRecvChannelId;
  recv_config.decoder_factory = decoder_factory;
  AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
  EXPECT_NE(recv_stream, nullptr);

  EXPECT_CALL(*recv_channel_proxy, AssociateSendChannel(testing::_)).Times(1);
  AudioSendStream::Config send_config(nullptr);
  send_config.rtp.ssrc = 777;
  send_config.voe_channel_id = 123;
  AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
  EXPECT_NE(send_stream, nullptr);

  EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
  call->DestroyAudioSendStream(send_stream);

  EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
  call->DestroyAudioReceiveStream(recv_stream);
}

TEST(CallTest, CreateDestroy_AssociateAudioSendReceiveStreams_SendFirst) {
  rtc::scoped_refptr<webrtc::AudioDecoderFactory> decoder_factory(
      new rtc::RefCountedObject<webrtc::MockAudioDecoderFactory>);
  CallHelper call(decoder_factory);
  ::testing::NiceMock<MockRtpRtcp> mock_rtp_rtcp;

  constexpr int kRecvChannelId = 101;

  // Set up the mock to create a channel proxy which we know of, so that we can
  // add our expectations to it.
  test::MockVoEChannelProxy* recv_channel_proxy = nullptr;
  EXPECT_CALL(*call.voice_engine(), ChannelProxyFactory(testing::_))
      .WillRepeatedly(testing::Invoke([&](int channel_id) {
        test::MockVoEChannelProxy* channel_proxy =
            new testing::NiceMock<test::MockVoEChannelProxy>();
        EXPECT_CALL(*channel_proxy, GetAudioDecoderFactory())
            .WillRepeatedly(testing::ReturnRef(decoder_factory));
        EXPECT_CALL(*channel_proxy, SetReceiveCodecs(testing::_))
            .WillRepeatedly(testing::Invoke(
                [](const std::map<int, SdpAudioFormat>& codecs) {
                  EXPECT_THAT(codecs, testing::IsEmpty());
                }));
        EXPECT_CALL(*channel_proxy, GetRtpRtcp(testing::_, testing::_))
            .WillRepeatedly(testing::SetArgPointee<0>(&mock_rtp_rtcp));
        // If being called for the send channel, save a pointer to the channel
        // proxy for later.
        if (channel_id == kRecvChannelId) {
          EXPECT_FALSE(recv_channel_proxy);
          recv_channel_proxy = channel_proxy;
          // We need to set this expectation here since the channel proxy is
          // created as a side effect of CreateAudioReceiveStream().
          EXPECT_CALL(*recv_channel_proxy,
                      AssociateSendChannel(testing::_)).Times(1);
        }
        return channel_proxy;
      }));

  AudioSendStream::Config send_config(nullptr);
  send_config.rtp.ssrc = 777;
  send_config.voe_channel_id = 123;
  AudioSendStream* send_stream = call->CreateAudioSendStream(send_config);
  EXPECT_NE(send_stream, nullptr);

  AudioReceiveStream::Config recv_config;
  recv_config.rtp.remote_ssrc = 42;
  recv_config.rtp.local_ssrc = 777;
  recv_config.voe_channel_id = kRecvChannelId;
  recv_config.decoder_factory = decoder_factory;
  AudioReceiveStream* recv_stream = call->CreateAudioReceiveStream(recv_config);
  EXPECT_NE(recv_stream, nullptr);

  EXPECT_CALL(*recv_channel_proxy, DisassociateSendChannel()).Times(1);
  call->DestroyAudioReceiveStream(recv_stream);

  call->DestroyAudioSendStream(send_stream);
}

TEST(CallTest, CreateDestroy_FlexfecReceiveStream) {
  CallHelper call;
  MockTransport rtcp_send_transport;
  FlexfecReceiveStream::Config config(&rtcp_send_transport);
  config.payload_type = 118;
  config.remote_ssrc = 38837212;
  config.protected_media_ssrcs = {27273};

  FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
  EXPECT_NE(stream, nullptr);
  call->DestroyFlexfecReceiveStream(stream);
}

TEST(CallTest, CreateDestroy_FlexfecReceiveStreams) {
  CallHelper call;
  MockTransport rtcp_send_transport;
  FlexfecReceiveStream::Config config(&rtcp_send_transport);
  config.payload_type = 118;
  std::list<FlexfecReceiveStream*> streams;

  for (int i = 0; i < 2; ++i) {
    for (uint32_t ssrc = 0; ssrc < 1234567; ssrc += 34567) {
      config.remote_ssrc = ssrc;
      config.protected_media_ssrcs = {ssrc + 1};
      FlexfecReceiveStream* stream = call->CreateFlexfecReceiveStream(config);
      EXPECT_NE(stream, nullptr);
      if (ssrc & 1) {
        streams.push_back(stream);
      } else {
        streams.push_front(stream);
      }
    }
    for (auto s : streams) {
      call->DestroyFlexfecReceiveStream(s);
    }
    streams.clear();
  }
}

TEST(CallTest, MultipleFlexfecReceiveStreamsProtectingSingleVideoStream) {
  CallHelper call;
  MockTransport rtcp_send_transport;
  FlexfecReceiveStream::Config config(&rtcp_send_transport);
  config.payload_type = 118;
  config.protected_media_ssrcs = {1324234};
  FlexfecReceiveStream* stream;
  std::list<FlexfecReceiveStream*> streams;

  config.remote_ssrc = 838383;
  stream = call->CreateFlexfecReceiveStream(config);
  EXPECT_NE(stream, nullptr);
  streams.push_back(stream);

  config.remote_ssrc = 424993;
  stream = call->CreateFlexfecReceiveStream(config);
  EXPECT_NE(stream, nullptr);
  streams.push_back(stream);

  config.remote_ssrc = 99383;
  stream = call->CreateFlexfecReceiveStream(config);
  EXPECT_NE(stream, nullptr);
  streams.push_back(stream);

  config.remote_ssrc = 5548;
  stream = call->CreateFlexfecReceiveStream(config);
  EXPECT_NE(stream, nullptr);
  streams.push_back(stream);

  for (auto s : streams) {
    call->DestroyFlexfecReceiveStream(s);
  }
}

namespace {
struct CallBitrateHelper {
  CallBitrateHelper() : CallBitrateHelper(Call::Config::BitrateConfig()) {}

  explicit CallBitrateHelper(const Call::Config::BitrateConfig& bitrate_config)
      : mock_cc_(Clock::GetRealTimeClock(), &event_log_, &pacer_) {
    Call::Config config(&event_log_);
    config.bitrate_config = bitrate_config;
    call_.reset(
        Call::Create(config, rtc::MakeUnique<FakeRtpTransportControllerSend>(
                                 &packet_router_, &pacer_, &mock_cc_)));
  }

  webrtc::Call* operator->() { return call_.get(); }
  testing::NiceMock<test::MockSendSideCongestionController>& mock_cc() {
    return mock_cc_;
  }

 private:
  webrtc::RtcEventLogNullImpl event_log_;
  PacketRouter packet_router_;
  testing::NiceMock<MockPacedSender> pacer_;
  testing::NiceMock<test::MockSendSideCongestionController> mock_cc_;
  std::unique_ptr<Call> call_;
};
}  // namespace

TEST(CallBitrateTest, SetBitrateConfigWithValidConfigCallsSetBweBitrates) {
  CallBitrateHelper call;

  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 1;
  bitrate_config.start_bitrate_bps = 2;
  bitrate_config.max_bitrate_bps = 3;

  EXPECT_CALL(call.mock_cc(), SetBweBitrates(1, 2, 3));
  call->SetBitrateConfig(bitrate_config);
}

TEST(CallBitrateTest, SetBitrateConfigWithDifferentMinCallsSetBweBitrates) {
  CallBitrateHelper call;

  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 10;
  bitrate_config.start_bitrate_bps = 20;
  bitrate_config.max_bitrate_bps = 30;
  call->SetBitrateConfig(bitrate_config);

  bitrate_config.min_bitrate_bps = 11;
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(11, -1, 30));
  call->SetBitrateConfig(bitrate_config);
}

TEST(CallBitrateTest, SetBitrateConfigWithDifferentStartCallsSetBweBitrates) {
  CallBitrateHelper call;

  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 10;
  bitrate_config.start_bitrate_bps = 20;
  bitrate_config.max_bitrate_bps = 30;
  call->SetBitrateConfig(bitrate_config);

  bitrate_config.start_bitrate_bps = 21;
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(10, 21, 30));
  call->SetBitrateConfig(bitrate_config);
}

TEST(CallBitrateTest, SetBitrateConfigWithDifferentMaxCallsSetBweBitrates) {
  CallBitrateHelper call;

  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 10;
  bitrate_config.start_bitrate_bps = 20;
  bitrate_config.max_bitrate_bps = 30;
  call->SetBitrateConfig(bitrate_config);

  bitrate_config.max_bitrate_bps = 31;
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(10, -1, 31));
  call->SetBitrateConfig(bitrate_config);
}

TEST(CallBitrateTest, SetBitrateConfigWithSameConfigElidesSecondCall) {
  CallBitrateHelper call;
  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 1;
  bitrate_config.start_bitrate_bps = 2;
  bitrate_config.max_bitrate_bps = 3;

  EXPECT_CALL(call.mock_cc(), SetBweBitrates(1, 2, 3)).Times(1);
  call->SetBitrateConfig(bitrate_config);
  call->SetBitrateConfig(bitrate_config);
}

TEST(CallBitrateTest,
     SetBitrateConfigWithSameMinMaxAndNegativeStartElidesSecondCall) {
  CallBitrateHelper call;

  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 1;
  bitrate_config.start_bitrate_bps = 2;
  bitrate_config.max_bitrate_bps = 3;

  EXPECT_CALL(call.mock_cc(), SetBweBitrates(1, 2, 3)).Times(1);
  call->SetBitrateConfig(bitrate_config);

  bitrate_config.start_bitrate_bps = -1;
  call->SetBitrateConfig(bitrate_config);
}

TEST(CallTest, RecreatingAudioStreamWithSameSsrcReusesRtpState) {
  constexpr uint32_t kSSRC = 12345;
  testing::NiceMock<test::MockAudioDeviceModule> mock_adm;
  // Reply with a 10ms timer every time TimeUntilNextProcess is called to
  // avoid entering a tight loop on the process thread.
  EXPECT_CALL(mock_adm, TimeUntilNextProcess())
       .WillRepeatedly(testing::Return(10));
  rtc::scoped_refptr<test::MockAudioMixer> mock_mixer(
      new rtc::RefCountedObject<test::MockAudioMixer>);

  // There's similar functionality in cricket::VoEWrapper but it's not reachable
  // from here. Since we're working on removing VoE interfaces, I doubt it's
  // worth making VoEWrapper more easily available.
  struct ScopedVoiceEngine {
    ScopedVoiceEngine()
        : voe(VoiceEngine::Create()),
          base(VoEBase::GetInterface(voe)) {}
    ~ScopedVoiceEngine() {
      base->Release();
      EXPECT_TRUE(VoiceEngine::Delete(voe));
    }

    VoiceEngine* voe;
    VoEBase* base;
  };
  ScopedVoiceEngine voice_engine;

  AudioState::Config audio_state_config;
  audio_state_config.voice_engine = voice_engine.voe;
  audio_state_config.audio_mixer = mock_mixer;
  audio_state_config.audio_processing = AudioProcessing::Create();
  voice_engine.base->Init(&mock_adm, audio_state_config.audio_processing.get());
  auto audio_state = AudioState::Create(audio_state_config);

  RtcEventLogNullImpl event_log;
  Call::Config call_config(&event_log);
  call_config.audio_state = audio_state;
  std::unique_ptr<Call> call(Call::Create(call_config));

  auto create_stream_and_get_rtp_state = [&](uint32_t ssrc) {
    AudioSendStream::Config config(nullptr);
    config.rtp.ssrc = ssrc;
    config.voe_channel_id = voice_engine.base->CreateChannel();
    AudioSendStream* stream = call->CreateAudioSendStream(config);
    VoiceEngineImpl* voe_impl = static_cast<VoiceEngineImpl*>(voice_engine.voe);
    auto channel_proxy = voe_impl->GetChannelProxy(config.voe_channel_id);
    RtpRtcp* rtp_rtcp = nullptr;
    RtpReceiver* rtp_receiver = nullptr;  // Unused but required for call.
    channel_proxy->GetRtpRtcp(&rtp_rtcp, &rtp_receiver);
    const RtpState rtp_state = rtp_rtcp->GetRtpState();
    call->DestroyAudioSendStream(stream);
    voice_engine.base->DeleteChannel(config.voe_channel_id);
    return rtp_state;
  };

  const RtpState rtp_state1 = create_stream_and_get_rtp_state(kSSRC);
  const RtpState rtp_state2 = create_stream_and_get_rtp_state(kSSRC);

  EXPECT_EQ(rtp_state1.sequence_number, rtp_state2.sequence_number);
  EXPECT_EQ(rtp_state1.start_timestamp, rtp_state2.start_timestamp);
  EXPECT_EQ(rtp_state1.timestamp, rtp_state2.timestamp);
  EXPECT_EQ(rtp_state1.capture_time_ms, rtp_state2.capture_time_ms);
  EXPECT_EQ(rtp_state1.last_timestamp_time_ms,
            rtp_state2.last_timestamp_time_ms);
  EXPECT_EQ(rtp_state1.media_has_been_sent, rtp_state2.media_has_been_sent);
}
TEST(CallBitrateTest, BiggerMaskMinUsed) {
  CallBitrateHelper call;
  Call::Config::BitrateConfigMask mask;
  mask.min_bitrate_bps = rtc::Optional<int>(1234);

  EXPECT_CALL(call.mock_cc(),
              SetBweBitrates(*mask.min_bitrate_bps, testing::_, testing::_));
  call->SetBitrateConfigMask(mask);
}

TEST(CallBitrateTest, BiggerConfigMinUsed) {
  CallBitrateHelper call;
  Call::Config::BitrateConfigMask mask;
  mask.min_bitrate_bps = rtc::Optional<int>(1000);
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(1000, testing::_, testing::_));
  call->SetBitrateConfigMask(mask);

  Call::Config::BitrateConfig config;
  config.min_bitrate_bps = 1234;

  EXPECT_CALL(call.mock_cc(), SetBweBitrates(1234, testing::_, testing::_));
  call->SetBitrateConfig(config);
}

// The last call to set start should be used.
TEST(CallBitrateTest, LatestStartMaskPreferred) {
  CallBitrateHelper call;
  Call::Config::BitrateConfigMask mask;
  mask.start_bitrate_bps = rtc::Optional<int>(1300);

  EXPECT_CALL(call.mock_cc(),
              SetBweBitrates(testing::_, *mask.start_bitrate_bps, testing::_));
  call->SetBitrateConfigMask(mask);

  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.start_bitrate_bps = 1200;

  EXPECT_CALL(
      call.mock_cc(),
      SetBweBitrates(testing::_, bitrate_config.start_bitrate_bps, testing::_));
  call->SetBitrateConfig(bitrate_config);
}

TEST(CallBitrateTest, SmallerMaskMaxUsed) {
  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.max_bitrate_bps = bitrate_config.start_bitrate_bps + 2000;
  CallBitrateHelper call(bitrate_config);

  Call::Config::BitrateConfigMask mask;
  mask.max_bitrate_bps =
      rtc::Optional<int>(bitrate_config.start_bitrate_bps + 1000);

  EXPECT_CALL(call.mock_cc(),
              SetBweBitrates(testing::_, testing::_, *mask.max_bitrate_bps));
  call->SetBitrateConfigMask(mask);
}

TEST(CallBitrateTest, SmallerConfigMaxUsed) {
  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.max_bitrate_bps = bitrate_config.start_bitrate_bps + 1000;
  CallBitrateHelper call(bitrate_config);

  Call::Config::BitrateConfigMask mask;
  mask.max_bitrate_bps =
      rtc::Optional<int>(bitrate_config.start_bitrate_bps + 2000);

  // Expect no calls because nothing changes
  EXPECT_CALL(call.mock_cc(),
              SetBweBitrates(testing::_, testing::_, testing::_))
      .Times(0);
  call->SetBitrateConfigMask(mask);
}

TEST(CallBitrateTest, MaskStartLessThanConfigMinClamped) {
  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 2000;
  CallBitrateHelper call(bitrate_config);

  Call::Config::BitrateConfigMask mask;
  mask.start_bitrate_bps = rtc::Optional<int>(1000);

  EXPECT_CALL(call.mock_cc(), SetBweBitrates(2000, 2000, testing::_));
  call->SetBitrateConfigMask(mask);
}

TEST(CallBitrateTest, MaskStartGreaterThanConfigMaxClamped) {
  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.start_bitrate_bps = 2000;
  CallBitrateHelper call(bitrate_config);

  Call::Config::BitrateConfigMask mask;
  mask.max_bitrate_bps = rtc::Optional<int>(1000);

  EXPECT_CALL(call.mock_cc(), SetBweBitrates(testing::_, -1, 1000));
  call->SetBitrateConfigMask(mask);
}

TEST(CallBitrateTest, MaskMinGreaterThanConfigMaxClamped) {
  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.min_bitrate_bps = 2000;
  CallBitrateHelper call(bitrate_config);

  Call::Config::BitrateConfigMask mask;
  mask.max_bitrate_bps = rtc::Optional<int>(1000);

  EXPECT_CALL(call.mock_cc(), SetBweBitrates(1000, testing::_, 1000));
  call->SetBitrateConfigMask(mask);
}

TEST(CallBitrateTest, SettingMaskStartForcesUpdate) {
  CallBitrateHelper call;

  Call::Config::BitrateConfigMask mask;
  mask.start_bitrate_bps = rtc::Optional<int>(1000);

  // SetBweBitrates should be called twice with the same params since
  // start_bitrate_bps is set.
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(testing::_, 1000, testing::_))
      .Times(2);
  call->SetBitrateConfigMask(mask);
  call->SetBitrateConfigMask(mask);
}

TEST(CallBitrateTest, SetBitrateConfigWithNoChangesDoesNotCallSetBweBitrates) {
  CallBitrateHelper call;

  Call::Config::BitrateConfig config1;
  config1.min_bitrate_bps = 0;
  config1.start_bitrate_bps = 1000;
  config1.max_bitrate_bps = -1;

  Call::Config::BitrateConfig config2;
  config2.min_bitrate_bps = 0;
  config2.start_bitrate_bps = -1;
  config2.max_bitrate_bps = -1;

  // The second call should not call SetBweBitrates because it doesn't
  // change any values.
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(0, 1000, -1));
  call->SetBitrateConfig(config1);
  call->SetBitrateConfig(config2);
}

// If SetBitrateConfig changes the max, but not the effective max,
// SetBweBitrates shouldn't be called, to avoid unnecessary encoder
// reconfigurations.
TEST(CallBitrateTest, SetBweBitratesNotCalledWhenEffectiveMaxUnchanged) {
  CallBitrateHelper call;

  Call::Config::BitrateConfig config;
  config.min_bitrate_bps = 0;
  config.start_bitrate_bps = -1;
  config.max_bitrate_bps = 2000;
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(testing::_, testing::_, 2000));
  call->SetBitrateConfig(config);

  // Reduce effective max to 1000 with the mask.
  Call::Config::BitrateConfigMask mask;
  mask.max_bitrate_bps = rtc::Optional<int>(1000);
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(testing::_, testing::_, 1000));
  call->SetBitrateConfigMask(mask);

  // This leaves the effective max unchanged, so SetBweBitrates shouldn't be
  // called again.
  config.max_bitrate_bps = 1000;
  call->SetBitrateConfig(config);
}

// When the "start bitrate" mask is removed, SetBweBitrates shouldn't be called
// again, since nothing's changing.
TEST(CallBitrateTest, SetBweBitratesNotCalledWhenStartMaskRemoved) {
  CallBitrateHelper call;

  Call::Config::BitrateConfigMask mask;
  mask.start_bitrate_bps = rtc::Optional<int>(1000);
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(0, 1000, -1));
  call->SetBitrateConfigMask(mask);

  mask.start_bitrate_bps.reset();
  call->SetBitrateConfigMask(mask);
}

// Test that if SetBitrateConfig is called after SetBitrateConfigMask applies a
// "start" value, the SetBitrateConfig call won't apply that start value a
// second time.
TEST(CallBitrateTest, SetBitrateConfigAfterSetBitrateConfigMaskWithStart) {
  CallBitrateHelper call;

  Call::Config::BitrateConfigMask mask;
  mask.start_bitrate_bps = rtc::Optional<int>(1000);
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(0, 1000, -1));
  call->SetBitrateConfigMask(mask);

  Call::Config::BitrateConfig config;
  config.min_bitrate_bps = 0;
  config.start_bitrate_bps = -1;
  config.max_bitrate_bps = 5000;
  // The start value isn't changing, so SetBweBitrates should be called with
  // -1.
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(0, -1, 5000));
  call->SetBitrateConfig(config);
}

TEST(CallBitrateTest, SetBweBitratesNotCalledWhenClampedMinUnchanged) {
  Call::Config::BitrateConfig bitrate_config;
  bitrate_config.start_bitrate_bps = 500;
  bitrate_config.max_bitrate_bps = 1000;
  CallBitrateHelper call(bitrate_config);

  // Set min to 2000; it is clamped to the max (1000).
  Call::Config::BitrateConfigMask mask;
  mask.min_bitrate_bps = rtc::Optional<int>(2000);
  EXPECT_CALL(call.mock_cc(), SetBweBitrates(1000, -1, 1000));
  call->SetBitrateConfigMask(mask);

  // Set min to 3000; the clamped value stays the same so nothing happens.
  mask.min_bitrate_bps = rtc::Optional<int>(3000);
  call->SetBitrateConfigMask(mask);
}

}  // namespace webrtc
