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

#include <algorithm>
#include <array>
#include <cstddef>
#include <memory>
#include <span>
#include <vector>

#include "api/audio/echo_canceller3_config.h"
#include "api/environment/environment.h"
#include "modules/audio_processing/aec3/adaptive_fir_filter.h"
#include "modules/audio_processing/aec3/adaptive_fir_filter_erl.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/aec3_fft.h"
#include "modules/audio_processing/aec3/aec_state.h"
#include "modules/audio_processing/aec3/block.h"
#include "modules/audio_processing/aec3/coarse_filter_update_gain.h"
#include "modules/audio_processing/aec3/echo_path_variability.h"
#include "modules/audio_processing/aec3/fft_data.h"
#include "modules/audio_processing/aec3/refined_filter_update_gain.h"
#include "modules/audio_processing/aec3/render_buffer.h"
#include "modules/audio_processing/aec3/render_signal_analyzer.h"
#include "modules/audio_processing/aec3/subtractor_output.h"
#include "modules/audio_processing/logging/apm_data_dumper.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_minmax.h"

namespace webrtc {

namespace {

void PredictionError(const Aec3Fft& fft,
                     const FftData& S,
                     std::span<const float> y,
                     std::array<float, kBlockSize>* e,
                     std::array<float, kBlockSize>* s) {
  std::array<float, kFftLength> tmp;
  fft.Ifft(S, &tmp);
  constexpr float kScale = 1.0f / kFftLengthBy2;
  std::transform(y.begin(), y.end(), tmp.begin() + kFftLengthBy2, e->begin(),
                 [&](float a, float b) { return a - b * kScale; });

  if (s) {
    for (size_t k = 0; k < s->size(); ++k) {
      (*s)[k] = kScale * tmp[k + kFftLengthBy2];
    }
  }
}

void ScaleFilterOutput(std::span<const float> y,
                       float factor,
                       std::span<float> e,
                       std::span<float> s) {
  RTC_DCHECK_EQ(y.size(), e.size());
  RTC_DCHECK_EQ(y.size(), s.size());
  for (size_t k = 0; k < y.size(); ++k) {
    s[k] *= factor;
    e[k] = y[k] - s[k];
  }
}

}  // namespace

Subtractor::Subtractor(const Environment& env,
                       const EchoCanceller3Config& config,
                       size_t num_render_channels,
                       size_t num_capture_channels,
                       ApmDataDumper* data_dumper,
                       Aec3Optimization optimization)
    : fft_(),
      data_dumper_(data_dumper),
      optimization_(optimization),
      config_(config),
      num_capture_channels_(num_capture_channels),
      refined_filters_(num_capture_channels_),
      coarse_filter_(num_capture_channels_),
      refined_gains_(num_capture_channels_),
      coarse_gains_(num_capture_channels_),
      filter_misadjustment_estimators_(num_capture_channels_),
      poor_coarse_filter_counters_(num_capture_channels_, 0),
      coarse_filter_reset_hangover_(num_capture_channels_, 0),
      refined_frequency_responses_(
          num_capture_channels_,
          std::vector<std::array<float, kFftLengthBy2Plus1>>(
              std::max(config_.filter.refined_initial.length_blocks,
                       config_.filter.refined.length_blocks),
              std::array<float, kFftLengthBy2Plus1>())),
      refined_impulse_responses_(
          num_capture_channels_,
          std::vector<float>(GetTimeDomainLength(std::max(
                                 config_.filter.refined_initial.length_blocks,
                                 config_.filter.refined.length_blocks)),
                             0.f)),
      coarse_impulse_responses_(0) {
  // Set up the storing of coarse impulse responses if data dumping is
  // available.
  if (ApmDataDumper::IsAvailable()) {
    coarse_impulse_responses_.resize(num_capture_channels_);
    const size_t filter_size = GetTimeDomainLength(
        std::max(config_.filter.coarse_initial.length_blocks,
                 config_.filter.coarse.length_blocks));
    for (std::vector<float>& impulse_response : coarse_impulse_responses_) {
      impulse_response.resize(filter_size, 0.f);
    }
  }

  for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
    refined_filters_[ch] = std::make_unique<AdaptiveFirFilter>(
        config_.filter.refined.length_blocks,
        config_.filter.refined_initial.length_blocks,
        config.filter.config_change_duration_blocks, num_render_channels,
        optimization, data_dumper_);

    coarse_filter_[ch] = std::make_unique<AdaptiveFirFilter>(
        config_.filter.coarse.length_blocks,
        config_.filter.coarse_initial.length_blocks,
        config.filter.config_change_duration_blocks, num_render_channels,
        optimization, data_dumper_);
    refined_gains_[ch] = std::make_unique<RefinedFilterUpdateGain>(
        config_.filter.refined_initial,
        config_.filter.config_change_duration_blocks);
    coarse_gains_[ch] = std::make_unique<CoarseFilterUpdateGain>(
        config_.filter.coarse_initial,
        config.filter.config_change_duration_blocks);
  }

