/*
 *  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 "webrtc/base/fakeclock.h"
#include "webrtc/common_audio/smoothing_filter.h"
#include "webrtc/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(rtc::TimeDelta::FromMilliseconds(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(
      rtc::TimeDelta::FromMilliseconds(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(rtc::Optional<float>(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(
      rtc::TimeDelta::FromMilliseconds(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(rtc::TimeDelta::FromMilliseconds(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
