// Copyright 2017 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/random/zipf_distribution.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <random>
#include <string>
#include <utility>
#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/random/internal/chi_square.h"
#include "absl/random/internal/pcg_engine.h"
#include "absl/random/internal/sequence_urbg.h"
#include "absl/random/random.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/strip.h"

namespace {

using ::absl::random_internal::kChiSquared;
using ::testing::ElementsAre;

template <typename IntType>
class ZipfDistributionTypedTest : public ::testing::Test {};

using IntTypes = ::testing::Types<int, int8_t, int16_t, int32_t, int64_t,
                                  uint8_t, uint16_t, uint32_t, uint64_t>;
TYPED_TEST_CASE(ZipfDistributionTypedTest, IntTypes);

TYPED_TEST(ZipfDistributionTypedTest, SerializeTest) {
  using param_type = typename absl::zipf_distribution<TypeParam>::param_type;

  constexpr int kCount = 1000;
  absl::InsecureBitGen gen;
  for (const auto& param : {
           param_type(),
           param_type(32),
           param_type(100, 3, 2),
           param_type(std::numeric_limits<TypeParam>::max(), 4, 3),
           param_type(std::numeric_limits<TypeParam>::max() / 2),
       }) {
    // Validate parameters.
    const auto k = param.k();
    const auto q = param.q();
    const auto v = param.v();

    absl::zipf_distribution<TypeParam> before(k, q, v);
    EXPECT_EQ(before.k(), param.k());
    EXPECT_EQ(before.q(), param.q());
    EXPECT_EQ(before.v(), param.v());

    {
      absl::zipf_distribution<TypeParam> via_param(param);
      EXPECT_EQ(via_param, before);
    }

    // Validate stream serialization.
    std::stringstream ss;
    ss << before;
    absl::zipf_distribution<TypeParam> after(4, 5.5, 4.4);

    EXPECT_NE(before.k(), after.k());
    EXPECT_NE(before.q(), after.q());
    EXPECT_NE(before.v(), after.v());
    EXPECT_NE(before.param(), after.param());
    EXPECT_NE(before, after);

    ss >> after;

    EXPECT_EQ(before.k(), after.k());
    EXPECT_EQ(before.q(), after.q());
    EXPECT_EQ(before.v(), after.v());
    EXPECT_EQ(before.param(), after.param());
    EXPECT_EQ(before, after);

    // Smoke test.
    auto sample_min = after.max();
    auto sample_max = after.min();
    for (int i = 0; i < kCount; i++) {
      auto sample = after(gen);
      EXPECT_GE(sample, after.min());
      EXPECT_LE(sample, after.max());
      if (sample > sample_max) sample_max = sample;
      if (sample < sample_min) sample_min = sample;
    }
    ABSL_INTERNAL_LOG(INFO,
                      absl::StrCat("Range: ", +sample_min, ", ", +sample_max));
  }
}

class ZipfModel {
 public:
  ZipfModel(size_t k, double q, double v) : k_(k), q_(q), v_(v) {}

  double mean() const { return mean_; }

  // For the other moments of the Zipf distribution, see, for example,
  // http://mathworld.wolfram.com/ZipfDistribution.html

  // PMF(k) = (1 / k^s) / H(N,s)
  // Returns the probability that any single invocation returns k.
  double PMF(size_t i) { return i >= hnq_.size() ? 0.0 : hnq_[i] / sum_hnq_; }

  // CDF = H(k, s) / H(N,s)
  double CDF(size_t i) {
    if (i >= hnq_.size()) {
      return 1.0;
    }
    auto it = std::begin(hnq_);
    double h = 0.0;
    for (const auto end = it; it != end; it++) {
      h += *it;
    }
    return h / sum_hnq_;
  }

  // The InverseCDF returns the k values which bound p on the upper and lower
  // bound. Since there is no closed-form solution, this is implemented as a
  // bisction of the cdf.
  std::pair<size_t, size_t> InverseCDF(double p) {
    size_t min = 0;
    size_t max = hnq_.size();
    while (max > min + 1) {
      size_t target = (max + min) >> 1;
      double x = CDF(target);
      if (x > p) {
        max = target;
      } else {
        min = target;
      }
    }
    return {min, max};
  }