  RTC_DCHECK(data_dumper_);
  for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
    for (auto& H2_k : refined_frequency_responses_[ch]) {
      H2_k.fill(0.f);
    }
  }
}

Subtractor::~Subtractor() = default;

void Subtractor::HandleEchoPathChange(
    const EchoPathVariability& echo_path_variability) {
  const auto full_reset = [&]() {
    for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
      refined_filters_[ch]->HandleEchoPathChange();
      coarse_filter_[ch]->HandleEchoPathChange();
      refined_gains_[ch]->HandleEchoPathChange(echo_path_variability);
      coarse_gains_[ch]->HandleEchoPathChange();
      refined_gains_[ch]->SetConfig(config_.filter.refined_initial, true);
      coarse_gains_[ch]->SetConfig(config_.filter.coarse_initial, true);
      refined_filters_[ch]->SetSizePartitions(
          config_.filter.refined_initial.length_blocks, true);
      coarse_filter_[ch]->SetSizePartitions(
          config_.filter.coarse_initial.length_blocks, true);
    }
  };

  if (echo_path_variability.delay_change !=
      EchoPathVariability::DelayAdjustment::kNone) {
    full_reset();
  }

  if (echo_path_variability.gain_change) {
    for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
      refined_gains_[ch]->HandleEchoPathChange(echo_path_variability);
    }
  }
}

void Subtractor::ExitInitialState() {
  for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
    refined_gains_[ch]->SetConfig(config_.filter.refined, false);
    coarse_gains_[ch]->SetConfig(config_.filter.coarse, false);
    refined_filters_[ch]->SetSizePartitions(
        config_.filter.refined.length_blocks, false);
    coarse_filter_[ch]->SetSizePartitions(config_.filter.coarse.length_blocks,
                                          false);
  }
}

