/*
 *  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 <algorithm>
#include <array>
#include <cstddef>
#include <deque>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>
#include <vector>

#include "api/audio/echo_canceller3_config.h"
#include "api/audio/echo_control.h"
#include "api/audio/neural_residual_echo_estimator.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/block.h"
#include "modules/audio_processing/aec3/block_processor.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/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"
#include "test/create_test_field_trials.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(std::span<const float> reference,
                                   std::span<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 */,
                      Block* /* linear_output */,
                      Block* /* capture_block */) override {}

  void BufferRender(const Block& /* block */) override {}

  void UpdateEchoLeakageStatus(bool /* leakage_detected */) override {}

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

  void SetAudioBufferDelay(int /* delay_ms */) override {}

  void SetCaptureOutputUsage(bool /* capture_output_used */) 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 */,
                      Block* /* linear_output */,
                      Block* capture_block) override {
    Block render_block = received_render_blocks_.front();
    received_render_blocks_.pop_front();
    capture_block->Swap(render_block);
  }

  void BufferRender(const Block& 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 {}

  void SetCaptureOutputUsage(bool /* capture_output_used */) override {}

 private:
  std::deque<Block> received_render_blocks_;
};

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

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

void RunAecInStereo(AudioBuffer& buffer,
                    EchoCanceller3& aec3,
                    float channel_0_value,
                    float channel_1_value) {
  std::span<float> data_channel_0(&buffer.channels()[0][0],
                                  buffer.num_frames());
  std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
  std::span<float> data_channel_1(&buffer.channels()[1][0],
                                  buffer.num_frames());
  std::fill(data_channel_1.begin(), data_channel_1.end(), channel_1_value);
  aec3.AnalyzeRender(&buffer);
  aec3.AnalyzeCapture(&buffer);
  aec3.ProcessCapture(&buffer, /*level_change=*/false);
}

void RunAecInSMono(AudioBuffer& buffer,
                   EchoCanceller3& aec3,
                   float channel_0_value) {
  std::span<float> data_channel_0(&buffer.channels()[0][0],
                                  buffer.num_frames());
  std::fill(data_channel_0.begin(), data_channel_0.end(), channel_0_value);
  aec3.AnalyzeRender(&buffer);
  aec3.AnalyzeCapture(&buffer);
  aec3.ProcessCapture(&buffer, /*level_change=*/false);
}

}  // namespace

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_(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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(
        std::make_unique<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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(
        std::make_unique<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]);
      }
    }

    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<test::MockBlockProcessor>>
        block_processor_mock(new StrictMock<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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(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<test::MockBlockProcessor>>
        block_processor_mock(new StrictMock<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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(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<test::MockBlockProcessor>>
        block_processor_mock(new StrictMock<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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(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(CreateEnvironment(), config,
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        sample_rate_hz_, 1, 1);
    aec3.SetBlockProcessorForTesting(
        std::make_unique<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]);
      }
    }

    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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        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(CreateEnvironment(), EchoCanceller3Config(),
                        /*multichannel_config=*/std::nullopt,
                        /*neural_residual_echo_estimator=*/nullptr,
                        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_;
};

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
// anti-howling gain.
TEST(EchoCanceller3FieldTrials, Aec3SuppressorAntiHowlingGainOverride) {
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, CreateTestFieldTrials());
  ASSERT_EQ(
      default_config.suppressor.high_bands_suppression.anti_howling_gain,
      adjusted_config.suppressor.high_bands_suppression.anti_howling_gain);

  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3SuppressorAntiHowlingGainOverride/0.02/");
  adjusted_config = AdjustConfig(default_config, field_trials);

  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, CreateTestFieldTrials());
  ASSERT_EQ(default_config.render_levels.active_render_limit,
            adjusted_config.render_levels.active_render_limit);

  FieldTrials field_trials =
      CreateTestFieldTrials("WebRTC-Aec3EnforceLowActiveRenderLimit/Enabled/");
  adjusted_config = AdjustConfig(default_config, field_trials);

  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) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "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/");

  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);

  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);

  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);
}

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

  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);

  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);
}

