/*
 *  Copyright (c) 2016 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/aec3/echo_canceller3.h"

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

#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/block_processor.h"
#include "modules/audio_processing/aec3/frame_blocker.h"
#include "modules/audio_processing/aec3/mock/mock_block_processor.h"
#include "modules/audio_processing/audio_buffer.h"
#include "modules/audio_processing/high_pass_filter.h"
#include "modules/audio_processing/utility/cascaded_biquad_filter.h"
#include "rtc_base/strings/string_builder.h"
#include "test/field_trial.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::_;
using ::testing::StrictMock;

// Populates the frame with linearly increasing sample values for each band,
// with a band-specific offset, in order to allow simple bitexactness
// verification for each band.
void PopulateInputFrame(size_t frame_length,
                        size_t num_bands,
                        size_t frame_index,
                        float* const* frame,
                        int offset) {
  for (size_t k = 0; k < num_bands; ++k) {
    for (size_t i = 0; i < frame_length; ++i) {
      float value = static_cast<int>(frame_index * frame_length + i) + offset;
      frame[k][i] = (value > 0 ? 5000 * k + value : 0);
    }
  }
}

// Populates the frame with linearly increasing sample values.
void PopulateInputFrame(size_t frame_length,
                        size_t frame_index,
                        float* frame,
                        int offset) {
  for (size_t i = 0; i < frame_length; ++i) {
    float value = static_cast<int>(frame_index * frame_length + i) + offset;
    frame[i] = std::max(value, 0.f);
  }
}

// Verifies the that samples in the output frame are identical to the samples
// that were produced for the input frame, with an offset in order to compensate
// for buffering delays.
bool VerifyOutputFrameBitexactness(size_t frame_length,
                                   size_t num_bands,
                                   size_t frame_index,
                                   const float* const* frame,
                                   int offset) {
  float reference_frame_data[kMaxNumBands][2 * kSubFrameLength];
  float* reference_frame[kMaxNumBands];
  for (size_t k = 0; k < num_bands; ++k) {
    reference_frame[k] = &reference_frame_data[k][0];
  }

  PopulateInputFrame(frame_length, num_bands, frame_index, reference_frame,
                     offset);
  for (size_t k = 0; k < num_bands; ++k) {
    for (size_t i = 0; i < frame_length; ++i) {
      if (reference_frame[k][i] != frame[k][i]) {
        return false;
      }
    }
  }

  return true;
}

bool VerifyOutputFrameBitexactness(rtc::ArrayView<const float> reference,
                                   rtc::ArrayView<const float> frame,
                                   int offset) {
  for (size_t k = 0; k < frame.size(); ++k) {
    int reference_index = static_cast<int>(k) + offset;
    if (reference_index >= 0) {
      if (reference[reference_index] != frame[k]) {
        return false;
      }
    }
  }
  return true;
}

// Class for testing that the capture data is properly received by the block
// processor and that the processor data is properly passed to the
// EchoCanceller3 output.
class CaptureTransportVerificationProcessor : public BlockProcessor {
 public:
  explicit CaptureTransportVerificationProcessor(size_t num_bands) {}

  CaptureTransportVerificationProcessor() = delete;
  CaptureTransportVerificationProcessor(
      const CaptureTransportVerificationProcessor&) = delete;
  CaptureTransportVerificationProcessor& operator=(
      const CaptureTransportVerificationProcessor&) = delete;

  ~CaptureTransportVerificationProcessor() override = default;

  void ProcessCapture(
      bool level_change,
      bool saturated_microphone_signal,
      std::vector<std::vector<std::vector<float>>>* linear_output,
      std::vector<std::vector<std::vector<float>>>* capture_block) override {}

  void BufferRender(
      const std::vector<std::vector<std::vector<float>>>& block) override {}

  void UpdateEchoLeakageStatus(bool leakage_detected) override {}

  void GetMetrics(EchoControl::Metrics* metrics) const override {}

  void SetAudioBufferDelay(int delay_ms) override {}
};

// Class for testing that the render data is properly received by the block
// processor.
class RenderTransportVerificationProcessor : public BlockProcessor {
 public:
  explicit RenderTransportVerificationProcessor(size_t num_bands) {}

  RenderTransportVerificationProcessor() = delete;
  RenderTransportVerificationProcessor(
      const RenderTransportVerificationProcessor&) = delete;
  RenderTransportVerificationProcessor& operator=(
      const RenderTransportVerificationProcessor&) = delete;

  ~RenderTransportVerificationProcessor() override = default;

  void ProcessCapture(
      bool level_change,
      bool saturated_microphone_signal,
      std::vector<std::vector<std::vector<float>>>* linear_output,
      std::vector<std::vector<std::vector<float>>>* capture_block) override {
    std::vector<std::vector<std::vector<float>>> render_block =
        received_render_blocks_.front();
    received_render_blocks_.pop_front();
    capture_block->swap(render_block);
  }

  void BufferRender(
      const std::vector<std::vector<std::vector<float>>>& block) override {
    received_render_blocks_.push_back(block);
  }

  void UpdateEchoLeakageStatus(bool leakage_detected) override {}

  void GetMetrics(EchoControl::Metrics* metrics) const override {}

  void SetAudioBufferDelay(int delay_ms) override {}

 private:
  std::deque<std::vector<std::vector<std::vector<float>>>>
      received_render_blocks_;
};

class EchoCanceller3Tester {
 public:
  explicit EchoCanceller3Tester(int sample_rate_hz)
      : sample_rate_hz_(sample_rate_hz),
        num_bands_(NumBandsForRate(sample_rate_hz_)),
        frame_length_(160),
        fullband_frame_length_(rtc::CheckedDivExact(sample_rate_hz_, 100)),
        capture_buffer_(fullband_frame_length_ * 100,
                        1,
                        fullband_frame_length_ * 100,
                        1,
                        fullband_frame_length_ * 100,
                        1),
        render_buffer_(fullband_frame_length_ * 100,
                       1,
                       fullband_frame_length_ * 100,
                       1,
                       fullband_frame_length_ * 100,
                       1) {}

  EchoCanceller3Tester() = delete;
  EchoCanceller3Tester(const EchoCanceller3Tester&) = delete;
  EchoCanceller3Tester& operator=(const EchoCanceller3Tester&) = delete;

  // Verifies that the capture data is properly received by the block processor
  // and that the processor data is properly passed to the EchoCanceller3
  // output.
  void RunCaptureTransportVerificationTest() {
    EchoCanceller3 aec3(
        EchoCanceller3Config(), sample_rate_hz_, 1, 1,
        std::unique_ptr<BlockProcessor>(
            new CaptureTransportVerificationProcessor(num_bands_)));

    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, frame_index,
                         &render_buffer_.channels()[0][0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
      EXPECT_TRUE(VerifyOutputFrameBitexactness(
          frame_length_, num_bands_, frame_index,
          &capture_buffer_.split_bands(0)[0], -64));
    }
  }

  // Test method for testing that the render data is properly received by the
  // block processor.
  void RunRenderTransportVerificationTest() {
    EchoCanceller3 aec3(
        EchoCanceller3Config(), sample_rate_hz_, 1, 1,
        std::unique_ptr<BlockProcessor>(
            new RenderTransportVerificationProcessor(num_bands_)));

    std::vector<std::vector<float>> render_input(1);
    std::vector<float> capture_output;
    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 100);
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &render_buffer_.split_bands(0)[0], 0);

      for (size_t k = 0; k < frame_length_; ++k) {
        render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
      }
      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
      for (size_t k = 0; k < frame_length_; ++k) {
        capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
      }
    }
    HighPassFilter hp_filter(16000, 1);
    hp_filter.Process(&render_input);

    EXPECT_TRUE(
        VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
  }

  // Verifies that information about echo path changes are properly propagated
  // to the block processor.
  // The cases tested are:
  // -That no set echo path change flags are received when there is no echo path
  // change.
  // -That set echo path change flags are received and continues to be received
  // as long as echo path changes are flagged.
  // -That set echo path change flags are no longer received when echo path
  // change events stop being flagged.
  enum class EchoPathChangeTestVariant { kNone, kOneSticky, kOneNonSticky };

  void RunEchoPathChangeVerificationTest(
      EchoPathChangeTestVariant echo_path_change_test_variant) {
    constexpr size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
    constexpr size_t kExpectedNumBlocksToProcess =
        (kNumFramesToProcess * 160) / kBlockSize;
    std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
        block_processor_mock(
            new StrictMock<webrtc::test::MockBlockProcessor>());
    EXPECT_CALL(*block_processor_mock, BufferRender(_))
        .Times(kExpectedNumBlocksToProcess);
    EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);

    switch (echo_path_change_test_variant) {
      case EchoPathChangeTestVariant::kNone:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
            .Times(kExpectedNumBlocksToProcess);
        break;
      case EchoPathChangeTestVariant::kOneSticky:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
            .Times(kExpectedNumBlocksToProcess);
        break;
      case EchoPathChangeTestVariant::kOneNonSticky:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(true, _, _, _))
            .Times(kNumFullBlocksPerFrame);
        EXPECT_CALL(*block_processor_mock, ProcessCapture(false, _, _, _))
            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
        break;
    }

    EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
                        std::move(block_processor_mock));

    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      bool echo_path_change = false;
      switch (echo_path_change_test_variant) {
        case EchoPathChangeTestVariant::kNone:
          break;
        case EchoPathChangeTestVariant::kOneSticky:
          echo_path_change = true;
          break;
        case EchoPathChangeTestVariant::kOneNonSticky:
          if (frame_index == 0) {
            echo_path_change = true;
          }
          break;
      }

      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, frame_index,
                         &render_buffer_.channels()[0][0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, echo_path_change);
    }
  }

  // Test for verifying that echo leakage information is being properly passed
  // to the processor.
  // The cases tested are:
  // -That no method calls are received when they should not.
  // -That false values are received each time they are flagged.
  // -That true values are received each time they are flagged.
  // -That a false value is received when flagged after a true value has been
  // flagged.
  enum class EchoLeakageTestVariant {
    kNone,
    kFalseSticky,
    kTrueSticky,
    kTrueNonSticky
  };

  void RunEchoLeakageVerificationTest(
      EchoLeakageTestVariant leakage_report_variant) {
    constexpr size_t kExpectedNumBlocksToProcess =
        (kNumFramesToProcess * 160) / kBlockSize;
    std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
        block_processor_mock(
            new StrictMock<webrtc::test::MockBlockProcessor>());
    EXPECT_CALL(*block_processor_mock, BufferRender(_))
        .Times(kExpectedNumBlocksToProcess);
    EXPECT_CALL(*block_processor_mock, ProcessCapture(_, _, _, _))
        .Times(kExpectedNumBlocksToProcess);

    switch (leakage_report_variant) {
      case EchoLeakageTestVariant::kNone:
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);
        break;
      case EchoLeakageTestVariant::kFalseSticky:
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
            .Times(1);
        break;
      case EchoLeakageTestVariant::kTrueSticky:
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
            .Times(1);
        break;
      case EchoLeakageTestVariant::kTrueNonSticky: {
        ::testing::InSequence s;
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(true))
            .Times(1);
        EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(false))
            .Times(kNumFramesToProcess - 1);
      } break;
    }

    EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
                        std::move(block_processor_mock));

    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      switch (leakage_report_variant) {
        case EchoLeakageTestVariant::kNone:
          break;
        case EchoLeakageTestVariant::kFalseSticky:
          if (frame_index == 0) {
            aec3.UpdateEchoLeakageStatus(false);
          }
          break;
        case EchoLeakageTestVariant::kTrueSticky:
          if (frame_index == 0) {
            aec3.UpdateEchoLeakageStatus(true);
          }
          break;
        case EchoLeakageTestVariant::kTrueNonSticky:
          if (frame_index == 0) {
            aec3.UpdateEchoLeakageStatus(true);
          } else {
            aec3.UpdateEchoLeakageStatus(false);
          }
          break;
      }

      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, frame_index,
                         &render_buffer_.channels()[0][0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
    }
  }

  // This verifies that saturation information is properly passed to the
  // BlockProcessor.
  // The cases tested are:
  // -That no saturation event is passed to the processor if there is no
  // saturation.
  // -That one frame with one negative saturated sample value is reported to be
  // saturated and that following non-saturated frames are properly reported as
  // not being saturated.
  // -That one frame with one positive saturated sample value is reported to be
  // saturated and that following non-saturated frames are properly reported as
  // not being saturated.
  enum class SaturationTestVariant { kNone, kOneNegative, kOnePositive };

  void RunCaptureSaturationVerificationTest(
      SaturationTestVariant saturation_variant) {
    const size_t kNumFullBlocksPerFrame = 160 / kBlockSize;
    const size_t kExpectedNumBlocksToProcess =
        (kNumFramesToProcess * 160) / kBlockSize;
    std::unique_ptr<testing::StrictMock<webrtc::test::MockBlockProcessor>>
        block_processor_mock(
            new StrictMock<webrtc::test::MockBlockProcessor>());
    EXPECT_CALL(*block_processor_mock, BufferRender(_))
        .Times(kExpectedNumBlocksToProcess);
    EXPECT_CALL(*block_processor_mock, UpdateEchoLeakageStatus(_)).Times(0);

    switch (saturation_variant) {
      case SaturationTestVariant::kNone:
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
            .Times(kExpectedNumBlocksToProcess);
        break;
      case SaturationTestVariant::kOneNegative: {
        ::testing::InSequence s;
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
            .Times(kNumFullBlocksPerFrame);
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
      } break;
      case SaturationTestVariant::kOnePositive: {
        ::testing::InSequence s;
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, true, _, _))
            .Times(kNumFullBlocksPerFrame);
        EXPECT_CALL(*block_processor_mock, ProcessCapture(_, false, _, _))
            .Times(kExpectedNumBlocksToProcess - kNumFullBlocksPerFrame);
      } break;
    }

    EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1,
                        std::move(block_processor_mock));
    for (size_t frame_index = 0; frame_index < kNumFramesToProcess;
         ++frame_index) {
      for (int k = 0; k < fullband_frame_length_; ++k) {
        capture_buffer_.channels()[0][k] = 0.f;
      }
      switch (saturation_variant) {
        case SaturationTestVariant::kNone:
          break;
        case SaturationTestVariant::kOneNegative:
          if (frame_index == 0) {
            capture_buffer_.channels()[0][10] = -32768.f;
          }
          break;
        case SaturationTestVariant::kOnePositive:
          if (frame_index == 0) {
            capture_buffer_.channels()[0][10] = 32767.f;
          }
          break;
      }

      aec3.AnalyzeCapture(&capture_buffer_);
      OptionalBandSplit();

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &render_buffer_.split_bands(0)[0], 0);

      aec3.AnalyzeRender(&render_buffer_);
      aec3.ProcessCapture(&capture_buffer_, false);
    }
  }

  // This test verifies that the swapqueue is able to handle jitter in the
  // capture and render API calls.
  void RunRenderSwapQueueVerificationTest() {
    const EchoCanceller3Config config;
    EchoCanceller3 aec3(
        config, sample_rate_hz_, 1, 1,
        std::unique_ptr<BlockProcessor>(
            new RenderTransportVerificationProcessor(num_bands_)));

    std::vector<std::vector<float>> render_input(1);
    std::vector<float> capture_output;

    for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
         ++frame_index) {
      if (sample_rate_hz_ > 16000) {
        render_buffer_.SplitIntoFrequencyBands();
      }
      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &render_buffer_.split_bands(0)[0], 0);

      if (sample_rate_hz_ > 16000) {
        render_buffer_.SplitIntoFrequencyBands();
      }

      for (size_t k = 0; k < frame_length_; ++k) {
        render_input[0].push_back(render_buffer_.split_bands(0)[0][k]);
      }
      aec3.AnalyzeRender(&render_buffer_);
    }

    for (size_t frame_index = 0; frame_index < kRenderTransferQueueSizeFrames;
         ++frame_index) {
      aec3.AnalyzeCapture(&capture_buffer_);
      if (sample_rate_hz_ > 16000) {
        capture_buffer_.SplitIntoFrequencyBands();
      }

      PopulateInputFrame(frame_length_, num_bands_, frame_index,
                         &capture_buffer_.split_bands(0)[0], 0);

      aec3.ProcessCapture(&capture_buffer_, false);
      for (size_t k = 0; k < frame_length_; ++k) {
        capture_output.push_back(capture_buffer_.split_bands(0)[0][k]);
      }
    }
    HighPassFilter hp_filter(16000, 1);
    hp_filter.Process(&render_input);

    EXPECT_TRUE(
        VerifyOutputFrameBitexactness(render_input[0], capture_output, -64));
  }

  // This test verifies that a buffer overrun in the render swapqueue is
  // properly reported.
  void RunRenderPipelineSwapQueueOverrunReturnValueTest() {
    EchoCanceller3 aec3(EchoCanceller3Config(), sample_rate_hz_, 1, 1);

    constexpr size_t kRenderTransferQueueSize = 30;
    for (size_t k = 0; k < 2; ++k) {
      for (size_t frame_index = 0; frame_index < kRenderTransferQueueSize;
           ++frame_index) {
        if (sample_rate_hz_ > 16000) {
          render_buffer_.SplitIntoFrequencyBands();
        }
        PopulateInputFrame(frame_length_, frame_index,
                           &render_buffer_.channels()[0][0], 0);

        aec3.AnalyzeRender(&render_buffer_);
      }
    }
  }

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
  // Verifies the that the check for the number of bands in the AnalyzeRender
  // input is correct by adjusting the sample rates of EchoCanceller3 and the
  // input AudioBuffer to have a different number of bands.
  void RunAnalyzeRenderNumBandsCheckVerification() {
    // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
    // way that the number of bands for the rates are different.
    const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
    EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
    PopulateInputFrame(frame_length_, 0, &render_buffer_.channels_f()[0][0], 0);

    EXPECT_DEATH(aec3.AnalyzeRender(&render_buffer_), "");
  }

  // Verifies the that the check for the number of bands in the ProcessCapture
  // input is correct by adjusting the sample rates of EchoCanceller3 and the
  // input AudioBuffer to have a different number of bands.
  void RunProcessCaptureNumBandsCheckVerification() {
    // Set aec3_sample_rate_hz to be different from sample_rate_hz_ in such a
    // way that the number of bands for the rates are different.
    const int aec3_sample_rate_hz = sample_rate_hz_ == 48000 ? 32000 : 48000;
    EchoCanceller3 aec3(EchoCanceller3Config(), aec3_sample_rate_hz, 1, 1);
    PopulateInputFrame(frame_length_, num_bands_, 0,
                       &capture_buffer_.split_bands_f(0)[0], 100);
    EXPECT_DEATH(aec3.ProcessCapture(&capture_buffer_, false), "");
  }

#endif

 private:
  void OptionalBandSplit() {
    if (sample_rate_hz_ > 16000) {
      capture_buffer_.SplitIntoFrequencyBands();
      render_buffer_.SplitIntoFrequencyBands();
    }
  }

  static constexpr size_t kNumFramesToProcess = 20;
  const int sample_rate_hz_;
  const size_t num_bands_;
  const size_t frame_length_;
  const int fullband_frame_length_;
  AudioBuffer capture_buffer_;
  AudioBuffer render_buffer_;
};

std::string ProduceDebugText(int sample_rate_hz) {
  rtc::StringBuilder ss;
  ss << "Sample rate: " << sample_rate_hz;
  return ss.Release();
}

std::string ProduceDebugText(int sample_rate_hz, int variant) {
  rtc::StringBuilder ss;
  ss << "Sample rate: " << sample_rate_hz << ", variant: " << variant;
  return ss.Release();
}

}  // namespace

TEST(EchoCanceller3Buffering, CaptureBitexactness) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate).RunCaptureTransportVerificationTest();
  }
}

TEST(EchoCanceller3Buffering, RenderBitexactness) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate).RunRenderTransportVerificationTest();
  }
}

TEST(EchoCanceller3Buffering, RenderSwapQueue) {
  EchoCanceller3Tester(16000).RunRenderSwapQueueVerificationTest();
}

TEST(EchoCanceller3Buffering, RenderSwapQueueOverrunReturnValue) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate)
        .RunRenderPipelineSwapQueueOverrunReturnValueTest();
  }
}

TEST(EchoCanceller3Messaging, CaptureSaturation) {
  auto variants = {EchoCanceller3Tester::SaturationTestVariant::kNone,
                   EchoCanceller3Tester::SaturationTestVariant::kOneNegative,
                   EchoCanceller3Tester::SaturationTestVariant::kOnePositive};
  for (auto rate : {16000, 32000, 48000}) {
    for (auto variant : variants) {
      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
      EchoCanceller3Tester(rate).RunCaptureSaturationVerificationTest(variant);
    }
  }
}

TEST(EchoCanceller3Messaging, EchoPathChange) {
  auto variants = {
      EchoCanceller3Tester::EchoPathChangeTestVariant::kNone,
      EchoCanceller3Tester::EchoPathChangeTestVariant::kOneSticky,
      EchoCanceller3Tester::EchoPathChangeTestVariant::kOneNonSticky};
  for (auto rate : {16000, 32000, 48000}) {
    for (auto variant : variants) {
      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
      EchoCanceller3Tester(rate).RunEchoPathChangeVerificationTest(variant);
    }
  }
}

TEST(EchoCanceller3Messaging, EchoLeakage) {
  auto variants = {
      EchoCanceller3Tester::EchoLeakageTestVariant::kNone,
      EchoCanceller3Tester::EchoLeakageTestVariant::kFalseSticky,
      EchoCanceller3Tester::EchoLeakageTestVariant::kTrueSticky,
      EchoCanceller3Tester::EchoLeakageTestVariant::kTrueNonSticky};
  for (auto rate : {16000, 32000, 48000}) {
    for (auto variant : variants) {
      SCOPED_TRACE(ProduceDebugText(rate, static_cast<int>(variant)));
      EchoCanceller3Tester(rate).RunEchoLeakageVerificationTest(variant);
    }
  }
}

// Tests the parameter functionality for the field trial override for the
// default_len parameter.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorEpStrengthDefaultLenOverride) {
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
  ASSERT_EQ(default_config.ep_strength.default_len,
            adjusted_config.ep_strength.default_len);

  webrtc::test::ScopedFieldTrials field_trials(
      "WebRTC-Aec3SuppressorEpStrengthDefaultLenOverride/-0.02/");
  adjusted_config = AdjustConfig(default_config);

  ASSERT_NE(default_config.ep_strength.default_len,
            adjusted_config.ep_strength.default_len);
  EXPECT_FLOAT_EQ(-0.02f, adjusted_config.ep_strength.default_len);
}

// Tests the parameter functionality for the field trial override for the
// anti-howling gain.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorAntiHowlingGainOverride) {
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
  ASSERT_EQ(
      default_config.suppressor.high_bands_suppression.anti_howling_gain,
      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);

  webrtc::test::ScopedFieldTrials field_trials(
      "WebRTC-Aec3SuppressorAntiHowlingGainOverride/0.02/");
  adjusted_config = AdjustConfig(default_config);

  ASSERT_NE(
      default_config.suppressor.high_bands_suppression.anti_howling_gain,
      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
  EXPECT_FLOAT_EQ(
      0.02f,
      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);
}

// Tests the field trial override for the enforcement of a low active render
// limit.
TEST(EchoCanceller3FieldTrials, Aec3EnforceLowActiveRenderLimit) {
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config = AdjustConfig(default_config);
  ASSERT_EQ(default_config.render_levels.active_render_limit,
            adjusted_config.render_levels.active_render_limit);

  webrtc::test::ScopedFieldTrials field_trials(
      "WebRTC-Aec3EnforceLowActiveRenderLimit/Enabled/");
  adjusted_config = AdjustConfig(default_config);

  ASSERT_NE(default_config.render_levels.active_render_limit,
            adjusted_config.render_levels.active_render_limit);
  EXPECT_FLOAT_EQ(50.f, adjusted_config.render_levels.active_render_limit);
}

// Testing the field trial-based override of the suppressor parameters for a
// joint passing of all parameters.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideAllParams) {
  webrtc::test::ScopedFieldTrials field_trials(
      "WebRTC-Aec3SuppressorTuningOverride/"
      "nearend_tuning_mask_lf_enr_transparent:0.1,nearend_tuning_mask_lf_enr_"
      "suppress:0.2,nearend_tuning_mask_hf_enr_transparent:0.3,nearend_tuning_"
      "mask_hf_enr_suppress:0.4,nearend_tuning_max_inc_factor:0.5,nearend_"
      "tuning_max_dec_factor_lf:0.6,normal_tuning_mask_lf_enr_transparent:0.7,"
      "normal_tuning_mask_lf_enr_suppress:0.8,normal_tuning_mask_hf_enr_"
      "transparent:0.9,normal_tuning_mask_hf_enr_suppress:1.0,normal_tuning_"
      "max_inc_factor:1.1,normal_tuning_max_dec_factor_lf:1.2,dominant_nearend_"
      "detection_enr_threshold:1.3,dominant_nearend_detection_enr_exit_"
      "threshold:1.4,dominant_nearend_detection_snr_threshold:1.5,dominant_"
      "nearend_detection_hold_duration:10,dominant_nearend_detection_trigger_"
      "threshold:11,ep_strength_default_len:1.6/");

  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config = AdjustConfig(default_config);

  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
            default_config.suppressor.nearend_tuning.max_inc_factor);
  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
            default_config.suppressor.nearend_tuning.max_dec_factor_lf);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_inc_factor,
            default_config.suppressor.normal_tuning.max_inc_factor);
  ASSERT_NE(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
            default_config.suppressor.normal_tuning.max_dec_factor_lf);
  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
            default_config.suppressor.dominant_nearend_detection.enr_threshold);
  ASSERT_NE(
      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
      default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
            default_config.suppressor.dominant_nearend_detection.snr_threshold);
  ASSERT_NE(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
            default_config.suppressor.dominant_nearend_detection.hold_duration);
  ASSERT_NE(
      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
      default_config.suppressor.dominant_nearend_detection.trigger_threshold);
  ASSERT_NE(adjusted_config.ep_strength.default_len,
            default_config.ep_strength.default_len);

  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent, 0.1);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress, 0.2);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent, 0.3);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress, 0.4);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
                  0.5);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
                  0.6);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent, 0.7);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
                  0.8);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent, 0.9);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
                  1.0);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor, 1.1);
  EXPECT_FLOAT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
                  1.2);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.enr_threshold, 1.3);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
      1.4);
  EXPECT_FLOAT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.snr_threshold, 1.5);
  EXPECT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
            10);
  EXPECT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
      11);
  EXPECT_FLOAT_EQ(adjusted_config.ep_strength.default_len, 1.6);
}

// Testing the field trial-based override of the suppressor parameters for
// passing one parameter.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorTuningOverrideOneParam) {
  webrtc::test::ScopedFieldTrials field_trials(
      "WebRTC-Aec3SuppressorTuningOverride/nearend_tuning_max_inc_factor:0.5/");

  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config = AdjustConfig(default_config);

  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_lf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_lf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_lf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_transparent,
            default_config.suppressor.nearend_tuning.mask_hf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.mask_hf.enr_suppress,
            default_config.suppressor.nearend_tuning.mask_hf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.nearend_tuning.max_dec_factor_lf,
            default_config.suppressor.nearend_tuning.max_dec_factor_lf);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_lf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_lf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_lf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_transparent,
            default_config.suppressor.normal_tuning.mask_hf.enr_transparent);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.mask_hf.enr_suppress,
            default_config.suppressor.normal_tuning.mask_hf.enr_suppress);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_inc_factor,
            default_config.suppressor.normal_tuning.max_inc_factor);
  ASSERT_EQ(adjusted_config.suppressor.normal_tuning.max_dec_factor_lf,
            default_config.suppressor.normal_tuning.max_dec_factor_lf);
  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.enr_threshold,
            default_config.suppressor.dominant_nearend_detection.enr_threshold);
  ASSERT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.enr_exit_threshold,
      default_config.suppressor.dominant_nearend_detection.enr_exit_threshold);
  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.snr_threshold,
            default_config.suppressor.dominant_nearend_detection.snr_threshold);
  ASSERT_EQ(adjusted_config.suppressor.dominant_nearend_detection.hold_duration,
            default_config.suppressor.dominant_nearend_detection.hold_duration);
  ASSERT_EQ(
      adjusted_config.suppressor.dominant_nearend_detection.trigger_threshold,
      default_config.suppressor.dominant_nearend_detection.trigger_threshold);

  ASSERT_NE(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
            default_config.suppressor.nearend_tuning.max_inc_factor);

  EXPECT_FLOAT_EQ(adjusted_config.suppressor.nearend_tuning.max_inc_factor,
                  0.5);
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

TEST(EchoCanceller3InputCheckDeathTest, WrongCaptureNumBandsCheckVerification) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Tester(rate).RunProcessCaptureNumBandsCheckVerification();
  }
}

// Verifiers that the verification for null input to the capture processing api
// call works.
TEST(EchoCanceller3InputCheckDeathTest, NullCaptureProcessingParameter) {
  EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 16000, 1, 1)
                   .ProcessCapture(nullptr, false),
               "");
}

// Verifies the check for correct sample rate.
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
// tests on test bots has been fixed.
TEST(EchoCanceller3InputCheckDeathTest, DISABLED_WrongSampleRate) {
  ApmDataDumper data_dumper(0);
  EXPECT_DEATH(EchoCanceller3(EchoCanceller3Config(), 8001, 1, 1), "");
}

#endif

}  // namespace webrtc
