/*
 *  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/coarse_filter_update_gain.h"

#include <algorithm>
#include <memory>
#include <numeric>
#include <string>
#include <vector>

#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
#include "modules/audio_processing/aec3/aec3_common.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/numerics/safe_minmax.h"
#include "rtc_base/random.h"
#include "rtc_base/strings/string_builder.h"
#include "test/gtest.h"

namespace webrtc {
namespace {
// Method for performing the simulations needed to test the refined filter
// update gain functionality.
void RunFilterUpdateTest(int num_blocks_to_process,
                         size_t delay_samples,
                         size_t num_render_channels,
                         int filter_length_blocks,
                         const std::vector<int>& blocks_with_saturation,
                         std::array<float, kBlockSize>* e_last_block,
                         std::array<float, kBlockSize>* y_last_block,
                         FftData* G_last_block) {
  ApmDataDumper data_dumper(42);
  EchoCanceller3Config config;
  config.filter.refined.length_blocks = filter_length_blocks;
  AdaptiveFirFilter refined_filter(
      config.filter.refined.length_blocks, config.filter.refined.length_blocks,
      config.filter.config_change_duration_blocks, num_render_channels,
      DetectOptimization(), &data_dumper);
  AdaptiveFirFilter coarse_filter(
      config.filter.coarse.length_blocks, config.filter.coarse.length_blocks,
      config.filter.config_change_duration_blocks, num_render_channels,
      DetectOptimization(), &data_dumper);
  Aec3Fft fft;

  constexpr int kSampleRateHz = 48000;
  config.delay.default_delay = 1;
  std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
      RenderDelayBuffer::Create(config, kSampleRateHz, num_render_channels));

  CoarseFilterUpdateGain coarse_gain(
      config.filter.coarse, config.filter.config_change_duration_blocks);
  Random random_generator(42U);
  Block x(NumBandsForRate(kSampleRateHz), num_render_channels);
  std::array<float, kBlockSize> y;
  RenderSignalAnalyzer render_signal_analyzer(config);
  std::array<float, kFftLength> s;
  FftData S;
  FftData G;
  FftData E_coarse;
  std::array<float, kBlockSize> e_coarse;

  constexpr float kScale = 1.0f / kFftLengthBy2;

  DelayBuffer<float> delay_buffer(delay_samples);
  for (int k = 0; k < num_blocks_to_process; ++k) {
    // Handle saturation.
    bool saturation =
        std::find(blocks_with_saturation.begin(), blocks_with_saturation.end(),
                  k) != blocks_with_saturation.end();

    // Create the render signal.
    for (int band = 0; band < x.NumBands(); ++band) {
      for (int channel = 0; channel < x.NumChannels(); ++channel) {
        RandomizeSampleVector(&random_generator, x.View(band, channel));
      }
    }
    delay_buffer.Delay(x.View(/*band=*/0, /*channel*/ 0), y);

    render_delay_buffer->Insert(x);
    if (k == 0) {
      render_delay_buffer->Reset();
    }
    render_delay_buffer->PrepareCaptureProcessing();

    render_signal_analyzer.Update(*render_delay_buffer->GetRenderBuffer(),
                                  delay_samples / kBlockSize);

    coarse_filter.Filter(*render_delay_buffer->GetRenderBuffer(), &S);
    fft.Ifft(S, &s);
    std::transform(y.begin(), y.end(), s.begin() + kFftLengthBy2,
                   e_coarse.begin(),
                   [&](float a, float b) { return a - b * kScale; });
    std::for_each(e_coarse.begin(), e_coarse.end(),
                  [](float& a) { a = rtc::SafeClamp(a, -32768.f, 32767.f); });
    fft.ZeroPaddedFft(e_coarse, Aec3Fft::Window::kRectangular, &E_coarse);

    std::array<float, kFftLengthBy2Plus1> render_power;
    render_delay_buffer->GetRenderBuffer()->SpectralSum(
        coarse_filter.SizePartitions(), &render_power);
    coarse_gain.Compute(render_power, render_signal_analyzer, E_coarse,
                        coarse_filter.SizePartitions(), saturation, &G);
    coarse_filter.Adapt(*render_delay_buffer->GetRenderBuffer(), G);
  }

  std::copy(e_coarse.begin(), e_coarse.end(), e_last_block->begin());
  std::copy(y.begin(), y.end(), y_last_block->begin());
  std::copy(G.re.begin(), G.re.end(), G_last_block->re.begin());
  std::copy(G.im.begin(), G.im.end(), G_last_block->im.begin());
}

std::string ProduceDebugText(int filter_length_blocks) {
  rtc::StringBuilder ss;
  ss << "Length: " << filter_length_blocks;
  return ss.Release();
}

std::string ProduceDebugText(size_t delay, int filter_length_blocks) {
  rtc::StringBuilder ss;
  ss << "Delay: " << delay << ", ";
  ss << ProduceDebugText(filter_length_blocks);
  return ss.Release();
}

}  // namespace

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

// Verifies that the check for non-null output gain parameter works.
TEST(CoarseFilterUpdateGainDeathTest, NullDataOutputGain) {
  ApmDataDumper data_dumper(42);
  FftBuffer fft_buffer(1, 1);
  RenderSignalAnalyzer analyzer(EchoCanceller3Config{});
  FftData E;
  const EchoCanceller3Config::Filter::CoarseConfiguration& config = {
      12, 0.5f, 220075344.f};
  CoarseFilterUpdateGain gain(config, 250);
  std::array<float, kFftLengthBy2Plus1> render_power;
  render_power.fill(0.f);
  EXPECT_DEATH(gain.Compute(render_power, analyzer, E, 1, false, nullptr), "");
}

