/*
 *  Copyright (c) 2016 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 <cmath>
#include <memory>

#include "common_audio/smoothing_filter.h"
#include "rtc_base/fake_clock.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

constexpr float kMaxAbsError = 1e-5f;
constexpr int64_t kClockInitialTime = 123456;

struct SmoothingFilterStates {
  explicit SmoothingFilterStates(int init_time_ms)
      : smoothing_filter(init_time_ms) {
    fake_clock.AdvanceTime(TimeDelta::ms(kClockInitialTime));
  }
  rtc::ScopedFakeClock fake_clock;
  SmoothingFilterImpl smoothing_filter;
};

// This function does the following:
//   1. Add a sample to filter at current clock,
//   2. Advance the clock by |advance_time_ms|,
//   3. Get the output of both SmoothingFilter and verify that it equals to an
//      expected value.
void CheckOutput(SmoothingFilterStates* states,
                 float sample,
                 int advance_time_ms,
                 float expected_ouput) {
  states->smoothing_filter.AddSample(sample);
  states->fake_clock.AdvanceTime(TimeDelta::ms(advance_time_ms));
  auto output = states->smoothing_filter.GetAverage();
  EXPECT_TRUE(output);
  EXPECT_NEAR(expected_ouput, *output, kMaxAbsError);
}

}  // namespace

TEST(SmoothingFilterTest, NoOutputWhenNoSampleAdded) {
  constexpr int kInitTimeMs = 100;
  SmoothingFilterStates states(kInitTimeMs);
  EXPECT_FALSE(states.smoothing_filter.GetAverage());
}

// Python script to calculate the reference values used in this test.
//   import math
//
//   class ExpFilter:
//     def add_sample(self, new_value):
//       self.state = self.state * self.alpha + (1.0 - self.alpha) * new_value
//
//   filter = ExpFilter()
//   init_time = 795
//   init_factor = (1.0 / init_time) ** (1.0 / init_time)
//
//   filter.state = 1.0
//
//   for time_now in range(1, 500):
//     filter.alpha = math.exp(-init_factor ** time_now)
//     filter.add_sample(1.0)
//   print filter.state
//
//   for time_now in range(500, 600):
//     filter.alpha = math.exp(-init_factor ** time_now)
//     filter.add_sample(0.5)
//   print filter.state
//
//   for time_now in range(600, 700):
//     filter.alpha = math.exp(-init_factor ** time_now)
//     filter.add_sample(1.0)
//   print filter.state
//
//   for time_now in range(700, init_time):
//     filter.alpha = math.exp(-init_factor ** time_now)
//     filter.add_sample(1.0)
//
//   filter.alpha = math.exp(-1.0 / init_time)
//   for time_now in range(init_time, 800):
//     filter.add_sample(1.0)
//   print filter.state
//
//   for i in range(800, 900):
//     filter.add_sample(0.5)
//   print filter.state
//
//   for i in range(900, 1000):
//     filter.add_sample(1.0)
//   print filter.state
TEST(SmoothingFilterTest, CheckBehaviorAroundInitTime) {
  constexpr int kInitTimeMs = 795;
  SmoothingFilterStates states(kInitTimeMs);
  CheckOutput(&states, 1.0f, 500, 1.0f);
  CheckOutput(&states, 0.5f, 100, 0.680562264029f);
  CheckOutput(&states, 1.0f, 100, 0.794207139813f);
  // Next step will go across initialization time.
  CheckOutput(&states, 1.0f, 100, 0.829803409752f);
  CheckOutput(&states, 0.5f, 100, 0.790821764210f);
  CheckOutput(&states, 1.0f, 100, 0.815545922911f);
}

TEST(SmoothingFilterTest, InitTimeEqualsZero) {
  constexpr int kInitTimeMs = 0;
  SmoothingFilterStates states(kInitTimeMs);
  CheckOutput(&states, 1.0f, 1, 1.0f);
  CheckOutput(&states, 0.5f, 1, 0.5f);
}

TEST(SmoothingFilterTest, InitTimeEqualsOne) {
  constexpr int kInitTimeMs = 1;
  SmoothingFilterStates states(kInitTimeMs);
  CheckOutput(&states, 1.0f, 1, 1.0f);
  CheckOutput(&states, 0.5f, 1, 1.0f * exp(-1.0f) + (1.0f - exp(-1.0f)) * 0.5f);
}

TEST(SmoothingFilterTest, GetAverageOutputsEmptyBeforeFirstSample) {
  constexpr int kInitTimeMs = 100;
  SmoothingFilterStates states(kInitTimeMs);
  EXPECT_FALSE(states.smoothing_filter.GetAverage());
  constexpr float kFirstSample = 1.2345f;
  states.smoothing_filter.AddSample(kFirstSample);
  EXPECT_EQ(kFirstSample, states.smoothing_filter.GetAverage());
}

TEST(SmoothingFilterTest, CannotChangeTimeConstantDuringInitialization) {
  constexpr int kInitTimeMs = 100;
  SmoothingFilterStates states(kInitTimeMs);
  states.smoothing_filter.AddSample(0.0);

  // During initialization, |SetTimeConstantMs| does not take effect.
  states.fake_clock.AdvanceTime(TimeDelta::ms(kInitTimeMs - 1));
  states.smoothing_filter.AddSample(0.0);

  EXPECT_FALSE(states.smoothing_filter.SetTimeConstantMs(kInitTimeMs * 2));
  EXPECT_NE(exp(-1.0f / (kInitTimeMs * 2)), states.smoothing_filter.alpha());

  states.fake_clock.AdvanceTime(TimeDelta::ms(1));
  states.smoothing_filter.AddSample(0.0);
  // When initialization finishes, the time constant should be come
  // |kInitTimeConstantMs|.
  EXPECT_FLOAT_EQ(exp(-1.0f / kInitTimeMs), states.smoothing_filter.alpha());

  // After initialization, |SetTimeConstantMs| takes effect.
  EXPECT_TRUE(states.smoothing_filter.SetTimeConstantMs(kInitTimeMs * 2));
  EXPECT_FLOAT_EQ(exp(-1.0f / (kInitTimeMs * 2)),
                  states.smoothing_filter.alpha());
}

}  // namespace webrtc
