/*
 *  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 "webrtc/modules/audio_processing/aec3/echo_remover_metrics.h"

#include <math.h>

#include "webrtc/modules/audio_processing/aec3/aec_state.h"
#include "webrtc/modules/audio_processing/aec3/aec3_fft.h"
#include "webrtc/test/gtest.h"

namespace webrtc {

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

// Verifies the check for non-null input.
TEST(UpdateDbMetric, NullValue) {
  std::array<float, kFftLengthBy2Plus1> value;
  value.fill(0.f);
  EXPECT_DEATH(aec3::UpdateDbMetric(value, nullptr), "");
}

#endif

// Verifies the updating functionality of UpdateDbMetric.
TEST(UpdateDbMetric, Updating) {
  std::array<float, kFftLengthBy2Plus1> value;
  std::array<EchoRemoverMetrics::DbMetric, 2> statistic;
  statistic.fill(EchoRemoverMetrics::DbMetric(0.f, 100.f, -100.f));
  constexpr float kValue0 = 10.f;
  constexpr float kValue1 = 20.f;
  std::fill(value.begin(), value.begin() + 32, kValue0);
  std::fill(value.begin() + 32, value.begin() + 64, kValue1);

  aec3::UpdateDbMetric(value, &statistic);
  EXPECT_FLOAT_EQ(kValue0, statistic[0].sum_value);
  EXPECT_FLOAT_EQ(kValue0, statistic[0].ceil_value);
  EXPECT_FLOAT_EQ(kValue0, statistic[0].floor_value);
  EXPECT_FLOAT_EQ(kValue1, statistic[1].sum_value);
  EXPECT_FLOAT_EQ(kValue1, statistic[1].ceil_value);
  EXPECT_FLOAT_EQ(kValue1, statistic[1].floor_value);

  aec3::UpdateDbMetric(value, &statistic);
  EXPECT_FLOAT_EQ(2.f * kValue0, statistic[0].sum_value);
  EXPECT_FLOAT_EQ(kValue0, statistic[0].ceil_value);
  EXPECT_FLOAT_EQ(kValue0, statistic[0].floor_value);
  EXPECT_FLOAT_EQ(2.f * kValue1, statistic[1].sum_value);
  EXPECT_FLOAT_EQ(kValue1, statistic[1].ceil_value);
  EXPECT_FLOAT_EQ(kValue1, statistic[1].floor_value);
}

// Verifies that the TransformDbMetricForReporting method produces the desired
// output for values for dBFS.
TEST(TransformDbMetricForReporting, DbFsScaling) {
  std::array<float, kBlockSize> x;
  FftData X;
  std::array<float, kFftLengthBy2Plus1> X2;
  Aec3Fft fft;
  x.fill(1000.f);
  fft.ZeroPaddedFft(x, &X);
  X.Spectrum(Aec3Optimization::kNone, &X2);

  float offset = -10.f * log10(32768.f * 32768.f);
  EXPECT_NEAR(offset, -90.3f, 0.1f);
  EXPECT_EQ(
      static_cast<int>(30.3f),
      aec3::TransformDbMetricForReporting(
          true, 0.f, 90.f, offset, 1.f / (kBlockSize * kBlockSize), X2[0]));
}

// Verifies that the TransformDbMetricForReporting method is able to properly
// limit the output.
TEST(TransformDbMetricForReporting, Limits) {
  EXPECT_EQ(
      0,
      aec3::TransformDbMetricForReporting(false, 0.f, 10.f, 0.f, 1.f, 0.001f));
  EXPECT_EQ(
      10,
      aec3::TransformDbMetricForReporting(false, 0.f, 10.f, 0.f, 1.f, 100.f));
}

// Verifies that the TransformDbMetricForReporting method is able to properly
// negate output.
TEST(TransformDbMetricForReporting, Negate) {
  EXPECT_EQ(
      10,
      aec3::TransformDbMetricForReporting(true, -20.f, 20.f, 0.f, 1.f, 0.1f));
  EXPECT_EQ(
      -10,
      aec3::TransformDbMetricForReporting(true, -20.f, 20.f, 0.f, 1.f, 10.f));
}

// Verify the Update functionality of DbMetric.
TEST(DbMetric, Update) {
  EchoRemoverMetrics::DbMetric metric(0.f, 20.f, -20.f);
  constexpr int kNumValues = 100;
  constexpr float kValue = 10.f;
  for (int k = 0; k < kNumValues; ++k) {
    metric.Update(kValue);
  }
  EXPECT_FLOAT_EQ(kValue * kNumValues, metric.sum_value);
  EXPECT_FLOAT_EQ(kValue, metric.ceil_value);
  EXPECT_FLOAT_EQ(kValue, metric.floor_value);
}

// Verify the constructor functionality of DbMetric.
TEST(DbMetric, Constructor) {
  EchoRemoverMetrics::DbMetric metric;
  EXPECT_FLOAT_EQ(0.f, metric.sum_value);
  EXPECT_FLOAT_EQ(0.f, metric.ceil_value);
  EXPECT_FLOAT_EQ(0.f, metric.floor_value);

  metric = EchoRemoverMetrics::DbMetric(1.f, 2.f, 3.f);
  EXPECT_FLOAT_EQ(1.f, metric.sum_value);
  EXPECT_FLOAT_EQ(2.f, metric.floor_value);
  EXPECT_FLOAT_EQ(3.f, metric.ceil_value);
}

// Verify the general functionality of EchoRemoverMetrics.
TEST(EchoRemoverMetrics, NormalUsage) {
  EchoRemoverMetrics metrics;
  AecState aec_state(AudioProcessing::Config::EchoCanceller3{});
  std::array<float, kFftLengthBy2Plus1> comfort_noise_spectrum;
  std::array<float, kFftLengthBy2Plus1> suppressor_gain;
  comfort_noise_spectrum.fill(10.f);
  suppressor_gain.fill(1.f);
  for (int j = 0; j < 3; ++j) {
    for (int k = 0; k < kMetricsReportingIntervalBlocks - 1; ++k) {
      metrics.Update(aec_state, comfort_noise_spectrum, suppressor_gain);
      EXPECT_FALSE(metrics.MetricsReported());
    }
    metrics.Update(aec_state, comfort_noise_spectrum, suppressor_gain);
    EXPECT_TRUE(metrics.MetricsReported());
  }
}

}  // namespace webrtc