// Testing the field trial-based that override the exponential decay parameters.
TEST(EchoCanceller3FieldTrials, Aec3UseNearendReverb) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3UseNearendReverbLen/default_len:0.9,nearend_len:0.8/");
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);
  EXPECT_FLOAT_EQ(adjusted_config.ep_strength.default_len, 0.9);
  EXPECT_FLOAT_EQ(adjusted_config.ep_strength.nearend_len, 0.8);
}

// Testing the field trial-based that overrides the maximum allowed ecess render
// blocks in the render buffering.
TEST(EchoCanceller3FieldTrials, Aec3BufferingMaxAllowedExcessRenderBlocks) {
  FieldTrials field_trials = CreateTestFieldTrials(
      "WebRTC-Aec3BufferingMaxAllowedExcessRenderBlocksOverride/2/");
  EchoCanceller3Config default_config;
  EchoCanceller3Config adjusted_config =
      AdjustConfig(default_config, field_trials);
  EXPECT_EQ(adjusted_config.buffering.max_allowed_excess_render_blocks, 2ul);
}

TEST(EchoCanceller3, DetectionOfProperStereo) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> multichannel_config;

  mono_config.multi_channel.detect_stereo_content = true;
  mono_config.multi_channel.stereo_detection_threshold = 0.0f;
  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
  multichannel_config = mono_config;
  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
  multichannel_config->filter.coarse_initial.length_blocks =
      kNumBlocksForSurroundConfig;

  EchoCanceller3 aec3(CreateEnvironment(), mono_config, multichannel_config,
                      /*neural_residual_echo_estimator=*/nullptr,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);

  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForSurroundConfig);
}

TEST(EchoCanceller3, DetectionOfProperStereoUsingThreshold) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> multichannel_config;

  constexpr float kStereoDetectionThreshold = 2.0f;
  mono_config.multi_channel.detect_stereo_content = true;
  mono_config.multi_channel.stereo_detection_threshold =
      kStereoDetectionThreshold;
  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.0f;
  multichannel_config = mono_config;
  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
  multichannel_config->filter.coarse_initial.length_blocks =
      kNumBlocksForSurroundConfig;

  EchoCanceller3 aec3(CreateEnvironment(), mono_config, multichannel_config,
                      /*neural_residual_echo_estimator=*/nullptr,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);

  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f,
                 100.0f + kStereoDetectionThreshold - 1.0f);
  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f,
                 100.0f + kStereoDetectionThreshold + 10.0f);
  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForSurroundConfig);
}

TEST(EchoCanceller3, DetectionOfProperStereoUsingHysteresis) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> surround_config;

  mono_config.multi_channel.detect_stereo_content = true;
  mono_config.multi_channel.stereo_detection_hysteresis_seconds = 0.5f;
  surround_config = mono_config;
  mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
  surround_config->filter.coarse_initial.length_blocks =
      kNumBlocksForSurroundConfig;

  EchoCanceller3 aec3(CreateEnvironment(), mono_config, surround_config,
                      /*neural_residual_echo_estimator=*/nullptr,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);

  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  RunAecInStereo(buffer, aec3, 100.0f, 100.0f);
  EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForMonoConfig);

  constexpr int kNumFramesPerSecond = 100;
  for (int k = 0;
       k < static_cast<int>(
               kNumFramesPerSecond *
               mono_config.multi_channel.stereo_detection_hysteresis_seconds);
       ++k) {
    RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    EXPECT_EQ(
        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
        kNumBlocksForMonoConfig);
  }

  RunAecInStereo(buffer, aec3, 100.0f, 101.0f);
  EXPECT_TRUE(aec3.StereoRenderProcessingActiveForTesting());
  EXPECT_EQ(
      aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
      kNumBlocksForSurroundConfig);
}