  // Compute the probability totals, which are based on the generalized harmonic
  // number, H(N,s).
  //   H(N,s) == SUM(k=1..N, 1 / k^s)
  //
  // In the limit, H(N,s) == zetac(s) + 1.
  //
  // NOTE: The mean of a zipf distribution could be computed here as well.
  // Mean :=  H(N, s-1) / H(N,s).
  // Given the parameter v = 1, this gives the following function:
  // (Hn(100, 1) - Hn(1,1)) / (Hn(100,2) - Hn(1,2)) = 6.5944
  //
  void Init() {
    if (!hnq_.empty()) {
      return;
    }
    hnq_.clear();
    hnq_.reserve(std::min(k_, size_t{1000}));

    sum_hnq_ = 0;
    double qm1 = q_ - 1.0;
    double sum_hnq_m1 = 0;
    for (size_t i = 0; i < k_; i++) {
      // Partial n-th generalized harmonic number
      const double x = v_ + i;

      // H(n, q-1)
      const double hnqm1 =
          (q_ == 2.0) ? (1.0 / x)
                      : (q_ == 3.0) ? (1.0 / (x * x)) : std::pow(x, -qm1);
      sum_hnq_m1 += hnqm1;

      // H(n, q)
      const double hnq =
          (q_ == 2.0) ? (1.0 / (x * x))
                      : (q_ == 3.0) ? (1.0 / (x * x * x)) : std::pow(x, -q_);
      sum_hnq_ += hnq;
      hnq_.push_back(hnq);
      if (i > 1000 && hnq <= 1e-10) {
        // The harmonic number is too small.
        break;
      }
    }
    assert(sum_hnq_ > 0);
    mean_ = sum_hnq_m1 / sum_hnq_;
  }

 private:
  const size_t k_;
  const double q_;
  const double v_;

