/*
 *  Copyright (c) 2018 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/signal_dependent_erle_estimator.h"

#include <algorithm>
#include <iostream>
#include <string>

#include "api/audio/echo_canceller3_config.h"
#include "modules/audio_processing/aec3/render_buffer.h"
#include "modules/audio_processing/aec3/render_delay_buffer.h"
#include "rtc_base/strings/string_builder.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

void GetActiveFrame(rtc::ArrayView<float> x) {
  const std::array<float, kBlockSize> frame = {
      7459.88, 17209.6, 17383,   20768.9, 16816.7, 18386.3, 4492.83, 9675.85,
      6665.52, 14808.6, 9342.3,  7483.28, 19261.7, 4145.98, 1622.18, 13475.2,
      7166.32, 6856.61, 21937,   7263.14, 9569.07, 14919,   8413.32, 7551.89,
      7848.65, 6011.27, 13080.6, 15865.2, 12656,   17459.6, 4263.93, 4503.03,
      9311.79, 21095.8, 12657.9, 13906.6, 19267.2, 11338.1, 16828.9, 11501.6,
      11405,   15031.4, 14541.6, 19765.5, 18346.3, 19350.2, 3157.47, 18095.8,
      1743.68, 21328.2, 19727.5, 7295.16, 10332.4, 11055.5, 20107.4, 14708.4,
      12416.2, 16434,   2454.69, 9840.8,  6867.23, 1615.75, 6059.9,  8394.19};
  RTC_DCHECK_GE(x.size(), frame.size());
  std::copy(frame.begin(), frame.end(), x.begin());
}

class TestInputs {
 public:
  explicit TestInputs(const EchoCanceller3Config& cfg);
  ~TestInputs();
  const RenderBuffer& GetRenderBuffer() { return *render_buffer_; }
  rtc::ArrayView<const float> GetX2() { return X2_; }
  rtc::ArrayView<const float> GetY2() { return Y2_; }
  rtc::ArrayView<const float> GetE2() { return E2_; }
  std::vector<std::array<float, kFftLengthBy2Plus1>> GetH2() { return H2_; }
  void Update();

 private:
  void UpdateCurrentPowerSpectra();
  int n_ = 0;
  std::unique_ptr<RenderDelayBuffer> render_delay_buffer_;
  RenderBuffer* render_buffer_;
  std::array<float, kFftLengthBy2Plus1> X2_;
  std::array<float, kFftLengthBy2Plus1> Y2_;
  std::array<float, kFftLengthBy2Plus1> E2_;
  std::vector<std::array<float, kFftLengthBy2Plus1>> H2_;
  std::vector<std::vector<float>> x_;
};

TestInputs::TestInputs(const EchoCanceller3Config& cfg)
    : render_delay_buffer_(RenderDelayBuffer::Create(cfg, 1)),
      H2_(cfg.filter.main.length_blocks),
      x_(1, std::vector<float>(kBlockSize, 0.f)) {
  render_delay_buffer_->SetDelay(4);
  render_buffer_ = render_delay_buffer_->GetRenderBuffer();
  for (auto& H : H2_) {
    H.fill(0.f);
  }
  H2_[0].fill(1.0f);
}

TestInputs::~TestInputs() = default;

void TestInputs::Update() {
  if (n_ % 2 == 0) {
    std::fill(x_[0].begin(), x_[0].end(), 0.f);
  } else {
    GetActiveFrame(x_[0]);
  }

  render_delay_buffer_->Insert(x_);
  render_delay_buffer_->PrepareCaptureProcessing();
  UpdateCurrentPowerSpectra();
  ++n_;
}

void TestInputs::UpdateCurrentPowerSpectra() {
  const VectorBuffer& spectrum_render_buffer =
      render_buffer_->GetSpectrumBuffer();
  size_t idx = render_buffer_->Position();
  size_t prev_idx = spectrum_render_buffer.OffsetIndex(idx, 1);
  auto& X2 = spectrum_render_buffer.buffer[idx];
  auto& X2_prev = spectrum_render_buffer.buffer[prev_idx];
  std::copy(X2.begin(), X2.end(), X2_.begin());
  RTC_DCHECK_EQ(X2.size(), Y2_.size());
  for (size_t k = 0; k < X2.size(); ++k) {
    E2_[k] = 0.01f * X2_prev[k];
    Y2_[k] = X2[k] + E2_[k];
  }
}

}  // namespace

TEST(SignalDependentErleEstimator, SweepSettings) {
  EchoCanceller3Config cfg;
  size_t max_length_blocks = 50;
  for (size_t blocks = 0; blocks < max_length_blocks; blocks = blocks + 10) {
    for (size_t delay_headroom = 0; delay_headroom < 5; ++delay_headroom) {
      for (size_t num_sections = 2; num_sections < max_length_blocks;
           ++num_sections) {
        cfg.filter.main.length_blocks = blocks;
        cfg.filter.main_initial.length_blocks =
            std::min(cfg.filter.main_initial.length_blocks, blocks);
        cfg.delay.delay_headroom_samples = delay_headroom * kBlockSize;
        cfg.erle.num_sections = num_sections;
        if (EchoCanceller3Config::Validate(&cfg)) {
          SignalDependentErleEstimator s(cfg);
          std::array<float, kFftLengthBy2Plus1> average_erle;
          average_erle.fill(cfg.erle.max_l);
          TestInputs inputs(cfg);
          for (size_t n = 0; n < 10; ++n) {
            inputs.Update();
            s.Update(inputs.GetRenderBuffer(), inputs.GetH2(), inputs.GetX2(),
                     inputs.GetY2(), inputs.GetE2(), average_erle, true);
          }
        }
      }
    }
  }
}

TEST(SignalDependentErleEstimator, LongerRun) {
  EchoCanceller3Config cfg;
  cfg.filter.main.length_blocks = 2;
  cfg.filter.main_initial.length_blocks = 1;
  cfg.delay.delay_headroom_samples = 0;
  cfg.delay.hysteresis_limit_blocks = 0;
  cfg.erle.num_sections = 2;
  EXPECT_EQ(EchoCanceller3Config::Validate(&cfg), true);
  std::array<float, kFftLengthBy2Plus1> average_erle;
  average_erle.fill(cfg.erle.max_l);
  SignalDependentErleEstimator s(cfg);
  TestInputs inputs(cfg);
  for (size_t n = 0; n < 200; ++n) {
    inputs.Update();
    s.Update(inputs.GetRenderBuffer(), inputs.GetH2(), inputs.GetX2(),
             inputs.GetY2(), inputs.GetE2(), average_erle, true);
  }
}

}  // namespace webrtc
