/*
 *  Copyright (c) 2012 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 "webrtc/test/testsupport/fileutils.h"
#include "webrtc/voice_engine/test/auto_test/fixtures/after_streaming_fixture.h"
#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"

class RxCallback : public webrtc::VoERxVadCallback {
 public:
  RxCallback() :
    vad_decision(-1) {
  }

  virtual void OnRxVad(int, int vadDecision) {
    char msg[128];
    sprintf(msg, "RX VAD detected decision %d \n", vadDecision);
    TEST_LOG("%s", msg);
    vad_decision = vadDecision;
  }

  int vad_decision;
};

class AudioProcessingTest : public AfterStreamingFixture {
 protected:
  // Note: Be careful with this one, it is used in the
  // Android / iPhone part too.
  void TryEnablingAgcWithMode(webrtc::AgcModes agc_mode_to_set) {
    EXPECT_EQ(0, voe_apm_->SetAgcStatus(true, agc_mode_to_set));

    bool agc_enabled = false;
    webrtc::AgcModes agc_mode = webrtc::kAgcDefault;

    EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
    EXPECT_TRUE(agc_enabled);
    EXPECT_EQ(agc_mode_to_set, agc_mode);
  }

  void TryEnablingRxAgcWithMode(webrtc::AgcModes agc_mode_to_set) {
    EXPECT_EQ(0, voe_apm_->SetRxAgcStatus(channel_, true, agc_mode_to_set));

    bool rx_agc_enabled = false;
    webrtc::AgcModes agc_mode = webrtc::kAgcDefault;

    EXPECT_EQ(0, voe_apm_->GetRxAgcStatus(channel_, rx_agc_enabled, agc_mode));
    EXPECT_TRUE(rx_agc_enabled);
    EXPECT_EQ(agc_mode_to_set, agc_mode);
  }

  // EC modes can map to other EC modes, so we have a separate parameter
  // for what we expect the EC mode to be set to.
  void TryEnablingEcWithMode(webrtc::EcModes ec_mode_to_set,
                             webrtc::EcModes expected_mode) {
    EXPECT_EQ(0, voe_apm_->SetEcStatus(true, ec_mode_to_set));

    bool ec_enabled = true;
    webrtc::EcModes ec_mode = webrtc::kEcDefault;

    EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));

    EXPECT_EQ(expected_mode, ec_mode);
  }

  // Here, the CNG mode will be expected to be on or off depending on the mode.
  void TryEnablingAecmWithMode(webrtc::AecmModes aecm_mode_to_set,
                               bool cng_enabled_to_set) {
    EXPECT_EQ(0, voe_apm_->SetAecmMode(aecm_mode_to_set, cng_enabled_to_set));

    bool cng_enabled = false;
    webrtc::AecmModes aecm_mode = webrtc::kAecmEarpiece;

    voe_apm_->GetAecmMode(aecm_mode, cng_enabled);

    EXPECT_EQ(cng_enabled_to_set, cng_enabled);
    EXPECT_EQ(aecm_mode_to_set, aecm_mode);
  }

  void TryEnablingNsWithMode(webrtc::NsModes ns_mode_to_set,
                             webrtc::NsModes expected_ns_mode) {
    EXPECT_EQ(0, voe_apm_->SetNsStatus(true, ns_mode_to_set));

    bool ns_status = true;
    webrtc::NsModes ns_mode = webrtc::kNsDefault;
    EXPECT_EQ(0, voe_apm_->GetNsStatus(ns_status, ns_mode));

    EXPECT_TRUE(ns_status);
    EXPECT_EQ(expected_ns_mode, ns_mode);
  }

  void TryEnablingRxNsWithMode(webrtc::NsModes ns_mode_to_set,
                               webrtc::NsModes expected_ns_mode) {
    EXPECT_EQ(0, voe_apm_->SetRxNsStatus(channel_, true, ns_mode_to_set));

    bool ns_status = true;
    webrtc::NsModes ns_mode = webrtc::kNsDefault;
    EXPECT_EQ(0, voe_apm_->GetRxNsStatus(channel_, ns_status, ns_mode));

    EXPECT_TRUE(ns_status);
    EXPECT_EQ(expected_ns_mode, ns_mode);
  }

  void TryDetectingSilence() {
    // Here, speech is running. Shut down speech.
    EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, true));
    EXPECT_EQ(0, voe_volume_control_->SetInputMute(channel_, true));
    EXPECT_EQ(0, voe_file_->StopPlayingFileAsMicrophone(channel_));

    // We should detect the silence after a short time.
    Sleep(50);
    for (int i = 0; i < 25; i++) {
      EXPECT_EQ(0, voe_apm_->VoiceActivityIndicator(channel_));
      Sleep(10);
    }
  }

  void TryDetectingSpeechAfterSilence() {
    // Re-enable speech.
    RestartFakeMicrophone();
    EXPECT_EQ(0, voe_codec_->SetVADStatus(channel_, false));
    EXPECT_EQ(0, voe_volume_control_->SetInputMute(channel_, false));

    // We should detect the speech after a short time.
    for (int i = 0; i < 50; i++) {
      if (voe_apm_->VoiceActivityIndicator(channel_) == 1) {
        return;
      }
      Sleep(10);
    }

    ADD_FAILURE() << "Failed to detect speech within 500 ms.";
  }
};

#if !defined(WEBRTC_IOS) && !defined(WEBRTC_ANDROID)

TEST_F(AudioProcessingTest, AgcIsOnByDefault) {
  bool agc_enabled = false;
  webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog;

  EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
  EXPECT_TRUE(agc_enabled);
  EXPECT_EQ(webrtc::kAgcAdaptiveAnalog, agc_mode);
}

TEST_F(AudioProcessingTest, CanEnableAgcWithAllModes) {
  TryEnablingAgcWithMode(webrtc::kAgcAdaptiveDigital);
  TryEnablingAgcWithMode(webrtc::kAgcAdaptiveAnalog);
  TryEnablingAgcWithMode(webrtc::kAgcFixedDigital);
}

TEST_F(AudioProcessingTest, EcIsDisabledAndAecIsDefaultEcMode) {
  bool ec_enabled = true;
  webrtc::EcModes ec_mode = webrtc::kEcDefault;

  EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
  EXPECT_FALSE(ec_enabled);
  EXPECT_EQ(webrtc::kEcAec, ec_mode);
}

TEST_F(AudioProcessingTest, EnablingEcAecShouldEnableEcAec) {
  TryEnablingEcWithMode(webrtc::kEcAec, webrtc::kEcAec);
}

TEST_F(AudioProcessingTest, EnablingEcConferenceShouldEnableEcAec) {
  TryEnablingEcWithMode(webrtc::kEcConference, webrtc::kEcAec);
}

TEST_F(AudioProcessingTest, EcModeIsPreservedWhenEcIsTurnedOff) {
  TryEnablingEcWithMode(webrtc::kEcConference, webrtc::kEcAec);

  EXPECT_EQ(0, voe_apm_->SetEcStatus(false));

  bool ec_enabled = true;
  webrtc::EcModes ec_mode = webrtc::kEcDefault;
  EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));

  EXPECT_FALSE(ec_enabled);
  EXPECT_EQ(webrtc::kEcAec, ec_mode);
}

TEST_F(AudioProcessingTest, CanEnableAndDisableEcModeSeveralTimesInARow) {
  for (int i = 0; i < 10; i++) {
    EXPECT_EQ(0, voe_apm_->SetEcStatus(true));
    EXPECT_EQ(0, voe_apm_->SetEcStatus(false));
  }

  bool ec_enabled = true;
  webrtc::EcModes ec_mode = webrtc::kEcDefault;
  EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));

  EXPECT_FALSE(ec_enabled);
  EXPECT_EQ(webrtc::kEcAec, ec_mode);
}

// TODO(phoglund): Reenable below test when it's no longer flaky.
TEST_F(AudioProcessingTest, DISABLED_TestVoiceActivityDetectionWithObserver) {
  RxCallback rx_callback;
  EXPECT_EQ(0, voe_apm_->RegisterRxVadObserver(channel_, rx_callback));

  // The extra sleeps are to allow decisions some time to propagate to the
  // observer.
  TryDetectingSilence();
  Sleep(100);

  EXPECT_EQ(0, rx_callback.vad_decision);

  TryDetectingSpeechAfterSilence();
  Sleep(100);

  EXPECT_EQ(1, rx_callback.vad_decision);

  EXPECT_EQ(0, voe_apm_->DeRegisterRxVadObserver(channel_));
}

#endif   // !WEBRTC_IOS && !WEBRTC_ANDROID

TEST_F(AudioProcessingTest, EnablingEcAecmShouldEnableEcAecm) {
  // This one apparently applies to Android and iPhone as well.
  TryEnablingEcWithMode(webrtc::kEcAecm, webrtc::kEcAecm);
}

TEST_F(AudioProcessingTest, EcAecmModeIsEnabledAndSpeakerphoneByDefault) {
  bool cng_enabled = false;
  webrtc::AecmModes aecm_mode = webrtc::kAecmEarpiece;

  voe_apm_->GetAecmMode(aecm_mode, cng_enabled);

  EXPECT_TRUE(cng_enabled);
  EXPECT_EQ(webrtc::kAecmSpeakerphone, aecm_mode);
}

TEST_F(AudioProcessingTest, CanSetAecmMode) {
  EXPECT_EQ(0, voe_apm_->SetEcStatus(true, webrtc::kEcAecm));

  // Try some AECM mode - CNG enabled combinations.
  TryEnablingAecmWithMode(webrtc::kAecmEarpiece, true);
  TryEnablingAecmWithMode(webrtc::kAecmEarpiece, false);
  TryEnablingAecmWithMode(webrtc::kAecmLoudEarpiece, true);
  TryEnablingAecmWithMode(webrtc::kAecmLoudSpeakerphone, false);
  TryEnablingAecmWithMode(webrtc::kAecmQuietEarpieceOrHeadset, true);
  TryEnablingAecmWithMode(webrtc::kAecmSpeakerphone, false);
}

TEST_F(AudioProcessingTest, RxAgcShouldBeOffByDefault) {
  bool rx_agc_enabled = true;
  webrtc::AgcModes agc_mode = webrtc::kAgcDefault;

  EXPECT_EQ(0, voe_apm_->GetRxAgcStatus(channel_, rx_agc_enabled, agc_mode));
  EXPECT_FALSE(rx_agc_enabled);
  EXPECT_EQ(webrtc::kAgcAdaptiveDigital, agc_mode);
}

TEST_F(AudioProcessingTest, CanTurnOnDigitalRxAcg) {
  TryEnablingRxAgcWithMode(webrtc::kAgcAdaptiveDigital);
  TryEnablingRxAgcWithMode(webrtc::kAgcFixedDigital);
}

TEST_F(AudioProcessingTest, CannotTurnOnAdaptiveAnalogRxAgc) {
  EXPECT_EQ(-1, voe_apm_->SetRxAgcStatus(
      channel_, true, webrtc::kAgcAdaptiveAnalog));
}

TEST_F(AudioProcessingTest, NsIsOffWithModerateSuppressionByDefault) {
  bool ns_status = true;
  webrtc::NsModes ns_mode = webrtc::kNsDefault;
  EXPECT_EQ(0, voe_apm_->GetNsStatus(ns_status, ns_mode));

  EXPECT_FALSE(ns_status);
  EXPECT_EQ(webrtc::kNsModerateSuppression, ns_mode);
}

TEST_F(AudioProcessingTest, CanSetNsMode) {
  // Concrete suppression values map to themselves.
  TryEnablingNsWithMode(webrtc::kNsHighSuppression,
                        webrtc::kNsHighSuppression);
  TryEnablingNsWithMode(webrtc::kNsLowSuppression,
                        webrtc::kNsLowSuppression);
  TryEnablingNsWithMode(webrtc::kNsModerateSuppression,
                        webrtc::kNsModerateSuppression);
  TryEnablingNsWithMode(webrtc::kNsVeryHighSuppression,
                        webrtc::kNsVeryHighSuppression);

  // Conference and Default map to concrete values.
  TryEnablingNsWithMode(webrtc::kNsConference,
                        webrtc::kNsHighSuppression);
  TryEnablingNsWithMode(webrtc::kNsDefault,
                        webrtc::kNsModerateSuppression);
}

TEST_F(AudioProcessingTest, RxNsIsOffWithModerateSuppressionByDefault) {
  bool ns_status = true;
  webrtc::NsModes ns_mode = webrtc::kNsDefault;
  EXPECT_EQ(0, voe_apm_->GetRxNsStatus(channel_, ns_status, ns_mode));

  EXPECT_FALSE(ns_status);
  EXPECT_EQ(webrtc::kNsModerateSuppression, ns_mode);
}

TEST_F(AudioProcessingTest, CanSetRxNsMode) {
  EXPECT_EQ(0, voe_apm_->SetRxNsStatus(channel_, true));

  // See comments on the regular NS test above.
  TryEnablingRxNsWithMode(webrtc::kNsHighSuppression,
                          webrtc::kNsHighSuppression);
  TryEnablingRxNsWithMode(webrtc::kNsLowSuppression,
                          webrtc::kNsLowSuppression);
  TryEnablingRxNsWithMode(webrtc::kNsModerateSuppression,
                          webrtc::kNsModerateSuppression);
  TryEnablingRxNsWithMode(webrtc::kNsVeryHighSuppression,
                          webrtc::kNsVeryHighSuppression);
  TryEnablingRxNsWithMode(webrtc::kNsConference,
                          webrtc::kNsHighSuppression);
  TryEnablingRxNsWithMode(webrtc::kNsDefault,
                          webrtc::kNsModerateSuppression);
}

TEST_F(AudioProcessingTest, VadIsDisabledByDefault) {
  bool vad_enabled;
  bool disabled_dtx;
  webrtc::VadModes vad_mode;

  EXPECT_EQ(0, voe_codec_->GetVADStatus(
      channel_, vad_enabled, vad_mode, disabled_dtx));

  EXPECT_FALSE(vad_enabled);
}

TEST_F(AudioProcessingTest, VoiceActivityIndicatorReturns1WithSpeechOn) {
  // This sleep is necessary since the voice detection algorithm needs some
  // time to detect the speech from the fake microphone.
  Sleep(500);
  EXPECT_EQ(1, voe_apm_->VoiceActivityIndicator(channel_));
}

TEST_F(AudioProcessingTest, CanSetDelayOffset) {
  voe_apm_->SetDelayOffsetMs(50);
  EXPECT_EQ(50, voe_apm_->DelayOffsetMs());
  voe_apm_->SetDelayOffsetMs(-50);
  EXPECT_EQ(-50, voe_apm_->DelayOffsetMs());
}

TEST_F(AudioProcessingTest, HighPassFilterIsOnByDefault) {
  EXPECT_TRUE(voe_apm_->IsHighPassFilterEnabled());
}

TEST_F(AudioProcessingTest, CanSetHighPassFilter) {
  EXPECT_EQ(0, voe_apm_->EnableHighPassFilter(true));
  EXPECT_TRUE(voe_apm_->IsHighPassFilterEnabled());
  EXPECT_EQ(0, voe_apm_->EnableHighPassFilter(false));
  EXPECT_FALSE(voe_apm_->IsHighPassFilterEnabled());
}

TEST_F(AudioProcessingTest, StereoChannelSwappingIsOffByDefault) {
  EXPECT_FALSE(voe_apm_->IsStereoChannelSwappingEnabled());
}

TEST_F(AudioProcessingTest, CanSetStereoChannelSwapping) {
  voe_apm_->EnableStereoChannelSwapping(true);
  EXPECT_TRUE(voe_apm_->IsStereoChannelSwappingEnabled());
  voe_apm_->EnableStereoChannelSwapping(false);
  EXPECT_FALSE(voe_apm_->IsStereoChannelSwappingEnabled());
}

TEST_F(AudioProcessingTest, CanStartAndStopDebugRecording) {
  std::string output_path = webrtc::test::OutputPath();
  std::string output_file = output_path + "apm_debug.txt";

  EXPECT_EQ(0, voe_apm_->StartDebugRecording(output_file.c_str()));
  Sleep(1000);
  EXPECT_EQ(0, voe_apm_->StopDebugRecording());
}

#if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID)

TEST_F(AudioProcessingTest, AgcIsOffByDefaultAndDigital) {
  bool agc_enabled = true;
  webrtc::AgcModes agc_mode = webrtc::kAgcAdaptiveAnalog;

  EXPECT_EQ(0, voe_apm_->GetAgcStatus(agc_enabled, agc_mode));
  EXPECT_FALSE(agc_enabled);
  EXPECT_EQ(webrtc::kAgcAdaptiveDigital, agc_mode);
}

TEST_F(AudioProcessingTest, CanEnableAgcInAdaptiveDigitalMode) {
  TryEnablingAgcWithMode(webrtc::kAgcAdaptiveDigital);
}

TEST_F(AudioProcessingTest, AgcIsPossibleExceptInAdaptiveAnalogMode) {
  EXPECT_EQ(-1, voe_apm_->SetAgcStatus(true, webrtc::kAgcAdaptiveAnalog));
  EXPECT_EQ(0, voe_apm_->SetAgcStatus(true, webrtc::kAgcFixedDigital));
  EXPECT_EQ(0, voe_apm_->SetAgcStatus(true, webrtc::kAgcAdaptiveDigital));
}

TEST_F(AudioProcessingTest, EcIsDisabledAndAecmIsDefaultEcMode) {
  bool ec_enabled = true;
  webrtc::EcModes ec_mode = webrtc::kEcDefault;

  EXPECT_EQ(0, voe_apm_->GetEcStatus(ec_enabled, ec_mode));
  EXPECT_FALSE(ec_enabled);
  EXPECT_EQ(webrtc::kEcAecm, ec_mode);
}

TEST_F(AudioProcessingTest, TestVoiceActivityDetection) {
  TryDetectingSilence();
  TryDetectingSpeechAfterSilence();
}

#endif  // WEBRTC_IOS || WEBRTC_ANDROID