  double mean_;
  std::vector<double> hnq_;
  double sum_hnq_;
};

using zipf_u64 = absl::zipf_distribution<uint64_t>;

class ZipfTest : public testing::TestWithParam<zipf_u64::param_type>,
                 public ZipfModel {
 public:
  ZipfTest() : ZipfModel(GetParam().k(), GetParam().q(), GetParam().v()) {}

  // We use a fixed bit generator for distribution accuracy tests.  This allows
  // these tests to be deterministic, while still testing the qualify of the
  // implementation.
  absl::random_internal::pcg64_2018_engine rng_{0x2B7E151628AED2A6};
};

TEST_P(ZipfTest, ChiSquaredTest) {
  const auto& param = GetParam();
  Init();

  size_t trials = 10000;

  // Find the split-points for the buckets.
  std::vector<size_t> points;
  std::vector<double> expected;
  {
    double last_cdf = 0.0;
    double min_p = 1.0;
    for (double p = 0.01; p < 1.0; p += 0.01) {
      auto x = InverseCDF(p);
      if (points.empty() || points.back() < x.second) {
        const double p = CDF(x.second);
        points.push_back(x.second);
        double q = p - last_cdf;
        expected.push_back(q);
        last_cdf = p;
        if (q < min_p) {
          min_p = q;
        }
      }
    }
    if (last_cdf < 0.999) {
      points.push_back(std::numeric_limits<size_t>::max());
      double q = 1.0 - last_cdf;
      expected.push_back(q);
      if (q < min_p) {
        min_p = q;
      }
    } else {
      points.back() = std::numeric_limits<size_t>::max();
      expected.back() += (1.0 - last_cdf);
    }
    // The Chi-Squared score is not completely scale-invariant; it works best
    // when the small values are in the small digits.
    trials = static_cast<size_t>(8.0 / min_p);
  }
  ASSERT_GT(points.size(), 0);

  // Generate n variates and fill the counts vector with the count of their
  // occurrences.
  std::vector<int64_t> buckets(points.size(), 0);
  double avg = 0;
  {
    zipf_u64 dis(param);
    for (size_t i = 0; i < trials; i++) {
      uint64_t x = dis(rng_);
      ASSERT_LE(x, dis.max());
      ASSERT_GE(x, dis.min());
      avg += static_cast<double>(x);
      auto it = std::upper_bound(std::begin(points), std::end(points),
                                 static_cast<size_t>(x));
      buckets[std::distance(std::begin(points), it)]++;
    }
    avg = avg / static_cast<double>(trials);
  }

  // Validate the output using the Chi-Squared test.
  for (auto& e : expected) {
    e *= trials;
  }

  // The null-hypothesis is that the distribution is a poisson distribution with
  // the provided mean (not estimated from the data).
  const int dof = static_cast<int>(expected.size()) - 1;

  // NOTE: This test runs about 15x per invocation, so a value of 0.9995 is
  // approximately correct for a test suite failure rate of 1 in 100.  In
  // practice we see failures slightly higher than that.
  const double threshold = absl::random_internal::ChiSquareValue(dof, 0.9999);

  const double chi_square = absl::random_internal::ChiSquare(
      std::begin(buckets), std::end(buckets), std::begin(expected),
      std::end(expected));

  const double p_actual =
      absl::random_internal::ChiSquarePValue(chi_square, dof);

  // Log if the chi_squared value is above the threshold.
  if (chi_square > threshold) {
    ABSL_INTERNAL_LOG(INFO, "values");
    for (size_t i = 0; i < expected.size(); i++) {
      ABSL_INTERNAL_LOG(INFO, absl::StrCat(points[i], ": ", buckets[i],
                                           " vs. E=", expected[i]));
    }
    ABSL_INTERNAL_LOG(INFO, absl::StrCat("trials ", trials));
    ABSL_INTERNAL_LOG(INFO,
                      absl::StrCat("mean ", avg, " vs. expected ", mean()));
    ABSL_INTERNAL_LOG(INFO, absl::StrCat(kChiSquared, "(data, ", dof, ") = ",
                                         chi_square, " (", p_actual, ")"));
    ABSL_INTERNAL_LOG(INFO,
                      absl::StrCat(kChiSquared, " @ 0.9995 = ", threshold));
    FAIL() << kChiSquared << " value of " << chi_square
           << " is above the threshold.";
  }
}

std::vector<zipf_u64::param_type> GenParams() {
  using param = zipf_u64::param_type;
  const auto k = param().k();
  const auto q = param().q();
  const auto v = param().v();
  const uint64_t k2 = 1 << 10;
  return std::vector<zipf_u64::param_type>{
      // Default
      param(k, q, v),
      // vary K
      param(4, q, v), param(1 << 4, q, v), param(k2, q, v),
      // vary V
      param(k2, q, 0.5), param(k2, q, 1.5), param(k2, q, 2.5), param(k2, q, 10),
      // vary Q
      param(k2, 1.5, v), param(k2, 3, v), param(k2, 5, v), param(k2, 10, v),
      // Vary V & Q
      param(k2, 1.5, 0.5), param(k2, 3, 1.5), param(k, 10, 10)};
}

std::string ParamName(
    const ::testing::TestParamInfo<zipf_u64::param_type>& info) {
  const auto& p = info.param;
  std::string name = absl::StrCat("k_", p.k(), "__q_", absl::SixDigits(p.q()),
                                  "__v_", absl::SixDigits(p.v()));
  return absl::StrReplaceAll(name, {{"+", "_"}, {"-", "_"}, {".", "_"}});
}

INSTANTIATE_TEST_SUITE_P(All, ZipfTest, ::testing::ValuesIn(GenParams()),
                         ParamName);

// NOTE: absl::zipf_distribution is not guaranteed to be stable.
TEST(ZipfDistributionTest, StabilityTest) {
  // absl::zipf_distribution stability relies on
  // absl::uniform_real_distribution, std::log, std::exp, std::log1p
  absl::random_internal::sequence_urbg urbg(
      {0x0003eb76f6f7f755ull, 0xFFCEA50FDB2F953Bull, 0xC332DDEFBE6C5AA5ull,
       0x6558218568AB9702ull, 0x2AEF7DAD5B6E2F84ull, 0x1521B62829076170ull,
       0xECDD4775619F1510ull, 0x13CCA830EB61BD96ull, 0x0334FE1EAA0363CFull,
       0xB5735C904C70A239ull, 0xD59E9E0BCBAADE14ull, 0xEECC86BC60622CA7ull});

  std::vector<int> output(10);

  {
    absl::zipf_distribution<int32_t> dist;
    std::generate(std::begin(output), std::end(output),
                  [&] { return dist(urbg); });
    EXPECT_THAT(output, ElementsAre(10031, 0, 0, 3, 6, 0, 7, 47, 0, 0));
  }
  urbg.reset();
  {
    absl::zipf_distribution<int32_t> dist(std::numeric_limits<int32_t>::max(),
                                          3.3);
    std::generate(std::begin(output), std::end(output),
                  [&] { return dist(urbg); });
    EXPECT_THAT(output, ElementsAre(44, 0, 0, 0, 0, 1, 0, 1, 3, 0));
  }
}

TEST(ZipfDistributionTest, AlgorithmBounds) {
  absl::zipf_distribution<int32_t> dist;

  // Small values from absl::uniform_real_distribution map to larger Zipf
  // distribution values.
  const std::pair<uint64_t, int32_t> kInputs[] = {
      {0xffffffffffffffff, 0x0}, {0x7fffffffffffffff, 0x0},
      {0x3ffffffffffffffb, 0x1}, {0x1ffffffffffffffd, 0x4},
      {0xffffffffffffffe, 0x9},  {0x7ffffffffffffff, 0x12},
      {0x3ffffffffffffff, 0x25}, {0x1ffffffffffffff, 0x4c},
      {0xffffffffffffff, 0x99},  {0x7fffffffffffff, 0x132},
      {0x3fffffffffffff, 0x265}, {0x1fffffffffffff, 0x4cc},
      {0xfffffffffffff, 0x999},  {0x7ffffffffffff, 0x1332},
      {0x3ffffffffffff, 0x2665}, {0x1ffffffffffff, 0x4ccc},
      {0xffffffffffff, 0x9998},  {0x7fffffffffff, 0x1332f},
      {0x3fffffffffff, 0x2665a}, {0x1fffffffffff, 0x4cc9e},
      {0xfffffffffff, 0x998e0},  {0x7ffffffffff, 0x133051},
      {0x3ffffffffff, 0x265ae4}, {0x1ffffffffff, 0x4c9ed3},
      {0xffffffffff, 0x98e223},  {0x7fffffffff, 0x13058c4},
      {0x3fffffffff, 0x25b178e}, {0x1fffffffff, 0x4a062b2},
      {0xfffffffff, 0x8ee23b8},  {0x7ffffffff, 0x10b21642},
      {0x3ffffffff, 0x1d89d89d}, {0x1ffffffff, 0x2fffffff},
      {0xffffffff, 0x45d1745d},  {0x7fffffff, 0x5a5a5a5a},
      {0x3fffffff, 0x69ee5846},  {0x1fffffff, 0x73ecade3},
      {0xfffffff, 0x79a9d260},   {0x7ffffff, 0x7cc0532b},
      {0x3ffffff, 0x7e5ad146},   {0x1ffffff, 0x7f2c0bec},
      {0xffffff, 0x7f95adef},    {0x7fffff, 0x7fcac0da},
      {0x3fffff, 0x7fe55ae2},    {0x1fffff, 0x7ff2ac0e},
      {0xfffff, 0x7ff955ae},     {0x7ffff, 0x7ffcaac1},
      {0x3ffff, 0x7ffe555b},     {0x1ffff, 0x7fff2aac},
      {0xffff, 0x7fff9556},      {0x7fff, 0x7fffcaab},
      {0x3fff, 0x7fffe555},      {0x1fff, 0x7ffff2ab},
      {0xfff, 0x7ffff955},       {0x7ff, 0x7ffffcab},
      {0x3ff, 0x7ffffe55},       {0x1ff, 0x7fffff2b},
      {0xff, 0x7fffff95},        {0x7f, 0x7fffffcb},
      {0x3f, 0x7fffffe5},        {0x1f, 0x7ffffff3},
      {0xf, 0x7ffffff9},         {0x7, 0x7ffffffd},
      {0x3, 0x7ffffffe},         {0x1, 0x7fffffff},
  };

  for (const auto& instance : kInputs) {
    absl::random_internal::sequence_urbg urbg({instance.first});
    EXPECT_EQ(instance.second, dist(urbg));
  }
}

}  // namespace
