/*
 *  Copyright 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 <stdlib.h>
#include <array>
#include <climits>
#include <cstdint>
#include <random>

#include "absl/algorithm/container.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/numerics/percentile_filter.h"
#include "test/gtest.h"

namespace webrtc {

class PercentileFilterTest : public ::testing::TestWithParam<float> {
 public:
  PercentileFilterTest() : filter_(GetParam()) {
    // Make sure the tests are deterministic by seeding with a constant.
    srand(42);
  }

 protected:
  PercentileFilter<int64_t> filter_;

 private:
  RTC_DISALLOW_COPY_AND_ASSIGN(PercentileFilterTest);
};

INSTANTIATE_TEST_SUITE_P(PercentileFilterTests,
                         PercentileFilterTest,
                         ::testing::Values(0.0f, 0.1f, 0.5f, 0.9f, 1.0f));

TEST(PercentileFilterTest, MinFilter) {
  PercentileFilter<int64_t> filter(0.0f);
  filter.Insert(4);
  EXPECT_EQ(4, filter.GetPercentileValue());
  filter.Insert(3);
  EXPECT_EQ(3, filter.GetPercentileValue());
}

TEST(PercentileFilterTest, MaxFilter) {
  PercentileFilter<int64_t> filter(1.0f);
  filter.Insert(3);
  EXPECT_EQ(3, filter.GetPercentileValue());
  filter.Insert(4);
  EXPECT_EQ(4, filter.GetPercentileValue());
}

TEST(PercentileFilterTest, MedianFilterDouble) {
  PercentileFilter<double> filter(0.5f);
  filter.Insert(2.71828);
  filter.Insert(3.14159);
  filter.Insert(1.41421);
  EXPECT_EQ(2.71828, filter.GetPercentileValue());
}

TEST(PercentileFilterTest, MedianFilterInt) {
  PercentileFilter<int> filter(0.5f);
  filter.Insert(INT_MIN);
  filter.Insert(1);
  filter.Insert(2);
  EXPECT_EQ(1, filter.GetPercentileValue());
  filter.Insert(INT_MAX);
  filter.Erase(INT_MIN);
  EXPECT_EQ(2, filter.GetPercentileValue());
}

TEST(PercentileFilterTest, MedianFilterUnsigned) {
  PercentileFilter<unsigned> filter(0.5f);
  filter.Insert(UINT_MAX);
  filter.Insert(2u);
  filter.Insert(1u);
  EXPECT_EQ(2u, filter.GetPercentileValue());
  filter.Insert(0u);
  filter.Erase(UINT_MAX);
  EXPECT_EQ(1u, filter.GetPercentileValue());
}

TEST_P(PercentileFilterTest, EmptyFilter) {
  EXPECT_EQ(0, filter_.GetPercentileValue());
  filter_.Insert(3);
  bool success = filter_.Erase(3);
  EXPECT_TRUE(success);
  EXPECT_EQ(0, filter_.GetPercentileValue());
}

TEST_P(PercentileFilterTest, EraseNonExistingElement) {
  bool success = filter_.Erase(3);
  EXPECT_FALSE(success);
  EXPECT_EQ(0, filter_.GetPercentileValue());
  filter_.Insert(4);
  success = filter_.Erase(3);
  EXPECT_FALSE(success);
  EXPECT_EQ(4, filter_.GetPercentileValue());
}

TEST_P(PercentileFilterTest, DuplicateElements) {
  filter_.Insert(3);
  filter_.Insert(3);
  filter_.Erase(3);
  EXPECT_EQ(3, filter_.GetPercentileValue());
}

TEST_P(PercentileFilterTest, InsertAndEraseTenValuesInRandomOrder) {
  std::array<int64_t, 10> zero_to_nine = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
  // The percentile value of the ten values above.
  const int64_t expected_value = static_cast<int64_t>(GetParam() * 9);

  // Insert two sets of |zero_to_nine| in random order.
  for (int i = 0; i < 2; ++i) {
    absl::c_shuffle(zero_to_nine, std::mt19937(std::random_device()()));
    for (int64_t value : zero_to_nine)
      filter_.Insert(value);
    // After inserting a full set of |zero_to_nine|, the percentile should
    // stay constant.
    EXPECT_EQ(expected_value, filter_.GetPercentileValue());
  }

  // Insert and erase sets of |zero_to_nine| in random order a few times.
  for (int i = 0; i < 3; ++i) {
    absl::c_shuffle(zero_to_nine, std::mt19937(std::random_device()()));
    for (int64_t value : zero_to_nine)
      filter_.Erase(value);
    EXPECT_EQ(expected_value, filter_.GetPercentileValue());
    absl::c_shuffle(zero_to_nine, std::mt19937(std::random_device()()));
    for (int64_t value : zero_to_nine)
      filter_.Insert(value);
    EXPECT_EQ(expected_value, filter_.GetPercentileValue());
  }
}

}  // namespace webrtc
