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

#include <math.h>

#include "modules/audio_processing/aec3/aec_state.h"
#include "modules/audio_processing/aec3/aec3_fft.h"
#include "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(EchoCanceller3Config{});
  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
