/*
 *  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 "media/engine/apm_helpers.h"

#include "media/engine/webrtcvoe.h"
#include "modules/audio_device/include/mock_audio_device.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/mock_audio_decoder_factory.h"
#include "voice_engine/transmit_mixer.h"

namespace webrtc {
namespace {

constexpr AgcConfig kDefaultAgcConfig = { 3, 9, true };

struct TestHelper {
  TestHelper() {
    // Reply with a 10ms timer every time TimeUntilNextProcess is called to
    // avoid entering a tight loop on the process thread.
    EXPECT_CALL(mock_audio_device_, TimeUntilNextProcess())
        .WillRepeatedly(testing::Return(10));

    // This replicates the conditions from voe_auto_test.
    Config config;
    config.Set<ExperimentalAgc>(new ExperimentalAgc(false));
    apm_ = rtc::scoped_refptr<AudioProcessing>(AudioProcessing::Create(config));
    EXPECT_EQ(0, voe_wrapper_.base()->Init(
                     &mock_audio_device_, apm_,
                     MockAudioDecoderFactory::CreateEmptyFactory()));
  }

  AudioProcessing* apm() { return apm_.get(); }

  const AudioProcessing* apm() const { return apm_.get(); }

  test::MockAudioDeviceModule* adm() {
    return &mock_audio_device_;
  }

  voe::TransmitMixer* transmit_mixer() {
    return voe_wrapper_.base()->transmit_mixer();
  }

  bool GetEcMetricsStatus() const {
    EchoCancellation* ec = apm()->echo_cancellation();
    bool metrics_enabled = ec->are_metrics_enabled();
    EXPECT_EQ(metrics_enabled, ec->is_delay_logging_enabled());
    return metrics_enabled;
  }

  bool CanGetEcMetrics() const {
    EchoCancellation* ec = apm()->echo_cancellation();
    EchoCancellation::Metrics metrics;
    int metrics_result = ec->GetMetrics(&metrics);
    int median = 0;
    int std = 0;
    float fraction = 0;
    int delay_metrics_result = ec->GetDelayMetrics(&median, &std, &fraction);
    return metrics_result == AudioProcessing::kNoError &&
           delay_metrics_result == AudioProcessing::kNoError;
  }

 private:
  testing::NiceMock<test::MockAudioDeviceModule> mock_audio_device_;
  cricket::VoEWrapper voe_wrapper_;
  rtc::scoped_refptr<AudioProcessing> apm_;
};
}  // namespace

TEST(ApmHelpersTest, AgcConfig_DefaultConfiguration) {
  TestHelper helper;
  AgcConfig agc_config =
      apm_helpers::GetAgcConfig(helper.apm());

  EXPECT_EQ(kDefaultAgcConfig.targetLeveldBOv, agc_config.targetLeveldBOv);
  EXPECT_EQ(kDefaultAgcConfig.digitalCompressionGaindB,
            agc_config.digitalCompressionGaindB);
  EXPECT_EQ(kDefaultAgcConfig.limiterEnable, agc_config.limiterEnable);
}

TEST(ApmHelpersTest, AgcConfig_GetAndSet) {
  const AgcConfig agc_config = { 11, 17, false };

  TestHelper helper;
  apm_helpers::SetAgcConfig(helper.apm(), agc_config);
  AgcConfig actual_config =
      apm_helpers::GetAgcConfig(helper.apm());

  EXPECT_EQ(agc_config.digitalCompressionGaindB,
            actual_config.digitalCompressionGaindB);
  EXPECT_EQ(agc_config.limiterEnable,
            actual_config.limiterEnable);
  EXPECT_EQ(agc_config.targetLeveldBOv,
            actual_config.targetLeveldBOv);
}

TEST(ApmHelpersTest, AgcStatus_DefaultMode) {
  TestHelper helper;
  GainControl* gc = helper.apm()->gain_control();
#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
  EXPECT_FALSE(gc->is_enabled());
  EXPECT_EQ(GainControl::kAdaptiveDigital, gc->mode());
#elif defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
  EXPECT_FALSE(gc->is_enabled());
  EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
#else
  EXPECT_TRUE(gc->is_enabled());
  EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
#endif
}

TEST(ApmHelpersTest, AgcStatus_EnableDisable) {
  TestHelper helper;
  GainControl* gc = helper.apm()->gain_control();
#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)
  apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
  EXPECT_FALSE(gc->is_enabled());
  EXPECT_EQ(GainControl::kFixedDigital, gc->mode());

  apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
  EXPECT_TRUE(gc->is_enabled());
  EXPECT_EQ(GainControl::kFixedDigital, gc->mode());
#else
  EXPECT_CALL(*helper.adm(), SetAGC(false)).WillOnce(testing::Return(0));
  apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), false);
  EXPECT_FALSE(gc->is_enabled());
  EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());

  EXPECT_CALL(*helper.adm(), SetAGC(true)).WillOnce(testing::Return(0));
  apm_helpers::SetAgcStatus(helper.apm(), helper.adm(), true);
  EXPECT_TRUE(gc->is_enabled());
  EXPECT_EQ(GainControl::kAdaptiveAnalog, gc->mode());
#endif
}

TEST(ApmHelpersTest, EcStatus_DefaultMode) {
  TestHelper helper;
  EchoCancellation* ec = helper.apm()->echo_cancellation();
  EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
  EXPECT_FALSE(ec->is_enabled());
  EXPECT_FALSE(ecm->is_enabled());
}

TEST(ApmHelpersTest, EcStatus_EnableDisable) {
  TestHelper helper;
  EchoCancellation* ec = helper.apm()->echo_cancellation();
  EchoControlMobile* ecm = helper.apm()->echo_control_mobile();

  apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
  EXPECT_FALSE(ec->is_enabled());
  EXPECT_TRUE(ecm->is_enabled());

  apm_helpers::SetEcStatus(helper.apm(), false, kEcAecm);
  EXPECT_FALSE(ec->is_enabled());
  EXPECT_FALSE(ecm->is_enabled());

  apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
  EXPECT_TRUE(ec->is_enabled());
  EXPECT_FALSE(ecm->is_enabled());
  EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());

  apm_helpers::SetEcStatus(helper.apm(), false, kEcConference);
  EXPECT_FALSE(ec->is_enabled());
  EXPECT_FALSE(ecm->is_enabled());
  EXPECT_EQ(EchoCancellation::kHighSuppression, ec->suppression_level());

  apm_helpers::SetEcStatus(helper.apm(), true, kEcAecm);
  EXPECT_FALSE(ec->is_enabled());
  EXPECT_TRUE(ecm->is_enabled());
}

TEST(ApmHelpersTest, EcMetrics_DefaultMode) {
  TestHelper helper;
  apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
  EXPECT_TRUE(helper.GetEcMetricsStatus());
}

TEST(ApmHelpersTest, EcMetrics_CanEnableDisable) {
  TestHelper helper;
  apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);

  apm_helpers::SetEcMetricsStatus(helper.apm(), true);
  EXPECT_TRUE(helper.GetEcMetricsStatus());
  apm_helpers::SetEcMetricsStatus(helper.apm(), false);
  EXPECT_FALSE(helper.GetEcMetricsStatus());
}

TEST(ApmHelpersTest, EcMetrics_NoStatsUnlessEcMetricsAndEcEnabled) {
  TestHelper helper;
  EXPECT_FALSE(helper.CanGetEcMetrics());

  apm_helpers::SetEcMetricsStatus(helper.apm(), true);
  EXPECT_FALSE(helper.CanGetEcMetrics());

  apm_helpers::SetEcStatus(helper.apm(), true, kEcConference);
  EXPECT_TRUE(helper.CanGetEcMetrics());

  apm_helpers::SetEcMetricsStatus(helper.apm(), false);
  EXPECT_FALSE(helper.CanGetEcMetrics());
}

TEST(ApmHelpersTest, AecmMode_DefaultMode) {
  TestHelper helper;
  EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
  EXPECT_EQ(EchoControlMobile::kSpeakerphone, ecm->routing_mode());
  EXPECT_TRUE(ecm->is_comfort_noise_enabled());
}

TEST(ApmHelpersTest, AecmMode_EnableDisableCng) {
  TestHelper helper;
  EchoControlMobile* ecm = helper.apm()->echo_control_mobile();
  apm_helpers::SetAecmMode(helper.apm(), false);
  EXPECT_FALSE(ecm->is_comfort_noise_enabled());
  apm_helpers::SetAecmMode(helper.apm(), true);
  EXPECT_TRUE(ecm->is_comfort_noise_enabled());
}

TEST(ApmHelpersTest, NsStatus_DefaultMode) {
  TestHelper helper;
  NoiseSuppression* ns = helper.apm()->noise_suppression();
  EXPECT_EQ(NoiseSuppression::kModerate, ns->level());
  EXPECT_FALSE(ns->is_enabled());
}

TEST(ApmHelpersTest, NsStatus_EnableDisable) {
  TestHelper helper;
  NoiseSuppression* ns = helper.apm()->noise_suppression();
  apm_helpers::SetNsStatus(helper.apm(), true);
  EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
  EXPECT_TRUE(ns->is_enabled());
  apm_helpers::SetNsStatus(helper.apm(), false);
  EXPECT_EQ(NoiseSuppression::kHigh, ns->level());
  EXPECT_FALSE(ns->is_enabled());
}

TEST(ApmHelpersTest, TypingDetectionStatus_DefaultMode) {
  TestHelper helper;
  VoiceDetection* vd = helper.apm()->voice_detection();
  EXPECT_FALSE(vd->is_enabled());
}

// TODO(kthelgason): Reenable this test on simulator.
// See bugs.webrtc.org/5569
#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR
#define MAYBE_TypingDetectionStatus_EnableDisable DISABLED_TypingDetectionStatus_EnableDisable
#else
#define MAYBE_TypingDetectionStatus_EnableDisable TypingDetectionStatus_EnableDisable
#endif
TEST(ApmHelpersTest, MAYBE_TypingDetectionStatus_EnableDisable) {
  TestHelper helper;
  VoiceDetection* vd = helper.apm()->voice_detection();
  apm_helpers::SetTypingDetectionStatus(helper.apm(), true);
  EXPECT_TRUE(vd->is_enabled());
  apm_helpers::SetTypingDetectionStatus(helper.apm(), false);
  EXPECT_FALSE(vd->is_enabled());
}

// TODO(solenberg): Move this test to a better place - added here for the sake
// of duplicating all relevant tests from audio_processing_test.cc.
TEST(ApmHelpersTest, HighPassFilter_DefaultMode) {
  TestHelper helper;
  EXPECT_TRUE(helper.apm()->high_pass_filter()->is_enabled());
}

// TODO(solenberg): Move this test to a better place - added here for the sake
// of duplicating all relevant tests from audio_processing_test.cc.
TEST(ApmHelpersTest, StereoSwapping_DefaultMode) {
  TestHelper helper;
  EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
}

// TODO(solenberg): Move this test to a better place - added here for the sake
// of duplicating all relevant tests from audio_processing_test.cc.
TEST(ApmHelpersTest, StereoSwapping_EnableDisable) {
  TestHelper helper;
  helper.transmit_mixer()->EnableStereoChannelSwapping(true);
  EXPECT_TRUE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
  helper.transmit_mixer()->EnableStereoChannelSwapping(false);
  EXPECT_FALSE(helper.transmit_mixer()->IsStereoChannelSwappingEnabled());
}
}  // namespace webrtc