TEST(EchoCanceller3, StereoContentDetectionForMonoSignals) {
  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 2;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*input_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);

  constexpr size_t kNumBlocksForMonoConfig = 1;
  constexpr size_t kNumBlocksForSurroundConfig = 2;
  const Environment env = CreateEnvironment();
  EchoCanceller3Config mono_config;
  std::optional<EchoCanceller3Config> multichannel_config;

  for (bool detect_stereo_content : {false, true}) {
    mono_config.multi_channel.detect_stereo_content = detect_stereo_content;
    multichannel_config = mono_config;
    mono_config.filter.coarse_initial.length_blocks = kNumBlocksForMonoConfig;
    multichannel_config->filter.coarse_initial.length_blocks =
        kNumBlocksForSurroundConfig;

    AudioBuffer mono_buffer(/*input_rate=*/kSampleRateHz,
                            /*input_num_channels=*/1,
                            /*input_rate=*/kSampleRateHz,
                            /*buffer_num_channels=*/1,
                            /*output_rate=*/kSampleRateHz,
                            /*output_num_channels=*/1);

    EchoCanceller3 aec3(env, mono_config, multichannel_config,
                        /*neural_residual_echo_estimator=*/nullptr,
                        /*sample_rate_hz=*/kSampleRateHz,
                        /*num_render_channels=*/1,
                        /*num_capture_channels=*/1);

    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    EXPECT_EQ(
        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
        kNumBlocksForMonoConfig);

    RunAecInSMono(mono_buffer, aec3, 100.0f);
    EXPECT_FALSE(aec3.StereoRenderProcessingActiveForTesting());
    EXPECT_EQ(
        aec3.GetActiveConfigForTesting().filter.coarse_initial.length_blocks,
        kNumBlocksForMonoConfig);
  }
}

TEST(EchoCanceller3, InjectedNeuralResidualEchoEstimatorIsUsed) {
  class NeuralResidualEchoEstimatorMock : public NeuralResidualEchoEstimator {
   public:
    NeuralResidualEchoEstimatorMock() {}

    void Estimate(const Block& render,
                  std::span<const std::array<float, 64>> capture,
                  std::span<const std::array<float, 64>> linear_aec_output,
                  std::span<const std::array<float, 65>> S2_linear,
                  std::span<const std::array<float, 65>> Y2,
                  std::span<const std::array<float, 65>> E2,
                  bool dominant_nearend,
                  std::span<std::array<float, 65>> R2,
                  std::span<std::array<float, 65>> R2_unbounded) override {
      residual_echo_estimate_requested_ = true;
      for (auto& R2_ch : R2) {
        R2_ch.fill(0.0f);
      }
      for (auto& R2_ch : R2_unbounded) {
        R2_ch.fill(0.0f);
      }
    }
    bool residual_echo_estimate_requested() const {
      return residual_echo_estimate_requested_;
    }

    EchoCanceller3Config::Suppressor AdjustConfig(
        const EchoCanceller3Config::Suppressor& config) const override {
      return config;
    }

    MOCK_METHOD(void, Reset, (), (override));

   private:
    bool residual_echo_estimate_requested_ = false;
  };

  constexpr int kSampleRateHz = 16000;
  constexpr int kNumChannels = 1;
  NeuralResidualEchoEstimatorMock neural_residual_echo_estimator;
  const Environment env = CreateEnvironment();
  EchoCanceller3Config config;
  AudioBuffer buffer(/*input_rate=*/kSampleRateHz,
                     /*input_num_channels=*/kNumChannels,
                     /*buffer_rate=*/kSampleRateHz,
                     /*buffer_num_channels=*/kNumChannels,
                     /*output_rate=*/kSampleRateHz,
                     /*output_num_channels=*/kNumChannels);
  EchoCanceller3 aec3(env, config, /*multichannel_config=*/std::nullopt,
                      &neural_residual_echo_estimator,
                      /*sample_rate_hz=*/kSampleRateHz,
                      /*num_render_channels=*/kNumChannels,
                      /*num_capture_channels=*/kNumChannels);
  constexpr int kNumFramesToProcess = 300;
  for (int k = 0; k < kNumFramesToProcess; ++k) {
    RunAecInSMono(buffer, aec3, k);
  }
  EXPECT_TRUE(
      neural_residual_echo_estimator.residual_echo_estimate_requested());
}

#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(CreateEnvironment(), EchoCanceller3Config(),
                     /*multichannel_config_=*/std::nullopt,
                     /*neural_residual_echo_estimator=*/nullptr, 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(CreateEnvironment(), EchoCanceller3Config(),
                     /*multichannel_config_=*/std::nullopt,
                     /*neural_residual_echo_estimator=*/nullptr, 8001, 1, 1),
      "");
}

#endif

}  // namespace webrtc
