// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/lib/crypto_util/random.h"

#include <bitset>
#include <cmath>
#include <memory>
#include <utility>
#include <vector>

#include <gtest/gtest.h>

#include "src/lib/crypto_util/random_test_utils.h"

namespace cobalt::crypto {

// Returns the number of bits of the size bytes in x that are set to one.
int NumBitsSet(byte* x, std::size_t size) {
  int count = 0;
  for (std::size_t i = 0; i < size; i++) {
    std::bitset<8> bit_set(x[i]);
    count += bit_set.count();
  }
  return count;
}

// Performs the experiment of invoking RandomBits(p, 10) 100 times and
// returns the average number of bits set per byte.
// Uses DeterministicRandom in order to ensure reproducibility.
float AverageNumBitsSet(float p) {
  std::unique_ptr<Random> rand(new DeterministicRandom());
  int cumulative_num_bits_set = 0;
  std::size_t size = 10;
  auto random_bits = std::make_unique<byte[]>(size);
  for (int i = 0; i < 100; i++) {
    rand->RandomBits(p, random_bits.get(), size);
    cumulative_num_bits_set += NumBitsSet(random_bits.get(), size);
  }
  return static_cast<float>(cumulative_num_bits_set) / 1000.0f;
}

// Invokes RandomBits(p, 10) 1000 times, collects the sum of the values for
// each of the 8 bits per byte separately, and then performs Pearson's
// chi-squared test on each bit separately to check for goodness of fit to a
// binomial distribution with parameter p. Fails if chi-squared >= 5.024 which
// corresponds to rejecting the null hypothesis with confidence 0.975.
// Uses DeterministicRandom in order to ensure reproducibility.
void DoChiSquaredTest(float p) {
  // Do the experiment and collect the counts.
  std::unique_ptr<Random> rand(new DeterministicRandom());
  std::vector<unsigned int> counts(8, 0);
  std::size_t size = 10;
  static const int kNumTrials = 1000;
  auto random_bits = std::make_unique<byte[]>(size);
  for (int i = 0; i < kNumTrials; i++) {
    rand->RandomBits(p, random_bits.get(), size);
    for (std::size_t b = 0; b < size; b++) {
      std::bitset<8> bit_set(random_bits[b]);
      for (size_t j = 0; j < 8; j++) {
        counts[j] += bit_set[j];
      }
    }
  }

  // Check the errors.
  const double expected_1 = static_cast<double>(kNumTrials * size) * p;
  const double expected_0 = static_cast<double>(kNumTrials * size) - expected_1;
  for (size_t j = 0; j < 8; j++) {
    // Difference between actual 1 count and expected 1 count.
    double delta_1 = static_cast<double>(counts[j]) - expected_1;

    // Difference between actual 0 count and expected 0 count.
    double delta_0 = static_cast<double>(kNumTrials * size - counts[j]) - expected_0;

    // Compute and check the Chi-Squared value.
    double chi_squared = delta_1 * delta_1 / expected_1 + delta_0 * delta_0 / expected_0;

    // The number 5.024 below has the property that
    // P(X < 5.024) = 0.975 where X ~ chi^2(1)
    EXPECT_TRUE(chi_squared < 5.024);
  }
}

// Tests the function RandomBits()
TEST(RandomTest, TestRandomBitsExtremeValues) {
  std::unique_ptr<Random> rand(new Random());
  std::size_t size = 100;

  // When p = 0 none of the bits should be set.
  auto buffer = std::make_unique<byte[]>(size);
  rand->RandomBits(0.0, buffer.get(), size);
  for (std::size_t i = 0; i < size; i++) {
    EXPECT_EQ(0, buffer[i]);
  }

  // When p = 1 all of the bits should be set.
  rand->RandomBits(1.0, buffer.get(), size);
  for (std::size_t i = 0; i < size; i++) {
    EXPECT_EQ(0xFF, buffer[i]);
  }
}

TEST(RandomTest, TestRandomBitsStatisticalTests) {
  // We use DeterministicRandom so that the test is not flaky.

  // When p = i/8 then on average i of the bits should be set.
  for (int i = 1; i <= 7; i++) {
    auto p = static_cast<float>(i / 8.0);
    EXPECT_NEAR(i, AverageNumBitsSet(p), 2 * p);
  }

  // Pick some other values for p and both test the average number of bits
  // set and also perform a Chi-squared test.
  static const float ps[] = {0.01f, 0.1f, 0.2f,  0.25f, 0.3f, 0.4f,  0.5f,
                             0.6f,  0.7f, 0.75f, 0.8f,  0.9f, 0.95f, 0.99f};
  for (auto p : ps) {
    EXPECT_NEAR(8.0 * p, AverageNumBitsSet(p), 2 * p);

    DoChiSquaredTest(p);
  }
}

}  // namespace cobalt::crypto
