/*
 *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "modules/audio_processing/aec3/residual_echo_estimator.h"

#include "api/audio/echo_canceller3_config.h"
#include "modules/audio_processing/aec3/aec3_fft.h"
#include "modules/audio_processing/aec3/aec_state.h"
#include "modules/audio_processing/aec3/render_delay_buffer.h"
#include "modules/audio_processing/test/echo_canceller_test_tools.h"
#include "rtc_base/random.h"
#include "test/gtest.h"

namespace webrtc {

TEST(ResidualEchoEstimator, BasicTest) {
  for (size_t num_render_channels : {1, 2, 4}) {
    for (size_t num_capture_channels : {1, 2, 4}) {
      constexpr int kSampleRateHz = 48000;
      constexpr size_t kNumBands = NumBandsForRate(kSampleRateHz);

      EchoCanceller3Config config;
      ResidualEchoEstimator estimator(config, num_render_channels);
      AecState aec_state(config, num_capture_channels);
      std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
          RenderDelayBuffer::Create(config, kSampleRateHz,
                                    num_render_channels));

      std::vector<std::array<float, kFftLengthBy2Plus1>> E2_main(
          num_capture_channels);
      std::vector<std::array<float, kFftLengthBy2Plus1>> S2_linear(
          num_capture_channels);
      std::vector<std::array<float, kFftLengthBy2Plus1>> Y2(
          num_capture_channels);
      std::vector<std::array<float, kFftLengthBy2Plus1>> R2(
          num_capture_channels);
      std::vector<std::vector<std::vector<float>>> x(
          kNumBands,
          std::vector<std::vector<float>>(num_render_channels,
                                          std::vector<float>(kBlockSize, 0.f)));
      std::vector<std::vector<std::array<float, kFftLengthBy2Plus1>>> H2(
          num_capture_channels,
          std::vector<std::array<float, kFftLengthBy2Plus1>>(10));
      Random random_generator(42U);
      std::vector<SubtractorOutput> output(num_capture_channels);
      std::array<float, kBlockSize> y;
      absl::optional<DelayEstimate> delay_estimate;

      for (auto& H2_ch : H2) {
        for (auto& H2_k : H2_ch) {
          H2_k.fill(0.01f);
        }
        H2_ch[2].fill(10.f);
        H2_ch[2][0] = 0.1f;
      }

      std::vector<std::vector<float>> h(
          num_capture_channels,
          std::vector<float>(
              GetTimeDomainLength(config.filter.main.length_blocks), 0.f));

      for (auto& subtractor_output : output) {
        subtractor_output.Reset();
        subtractor_output.s_main.fill(100.f);
      }
      y.fill(0.f);

      constexpr float kLevel = 10.f;
      for (auto& E2_main_ch : E2_main) {
        E2_main_ch.fill(kLevel);
      }
      S2_linear[0].fill(kLevel);
      for (auto& Y2_ch : Y2) {
        Y2_ch.fill(kLevel);
      }

      for (int k = 0; k < 1993; ++k) {
        RandomizeSampleVector(&random_generator, x[0][0]);
        render_delay_buffer->Insert(x);
        if (k == 0) {
          render_delay_buffer->Reset();
        }
        render_delay_buffer->PrepareCaptureProcessing();

        aec_state.Update(delay_estimate, H2, h,
                         *render_delay_buffer->GetRenderBuffer(), E2_main, Y2,
                         output);

        estimator.Estimate(aec_state, *render_delay_buffer->GetRenderBuffer(),
                           S2_linear, Y2, R2);
      }
    }
  }
}

}  // namespace webrtc
