/*
 *  Copyright (c) 2019 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 "modules/audio_processing/gain_control_config_proxy.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "rtc_base/critical_section.h"
#include "rtc_base/ref_counted_object.h"
#include "test/gtest.h"

namespace webrtc {
class GainControlConfigProxyTest : public ::testing::Test {
 protected:
  GainControlConfigProxyTest()
      : apm_(new rtc::RefCountedObject<
             ::testing::StrictMock<test::MockAudioProcessing>>()),
        agc_(),
        proxy_(&lock_, apm_, &agc_) {
    EXPECT_CALL(*apm_, GetConfig())
        .WillRepeatedly(::testing::ReturnPointee(&apm_config_));
    EXPECT_CALL(*apm_, ApplyConfig(::testing::_))
        .WillRepeatedly(::testing::SaveArg<0>(&apm_config_));
  }

  GainControl* proxy() { return &proxy_; }

  rtc::scoped_refptr<testing::StrictMock<test::MockAudioProcessing>> apm_;
  ::testing::StrictMock<test::MockGainControl> agc_;
  AudioProcessing::Config apm_config_;

 private:
  rtc::CriticalSection lock_;
  GainControlConfigProxy proxy_;
};

// GainControl API during processing.
TEST_F(GainControlConfigProxyTest, SetStreamAnalogLevel) {
  EXPECT_CALL(*apm_, set_stream_analog_level(100));
  proxy()->set_stream_analog_level(100);
}

TEST_F(GainControlConfigProxyTest, StreamAnalogLevel) {
  EXPECT_CALL(*apm_, recommended_stream_analog_level())
      .WillOnce(::testing::Return(100));
  EXPECT_EQ(100, proxy()->stream_analog_level());
}

// GainControl config setters.
TEST_F(GainControlConfigProxyTest, SetEnable) {
  proxy()->Enable(true);
  EXPECT_TRUE(apm_config_.gain_controller1.enabled);

  proxy()->Enable(false);
  EXPECT_FALSE(apm_config_.gain_controller1.enabled);
}

TEST_F(GainControlConfigProxyTest, SetMode) {
  proxy()->set_mode(GainControl::Mode::kAdaptiveAnalog);
  EXPECT_EQ(apm_config_.gain_controller1.kAdaptiveAnalog,
            apm_config_.gain_controller1.mode);

  proxy()->set_mode(GainControl::Mode::kAdaptiveDigital);
  EXPECT_EQ(apm_config_.gain_controller1.kAdaptiveDigital,
            apm_config_.gain_controller1.mode);

  proxy()->set_mode(GainControl::Mode::kFixedDigital);
  EXPECT_EQ(apm_config_.gain_controller1.kFixedDigital,
            apm_config_.gain_controller1.mode);
}

TEST_F(GainControlConfigProxyTest, SetTargetLevelDbfs) {
  proxy()->set_target_level_dbfs(17);
  EXPECT_EQ(17, apm_config_.gain_controller1.target_level_dbfs);
}

TEST_F(GainControlConfigProxyTest, SetCompressionGainDb) {
  AudioProcessing::RuntimeSetting setting;
  EXPECT_CALL(*apm_, SetRuntimeSetting(::testing::_))
      .WillOnce(::testing::SaveArg<0>(&setting));
  proxy()->set_compression_gain_db(17);
  EXPECT_EQ(AudioProcessing::RuntimeSetting::Type::kCaptureCompressionGain,
            setting.type());
  float value;
  setting.GetFloat(&value);
  EXPECT_EQ(17, static_cast<int>(value + .5f));
}

TEST_F(GainControlConfigProxyTest, SetEnableLimiter) {
  proxy()->enable_limiter(true);
  EXPECT_TRUE(apm_config_.gain_controller1.enable_limiter);
  proxy()->enable_limiter(false);
  EXPECT_FALSE(apm_config_.gain_controller1.enable_limiter);
}

TEST_F(GainControlConfigProxyTest, SetAnalogLevelLimits) {
  proxy()->set_analog_level_limits(100, 300);
  EXPECT_EQ(100, apm_config_.gain_controller1.analog_level_minimum);
  EXPECT_EQ(300, apm_config_.gain_controller1.analog_level_maximum);
}

TEST_F(GainControlConfigProxyTest, GetEnabled) {
  EXPECT_CALL(agc_, is_enabled())
      .WillOnce(::testing::Return(true))
      .WillOnce(::testing::Return(false));
  EXPECT_TRUE(proxy()->is_enabled());
  EXPECT_FALSE(proxy()->is_enabled());
}

TEST_F(GainControlConfigProxyTest, GetLimiterEnabled) {
  EXPECT_CALL(agc_, is_enabled())
      .WillOnce(::testing::Return(true))
      .WillOnce(::testing::Return(false));
  EXPECT_TRUE(proxy()->is_enabled());
  EXPECT_FALSE(proxy()->is_enabled());
}

TEST_F(GainControlConfigProxyTest, GetCompressionGainDb) {
  EXPECT_CALL(agc_, compression_gain_db()).WillOnce(::testing::Return(17));
  EXPECT_EQ(17, proxy()->compression_gain_db());
}

TEST_F(GainControlConfigProxyTest, GetTargetLevelDbfs) {
  EXPECT_CALL(agc_, target_level_dbfs()).WillOnce(::testing::Return(17));
  EXPECT_EQ(17, proxy()->target_level_dbfs());
}

TEST_F(GainControlConfigProxyTest, GetAnalogLevelMinimum) {
  EXPECT_CALL(agc_, analog_level_minimum()).WillOnce(::testing::Return(17));
  EXPECT_EQ(17, proxy()->analog_level_minimum());
}

TEST_F(GainControlConfigProxyTest, GetAnalogLevelMaximum) {
  EXPECT_CALL(agc_, analog_level_maximum()).WillOnce(::testing::Return(17));
  EXPECT_EQ(17, proxy()->analog_level_maximum());
}

TEST_F(GainControlConfigProxyTest, GetStreamIsSaturated) {
  EXPECT_CALL(agc_, stream_is_saturated())
      .WillOnce(::testing::Return(true))
      .WillOnce(::testing::Return(false));
  EXPECT_TRUE(proxy()->stream_is_saturated());
  EXPECT_FALSE(proxy()->stream_is_saturated());
}

TEST_F(GainControlConfigProxyTest, GetMode) {
  EXPECT_CALL(agc_, mode())
      .WillOnce(::testing::Return(GainControl::Mode::kAdaptiveAnalog))
      .WillOnce(::testing::Return(GainControl::Mode::kAdaptiveDigital))
      .WillOnce(::testing::Return(GainControl::Mode::kFixedDigital));
  EXPECT_EQ(GainControl::Mode::kAdaptiveAnalog, proxy()->mode());
  EXPECT_EQ(GainControl::Mode::kAdaptiveDigital, proxy()->mode());
  EXPECT_EQ(GainControl::Mode::kFixedDigital, proxy()->mode());
}

}  // namespace webrtc