#endif

class CoarseFilterUpdateGainOneTwoEightRenderChannels
    : public ::testing::Test,
      public ::testing::WithParamInterface<size_t> {};

INSTANTIATE_TEST_SUITE_P(MultiChannel,
                         CoarseFilterUpdateGainOneTwoEightRenderChannels,
                         ::testing::Values(1, 2, 8));

// Verifies that the gain formed causes the filter using it to converge.
TEST_P(CoarseFilterUpdateGainOneTwoEightRenderChannels,
       GainCausesFilterToConverge) {
  const size_t num_render_channels = GetParam();
  std::vector<int> blocks_with_echo_path_changes;
  std::vector<int> blocks_with_saturation;

  for (size_t filter_length_blocks : {12, 20, 30}) {
    for (size_t delay_samples : {0, 64, 150, 200, 301}) {
      SCOPED_TRACE(ProduceDebugText(delay_samples, filter_length_blocks));

      std::array<float, kBlockSize> e;
      std::array<float, kBlockSize> y;
      FftData G;

      RunFilterUpdateTest(5000, delay_samples, num_render_channels,
                          filter_length_blocks, blocks_with_saturation, &e, &y,
                          &G);

      // Verify that the refined filter is able to perform well.
      // Use different criteria to take overmodelling into account.
      if (filter_length_blocks == 12) {
        EXPECT_LT(1000 * std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
                  std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
      } else {
        EXPECT_LT(std::inner_product(e.begin(), e.end(), e.begin(), 0.f),
                  std::inner_product(y.begin(), y.end(), y.begin(), 0.f));
      }
    }
  }
}

// Verifies that the gain is zero when there is saturation.
TEST_P(CoarseFilterUpdateGainOneTwoEightRenderChannels, SaturationBehavior) {
  const size_t num_render_channels = GetParam();
  std::vector<int> blocks_with_echo_path_changes;
  std::vector<int> blocks_with_saturation;
  for (int k = 99; k < 200; ++k) {
    blocks_with_saturation.push_back(k);
  }
  for (size_t filter_length_blocks : {12, 20, 30}) {
    SCOPED_TRACE(ProduceDebugText(filter_length_blocks));

    std::array<float, kBlockSize> e;
    std::array<float, kBlockSize> y;
    FftData G_a;
    FftData G_a_ref;
    G_a_ref.re.fill(0.f);
    G_a_ref.im.fill(0.f);

    RunFilterUpdateTest(100, 65, num_render_channels, filter_length_blocks,
                        blocks_with_saturation, &e, &y, &G_a);

    EXPECT_EQ(G_a_ref.re, G_a.re);
    EXPECT_EQ(G_a_ref.im, G_a.im);
  }
}

class CoarseFilterUpdateGainOneTwoFourRenderChannels
    : public ::testing::Test,
      public ::testing::WithParamInterface<size_t> {};

INSTANTIATE_TEST_SUITE_P(
    MultiChannel,
    CoarseFilterUpdateGainOneTwoFourRenderChannels,
    ::testing::Values(1, 2, 4),
    [](const ::testing::TestParamInfo<
        CoarseFilterUpdateGainOneTwoFourRenderChannels::ParamType>& info) {
      return (rtc::StringBuilder() << "Render" << info.param).str();
    });

// Verifies that the magnitude of the gain on average decreases for a
// persistently exciting signal.
TEST_P(CoarseFilterUpdateGainOneTwoFourRenderChannels, DecreasingGain) {
  const size_t num_render_channels = GetParam();
  for (size_t filter_length_blocks : {12, 20, 30}) {
    SCOPED_TRACE(ProduceDebugText(filter_length_blocks));
    std::vector<int> blocks_with_echo_path_changes;
    std::vector<int> blocks_with_saturation;

    std::array<float, kBlockSize> e;
    std::array<float, kBlockSize> y;
    FftData G_a;
    FftData G_b;
    FftData G_c;
    std::array<float, kFftLengthBy2Plus1> G_a_power;
    std::array<float, kFftLengthBy2Plus1> G_b_power;
    std::array<float, kFftLengthBy2Plus1> G_c_power;

    RunFilterUpdateTest(100, 65, num_render_channels, filter_length_blocks,
                        blocks_with_saturation, &e, &y, &G_a);
    RunFilterUpdateTest(200, 65, num_render_channels, filter_length_blocks,
                        blocks_with_saturation, &e, &y, &G_b);
    RunFilterUpdateTest(300, 65, num_render_channels, filter_length_blocks,
                        blocks_with_saturation, &e, &y, &G_c);

    G_a.Spectrum(Aec3Optimization::kNone, G_a_power);
    G_b.Spectrum(Aec3Optimization::kNone, G_b_power);
    G_c.Spectrum(Aec3Optimization::kNone, G_c_power);

    EXPECT_GT(std::accumulate(G_a_power.begin(), G_a_power.end(), 0.),
              std::accumulate(G_b_power.begin(), G_b_power.end(), 0.));

    EXPECT_GT(std::accumulate(G_b_power.begin(), G_b_power.end(), 0.),
              std::accumulate(G_c_power.begin(), G_c_power.end(), 0.));
  }
}
}  // namespace webrtc