void Subtractor::Process(const RenderBuffer& render_buffer,
                         const Block& capture,
                         const RenderSignalAnalyzer& render_signal_analyzer,
                         const AecState& aec_state,
                         std::span<SubtractorOutput> outputs) {
  RTC_DCHECK_EQ(num_capture_channels_, capture.NumChannels());

  // Compute the render powers.
  const bool same_filter_sizes = refined_filters_[0]->SizePartitions() ==
                                 coarse_filter_[0]->SizePartitions();
  std::array<float, kFftLengthBy2Plus1> X2_refined;
  std::array<float, kFftLengthBy2Plus1> X2_coarse_data;
  auto& X2_coarse = same_filter_sizes ? X2_refined : X2_coarse_data;
  if (same_filter_sizes) {
    render_buffer.SpectralSum(refined_filters_[0]->SizePartitions(),
                              &X2_refined);
  } else if (refined_filters_[0]->SizePartitions() >
             coarse_filter_[0]->SizePartitions()) {
    render_buffer.SpectralSums(coarse_filter_[0]->SizePartitions(),
                               refined_filters_[0]->SizePartitions(),
                               &X2_coarse, &X2_refined);
  } else {
    render_buffer.SpectralSums(refined_filters_[0]->SizePartitions(),
                               coarse_filter_[0]->SizePartitions(), &X2_refined,
                               &X2_coarse);
  }

  // Process all capture channels
  for (size_t ch = 0; ch < num_capture_channels_; ++ch) {
    SubtractorOutput& output = outputs[ch];
    std::span<const float> y = capture.View(/*band=*/0, ch);
    FftData& E_refined = output.E_refined;
    FftData E_coarse;
    std::array<float, kBlockSize>& e_refined = output.e_refined;
    std::array<float, kBlockSize>& e_coarse = output.e_coarse;

    FftData S;
    FftData& G = S;

    // Form the outputs of the refined and coarse filters.
    refined_filters_[ch]->Filter(render_buffer, &S);
    PredictionError(fft_, S, y, &e_refined, &output.s_refined);

    coarse_filter_[ch]->Filter(render_buffer, &S);
    PredictionError(fft_, S, y, &e_coarse, &output.s_coarse);

    // Compute the signal powers in the subtractor output.
    output.ComputeMetrics(y);

    // Adjust the filter if needed.
    bool refined_filters_adjusted = false;
    filter_misadjustment_estimators_[ch].Update(output);
    if (filter_misadjustment_estimators_[ch].IsAdjustmentNeeded()) {
      float scale = filter_misadjustment_estimators_[ch].GetMisadjustment();
      refined_filters_[ch]->ScaleFilter(scale);
      for (auto& h_k : refined_impulse_responses_[ch]) {
        h_k *= scale;
      }
      ScaleFilterOutput(y, scale, e_refined, output.s_refined);
      filter_misadjustment_estimators_[ch].Reset();
      refined_filters_adjusted = true;
    }

    // Compute the FFts of the refined and coarse filter outputs.
    fft_.ZeroPaddedFft(e_refined, Aec3Fft::Window::kHanning, &E_refined);
    fft_.ZeroPaddedFft(e_coarse, Aec3Fft::Window::kHanning, &E_coarse);

    // Compute spectra for future use.
    E_coarse.Spectrum(optimization_, output.E2_coarse);
    E_refined.Spectrum(optimization_, output.E2_refined);

    // Update the refined filter.
    if (!refined_filters_adjusted) {
      // Do not allow the performance of the coarse filter to affect the
      // adaptation speed of the refined filter just after the coarse filter has
      // been reset.
      const bool disallow_leakage_diverged =
          coarse_filter_reset_hangover_[ch] > 0;

      std::array<float, kFftLengthBy2Plus1> erl;
      ComputeErl(optimization_, refined_frequency_responses_[ch], erl);
      refined_gains_[ch]->Compute(X2_refined, render_signal_analyzer, output,
                                  erl, refined_filters_[ch]->SizePartitions(),
                                  aec_state.SaturatedCapture(),
                                  disallow_leakage_diverged, &G);
    } else {
      G.re.fill(0.f);
      G.im.fill(0.f);
    }
    refined_filters_[ch]->Adapt(render_buffer, G,
                                &refined_impulse_responses_[ch]);
    refined_filters_[ch]->ComputeFrequencyResponse(
        &refined_frequency_responses_[ch]);

    if (ch == 0) {
      data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.re);
      data_dumper_->DumpRaw("aec3_subtractor_G_refined", G.im);
    }

    // Update the coarse filter.
    poor_coarse_filter_counters_[ch] =
        output.e2_refined < output.e2_coarse
            ? poor_coarse_filter_counters_[ch] + 1
            : 0;
    if (poor_coarse_filter_counters_[ch] < 5) {
      coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_coarse,
                                 coarse_filter_[ch]->SizePartitions(),
                                 aec_state.SaturatedCapture(), &G);
      coarse_filter_reset_hangover_[ch] =
          std::max(coarse_filter_reset_hangover_[ch] - 1, 0);
    } else {
      poor_coarse_filter_counters_[ch] = 0;
      coarse_filter_[ch]->SetFilter(refined_filters_[ch]->SizePartitions(),
                                    refined_filters_[ch]->GetFilter());
      coarse_gains_[ch]->Compute(X2_coarse, render_signal_analyzer, E_refined,
                                 coarse_filter_[ch]->SizePartitions(),
                                 aec_state.SaturatedCapture(), &G);
      coarse_filter_reset_hangover_[ch] =
          config_.filter.coarse_reset_hangover_blocks;
    }

    if (ApmDataDumper::IsAvailable()) {
      RTC_DCHECK_LT(ch, coarse_impulse_responses_.size());
      coarse_filter_[ch]->Adapt(render_buffer, G,
                                &coarse_impulse_responses_[ch]);
    } else {
      coarse_filter_[ch]->Adapt(render_buffer, G);
    }

    if (ch == 0) {
      data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.re);
      data_dumper_->DumpRaw("aec3_subtractor_G_coarse", G.im);
      filter_misadjustment_estimators_[ch].Dump(data_dumper_);
      DumpFilters();
    }

    std::for_each(e_refined.begin(), e_refined.end(),
                  [](float& a) { a = SafeClamp(a, -32768.f, 32767.f); });

    if (ch == 0) {
      data_dumper_->DumpWav("aec3_refined_filters_output", kBlockSize,
                            &e_refined[0], 16000, 1);
      data_dumper_->DumpWav("aec3_coarse_filter_output", kBlockSize,
                            &e_coarse[0], 16000, 1);
    }
  }
}

void Subtractor::FilterMisadjustmentEstimator::Update(
    const SubtractorOutput& output) {
  e2_acum_ += output.e2_refined;
  y2_acum_ += output.y2;
  if (++n_blocks_acum_ == n_blocks_) {
    if (y2_acum_ > n_blocks_ * 200.f * 200.f * kBlockSize) {
      float update = (e2_acum_ / y2_acum_);
      if (e2_acum_ > n_blocks_ * 7500.f * 7500.f * kBlockSize) {
        // Duration equal to blockSizeMs * n_blocks_ * 4.
        overhang_ = 4;
      } else {
        overhang_ = std::max(overhang_ - 1, 0);
      }

      if ((update < inv_misadjustment_) || (overhang_ > 0)) {
        inv_misadjustment_ += 0.1f * (update - inv_misadjustment_);
      }
    }
    e2_acum_ = 0.f;
    y2_acum_ = 0.f;
    n_blocks_acum_ = 0;
  }
}

void Subtractor::FilterMisadjustmentEstimator::Reset() {
  e2_acum_ = 0.f;
  y2_acum_ = 0.f;
  n_blocks_acum_ = 0;
  inv_misadjustment_ = 0.f;
  overhang_ = 0.f;
}

void Subtractor::FilterMisadjustmentEstimator::Dump(
    ApmDataDumper* data_dumper) const {
  data_dumper->DumpRaw("aec3_inv_misadjustment_factor", inv_misadjustment_);
}

}  // namespace webrtc
