// Copyright 2016 The Fuchsia 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
//
//    http://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 "algorithms/rappor/basic_rappor_analyzer.h"

#include <gflags/gflags.h>
#include <glog/logging.h>

#include <algorithm>
#include <cmath>
#include <string>
#include <utility>
#include <vector>

#include "algorithms/rappor/rappor_encoder.h"
#include "algorithms/rappor/rappor_test_utils.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"
#include "util/crypto_util/random_test_utils.h"

namespace cobalt {
namespace rappor {

using encoder::ClientSecret;

namespace {

// Given a string of "0"s and "1"s of length a multiple of 8, returns
// a BasicRapporObservation whose data is equal to the bytes whose binary
// representation is given by the string.
BasicRapporObservation BasicRapporObservationFromString(
    const std::string& binary_string) {
  BasicRapporObservation obs;
  obs.set_data(BinaryStringToData(binary_string));
  return obs;
}

// Makes a BasicRapporConfig with the given data.
BasicRapporConfig Config(int num_categories, double p, double q) {
  BasicRapporConfig config;
  config.set_prob_0_becomes_1(p);
  config.set_prob_1_stays_1(q);
  for (int i = 0; i < num_categories; i++) {
    config.mutable_string_categories()->add_category(CategoryName(i));
  }
  return config;
}

}  // namespace

class BasicRapporAnalyzerTest : public ::testing::Test {
 protected:
  // Sets the member variable analyzer_ to a new BasicRapporAnalyzer configured
  // to use |num_categories| categories and the current values of
  // prob_0_becomes_1_, prob_1_stays_1_.
  void SetAnalyzer(int num_categories) {
    analyzer_.reset(new BasicRapporAnalyzer(
        Config(num_categories, prob_0_becomes_1_, prob_1_stays_1_)));
    add_good_observation_call_count_ = 0;
    add_bad_observation_call_count_ = 0;
  }

  // Sets the member variable encoder_ to be a new BasicRapporEncoder configured
  // to use |num_categories| categories and the current values of
  // prob_0_becomes_1_, prob_1_stays_1_, a deterministic RNG.
  void SetEncoder(int num_categories) {
    encoder_.reset(new BasicRapporEncoder(
        Config(num_categories, prob_0_becomes_1_, prob_1_stays_1_),
        ClientSecret::GenerateNewSecret()));
    encoder_->SetRandomForTesting(
        std::unique_ptr<crypto::Random>(new crypto::DeterministicRandom()));
  }

  // Uses |encoder_| to encode |num_observations| observations for the given
  // |category| and adds each of the observations to |analyzer_|.
  void EncodeAndAdd(int category, int num_observations) {
    BasicRapporObservation obs;
    ValuePart value;
    value.set_string_value(CategoryName(category));
    for (int i = 0; i < num_observations; i++) {
      EXPECT_EQ(kOK, encoder_->Encode(value, &obs));
      EXPECT_TRUE(analyzer_->AddObservation(obs));
    }
  }

  // Adds an observation to analyzer_ described by |binary_string|. Expects
  // the operation to result in an error.
  void AddObservationExpectFalse(std::string binary_string) {
    EXPECT_FALSE(analyzer_->AddObservation(
        BasicRapporObservationFromString(binary_string)));
    CheckState(add_good_observation_call_count_,
               ++add_bad_observation_call_count_);
  }

  // Adds an observation to analyzer_ described by |binary_string|. Expects
  // the operation to succeed.
  void AddObservation(std::string binary_string) {
    EXPECT_TRUE(analyzer_->AddObservation(
        BasicRapporObservationFromString(binary_string)));
    CheckState(++add_good_observation_call_count_,
               add_bad_observation_call_count_);
  }

  // Invokes AddObservation() many times.
  void AddObservations(std::string binary_string, int num_times) {
    for (int count = 0; count < num_times; count++) {
      SCOPED_TRACE(std::string("count=") + std::to_string(count));
      AddObservation(binary_string);
    }
  }

  // Checks that analyzer_ has the expected number observations and errors.
  void CheckState(size_t expected_num_observations,
                  size_t expected_observation_errors) {
    EXPECT_EQ(expected_num_observations, analyzer_->num_observations());
    EXPECT_EQ(expected_observation_errors, analyzer_->observation_errors());
  }

  // Checks that analyzer_ has the expected raw count.
  void ExpectRawCount(size_t index, size_t expected_count) {
    EXPECT_EQ(expected_count, analyzer_->raw_category_counts()[index]);
  }

  // Checks that analyzer_ has the expected raw counts.
  void ExpectRawCounts(std::vector<size_t> expected_counts) {
    EXPECT_EQ(expected_counts, analyzer_->raw_category_counts());
  }

  // Invokes analyzer_->Analyze() and checks the count and std_error in
  // the given position.
  void AnalyzeAndCheckOnePosition(int position, double expected_estimate,
                                  double expected_std_err) {
    auto results = analyzer_->Analyze();
    EXPECT_FLOAT_EQ(expected_estimate, results[position].count_estimate)
        << "position=" << position;
    EXPECT_FLOAT_EQ(expected_std_err, results[position].std_error)
        << "position=" << position;
  }

  // Tests basic RAPPOR focusing on only a single bit at a time. No encoder
  // is used. Instead we directly construct observations to give to the
  // Analyzer.
  //
  // We use Basic RAPPOR with 24 bits but each time the test runs we single out
  // one |bit_index| to use. Only that |bit_index| receives any non-zero
  // observation data and only that |bit_index| is validated.
  //
  // Uses the currently set values for prob_0_becomes_1_ and prob_1_stays_1_.
  // There will be |n| total observations with |y| 1's and |n-y| 0's.
  void OneBitTest(int n, int y, double expected_estimate,
                  double expected_std_err) {
    // We pick five different bits out of the 24 bits to test.
    for (int bit_index : {0, 1, 8, 15, 23}) {
      SCOPED_TRACE(std::to_string(bit_index) + ", " + std::to_string(n) + ", " +
                   std::to_string(y));
      // Construct an analyzer for 24 bit Basic RAPPOR.
      SetAnalyzer(24);
      // Add y observations with a 1 in position |bit_index|.
      AddObservations(BuildBitPatternString(24, bit_index, '1', '0'), y);
      // Add n-y observations with a 0 in position |bit_index|.
      AddObservations(BuildBitPatternString(24, bit_index, '0', '0'), n - y);
      // Analyze and check position |bit_index|
      AnalyzeAndCheckOnePosition(bit_index, expected_estimate,
                                 expected_std_err);
    }
  }

  // We run basic RAPPOR with two categories using encoder_ and analyzer_.
  // We focus only on the results for category 0.
  //
  // We encode and add |y| observations for category 0 and |n-y| observations
  // for category 1. The parameters named "accumulated_*" are used to accumulate
  // sums of the results of invoking this method multiple times. This method
  // should be invoked multiple times with the same parameters.
  //
  // |accumulated_count_estimate| accumulates the sum of the count_estimates for
  // category 0.
  //
  // |accumulated_std_err_estimate| accumulates the sum of the std_errors for
  // category 0.
  //
  // |accumulated_actual_square_error| accumulates the sum of the squares of
  // the differences between the count_estimates, clipped to the feasible
  // region of [0, n], and the actual count,
  // y.
  void OneCategoryExperiment(int n, int y, double* accumulated_count_estimate,
                             double* accumulated_std_err_estimate,
                             double* accumulated_actual_square_error) {
    // Construct a fresh analyzer with 2 categories.
    SetAnalyzer(2);

    // Add y encoded observations with a true 1 for category 0.
    EncodeAndAdd(0, y);
    // Add n - y  encoded observations with a true 0 for category 0.
    EncodeAndAdd(1, n - y);

    // Analyze
    auto results = analyzer_->Analyze();

    (*accumulated_count_estimate) += results[0].count_estimate;
    (*accumulated_std_err_estimate) += results[0].std_error;
    double clipped_count_estimate =
        std::max(0.0, std::min(n * 1.0, results[0].count_estimate));
    double actual_error = (clipped_count_estimate - y);
    (*accumulated_actual_square_error) += actual_error * actual_error;
  }

  // Performs the OneCategoryExperiment 100 times and then checks that
  // (1) The average count_estimate is close to the true count, and
  // (2) The observed standard deviation is close to the std_error estimate.
  // p = the probability that a 0 is flipped to a 1
  // q = 1 minus the probability that a 1 is flipped to a 0.
  // n = number of observations
  // y = number of true 1's
  void OneCategoryTest(double p, double q, int n, int y) {
    // Set p and q.
    prob_0_becomes_1_ = p;
    prob_1_stays_1_ = q;
    SetEncoder(2);

    double accumulated_count_estimate = 0.0;
    double accumulated_std_err_estimate = 0.0;
    double accumulated_actual_square_error = 0.0;

    // Repeat the experiment 100 times.
    static const int kNumTrials = 100;

    for (int trial = 0; trial < kNumTrials; trial++) {
      OneCategoryExperiment(n, y, &accumulated_count_estimate,
                            &accumulated_std_err_estimate,
                            &accumulated_actual_square_error);
    }

    double average_count_estimate = accumulated_count_estimate / kNumTrials;
    double std_error_estimate = accumulated_std_err_estimate / kNumTrials;
    double observed_variance = accumulated_actual_square_error / kNumTrials;
    double observed_std_dev = sqrt(observed_variance);

    // Check that the average count estimate is within 1.66 observed
    // standard deviations of the true count, y. We may think of this
    // as performing a formal hypothesis test of the null hypothesis that
    // the count_estimates have been drawn from a distribution whose mean
    // is equal to y. For this we use a Student-t test with 100 degrees of
    // freedom (because kNumTrials = 100). By using the number 1.66 we are
    // performing the test at the 0.1 significance level because
    // P(t > 1.66) ~= 0.05 where t ~ T(100).
    double t_stat = fabs(average_count_estimate - y) / observed_std_dev;
    EXPECT_TRUE(t_stat < 1.66) << t_stat;

    // We check that the ratio of the observed_std_dev to the std_error_estimate
    // is close to one. Precisely, we check that the ratio is in the
    // interval (0.88, 1.11)  We may think of this as performing a formal
    // hypothesis test of the null hypothesis that the count_estimates have
    // been drawn from a distribution whose variance is equal to the square of
    // the std_error_estimate. For this we use a Chi-squared distribution with
    // 100 degrees of freedom (because kNumTrials = 100). The reason for numbers
    // 0.88 and 1.11 is that we are performing the test at the 0.1 significance
    // level and sqrt(77.93)/10 ~= 0.88 and sqrt(124.3)/10 ~= 1.11 and
    // P(X < 77.93) ~= 0.05 and P(X > 124.3) ~= 0.05 where X ~ Chi^2(100).
    double x_stat = observed_std_dev / std_error_estimate;
    EXPECT_TRUE(x_stat > 0.88) << x_stat;
    EXPECT_TRUE(x_stat < 1.11) << x_stat;
  }

  // By default this test uses p=0, q=1. Individual tests may override this.
  double prob_0_becomes_1_ = 0.0;
  double prob_1_stays_1_ = 1.0;
  std::unique_ptr<BasicRapporEncoder> encoder_;
  std::unique_ptr<BasicRapporAnalyzer> analyzer_;
  int add_bad_observation_call_count_ = 0;
  int add_good_observation_call_count_ = 0;
};

// Tests the raw counts when there are three categories.
TEST_F(BasicRapporAnalyzerTest, RawCountsThreeCategories) {
  // Construct an analyzer for BasicRappor with three categories.
  SetAnalyzer(3);

  AddObservation("00000000");
  ExpectRawCounts({0, 0, 0});

  AddObservation("00000000");
  ExpectRawCounts({0, 0, 0});

  AddObservation("00000001");
  ExpectRawCounts({1, 0, 0});

  AddObservation("00000001");
  ExpectRawCounts({2, 0, 0});

  AddObservation("00000010");
  ExpectRawCounts({2, 1, 0});

  AddObservation("00000010");
  ExpectRawCounts({2, 2, 0});

  AddObservation("00000011");
  ExpectRawCounts({3, 3, 0});

  AddObservation("00000100");
  ExpectRawCounts({3, 3, 1});

  AddObservation("00000101");
  ExpectRawCounts({4, 3, 2});

  AddObservation("00000011");
  ExpectRawCounts({5, 4, 2});

  AddObservation("00000111");
  ExpectRawCounts({6, 5, 3});

  AddObservation("00000111");
  ExpectRawCounts({7, 6, 4});

  for (int i = 0; i < 1000; i++) {
    AddObservation("00000101");
  }
  ExpectRawCounts({1007, 6, 1004});

  // The extra high-order-bits should be ignored
  AddObservation("11111000");
  ExpectRawCounts({1007, 6, 1004});
}

// Tests the raw counts when there are ten categories.
TEST_F(BasicRapporAnalyzerTest, RawCountsTenCategories) {
  // Construct an analyzer for BasicRappor with 10 categories.
  SetAnalyzer(10);

  AddObservation("0000000000000000");
  ExpectRawCounts({0, 0, 0, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000000");
  ExpectRawCounts({0, 0, 0, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000001");
  ExpectRawCounts({1, 0, 0, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000001");
  ExpectRawCounts({2, 0, 0, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000010");
  ExpectRawCounts({2, 1, 0, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000010");
  ExpectRawCounts({2, 2, 0, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000011");
  ExpectRawCounts({3, 3, 0, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000100");
  ExpectRawCounts({3, 3, 1, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000101");
  ExpectRawCounts({4, 3, 2, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000011");
  ExpectRawCounts({5, 4, 2, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000111");
  ExpectRawCounts({6, 5, 3, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000000000000111");
  ExpectRawCounts({7, 6, 4, 0, 0, 0, 0, 0, 0, 0});

  AddObservation("0000001000000000");
  ExpectRawCounts({7, 6, 4, 0, 0, 0, 0, 0, 0, 1});

  AddObservation("0000000100000000");
  ExpectRawCounts({7, 6, 4, 0, 0, 0, 0, 0, 1, 1});

  AddObservation("0000000010000000");
  ExpectRawCounts({7, 6, 4, 0, 0, 0, 0, 1, 1, 1});

  AddObservation("0000001010000000");
  ExpectRawCounts({7, 6, 4, 0, 0, 0, 0, 2, 1, 2});

  AddObservation("0000001110000000");
  ExpectRawCounts({7, 6, 4, 0, 0, 0, 0, 3, 2, 3});

  for (int i = 0; i < 1000; i++) {
    AddObservation("0000000100000101");
  }
  ExpectRawCounts({1007, 6, 1004, 0, 0, 0, 0, 3, 1002, 3});

  // The extra high-order-bits should be ignored
  AddObservation("1111110000000000");
  ExpectRawCounts({1007, 6, 1004, 0, 0, 0, 0, 3, 1002, 3});
}

// Tests the raw counts when there are 1,000 categories.
TEST_F(BasicRapporAnalyzerTest, RawCountsThousandCategories) {
  // Construct an analyzer for BasicRappor with 1000 categories.
  SetAnalyzer(1000);
  // Iterate 100 times
  for (int iteration = 0; iteration < 100; iteration++) {
    // For i = 0, 10, 20, 30, .....
    for (int bit_index = 0; bit_index < 1000; bit_index += 10) {
      // Add an observation with category i alone set.
      AddObservation(BuildBitPatternString(1000, bit_index, '1', '0'));
    }
  }

  // Check the counts.
  for (int category = 0; category < 1000; category++) {
    size_t expected_count = (category % 10 == 0 ? 100 : 0);
    ExpectRawCount(category, expected_count);
  }
}

// Tests that AddObservation() returns false when an invalid config is
// provided to the constructor.
TEST_F(BasicRapporAnalyzerTest, InvalidConfig) {
  // Set prob_0_becomes_1 to an invalid value.
  prob_0_becomes_1_ = 1.1;

  // Construct an analyzer for BasicRappor with 8 categories using the
  // invalid config.
  SetAnalyzer(8);

  AddObservationExpectFalse("00000000");
  AddObservationExpectFalse("00000000");
  AddObservationExpectFalse("00000001");
  AddObservationExpectFalse("00000001");
}

// Tests that AddObservation() returns false when an invalid observation
// is added.
TEST_F(BasicRapporAnalyzerTest, InvalidObservations) {
  // Construct an analyzer for BasicRappor with 8 categories using the
  // invalid config.
  SetAnalyzer(8);

  // Attempt to add observations with 2 bytes instead of one.
  AddObservationExpectFalse("0000000000000000");
  AddObservationExpectFalse("0000000000000000");
  AddObservationExpectFalse("0000000100000000");
  AddObservationExpectFalse("0000000100000000");

  // Successfully add observations with one bytes.
  AddObservation("00000001");
  AddObservation("00000001");
  AddObservation("00000001");
  AddObservation("00000001");
}

// Invokes OneBitTest on various y using n=100, p=0, q=1
TEST_F(BasicRapporAnalyzerTest, OneBitTestN100P0Q1) {
  int n = 100;
  double expected_std_err = 0;

  // Test with various values of y. expected_estimate = y.
  for (int y : {0, 1, 34, 49, 50, 51, 71, 99, 100}) {
    SCOPED_TRACE(std::to_string(y));
    OneBitTest(n, y, y, expected_std_err);
  }
}

// Invokes OneBitTest on various y using n=100, p=0.2, q=0.8
TEST_F(BasicRapporAnalyzerTest, OneBitTestN100P02Q08) {
  prob_0_becomes_1_ = 0.2;
  prob_1_stays_1_ = 0.8;
  int n = 100;

  // This is the formula for computing expected_estimate when n=100, p=0.2,
  // q=0.8.
  auto estimator = [](double y) { return (y - 20.0) * 5.0 / 3.0; };
  // This is the expected standard error for n=100, p=0.2, q=0.8, independent
  // of y.
  double expected_std_err = 20.0 / 3.0;

  // Test with various values of y.
  for (int y : {0, 1, 34, 49, 50, 51, 71, 99, 100}) {
    SCOPED_TRACE(std::to_string(y));
    OneBitTest(n, y, estimator(y), expected_std_err);
  }
}

// Invokes OneBitTest on various y using n=1000, p=0.15, q=0.85
TEST_F(BasicRapporAnalyzerTest, OneBitTestN1000P015Q085) {
  prob_0_becomes_1_ = 0.15;
  prob_1_stays_1_ = 0.85;
  int n = 1000;

  // This is the formula for computing expected_estimate when n=1000, p=0.15,
  // q=0.85.
  auto estimator = [](double y) { return (y - 150.0) * 10.0 / 7.0; };
  // This is the expected standard error for n=1000, p=0.15, q=0.85,
  // independent
  // of y.
  double expected_std_err = sqrt(127.5) * 10.0 / 7.0;

  // Test with various values of y.
  for (int y : {0, 1, 71, 333, 444, 555, 666, 777, 888, 999, 1000}) {
    SCOPED_TRACE(std::to_string(y));
    OneBitTest(n, y, estimator(y), expected_std_err);
  }
}

// Invokes OneBitTest on various y using n=5000, p=0.5, q=0.9. Notice that
// p + q > 1
TEST_F(BasicRapporAnalyzerTest, OneBitTestN5000P05Q09) {
  prob_0_becomes_1_ = 0.5;
  prob_1_stays_1_ = 0.9;
  int n = 5000;

  // This is the formula for computing expected_estimate when n=5000, p=0.5,
  // q=0.9.
  auto estimator = [](double y) { return (y - 2500.0) * 5.0 / 2.0; };

  // This is the formula for computing expected_std_err when n=5000, p=0.5,
  // q=0.9.
  auto std_err = [](double y) {
    return sqrt(y * -0.4 + 2250.0) * 5.0 / 2.0;
  };

  // Test with various values of y.
  for (int y : {0, 1, 49, 222, 1333, 2444, 3555, 4999, 5000}) {
    SCOPED_TRACE(std::to_string(y));
    OneBitTest(n, y, estimator(y), std_err(y));
  }
}

// Invokes OneBitTest on various y using n=5000, p=0.05, q=0.5. Notice that
// p + q < 1
TEST_F(BasicRapporAnalyzerTest, OneBitTestN5000P005Q05) {
  prob_0_becomes_1_ = 0.05;
  prob_1_stays_1_ = 0.5;
  int n = 5000;

  // This is the formula for computing expected_estimate when n=5000, p=0.05,
  // q=0.5.
  auto estimator = [](double y) { return (y - 250.0) / 0.45; };

  // This is the formula for computing expected_std_err when n=5000, p=0.05,
  // q=0.5.
  auto std_err = [](double y) { return sqrt(y * 0.45 + 125.0) / 0.45; };

  // Test with various values of y.
  for (int y : {0, 1, 49, 222, 1333, 2444, 3555, 4999, 5000}) {
    SCOPED_TRACE(std::to_string(y));
    OneBitTest(n, y, estimator(y), std_err(y));
  }
}

TEST_F(BasicRapporAnalyzerTest, OneCategoryTest) {
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.1, 0.9, 1000, 800);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.1, 0.9, 1000, 500);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.1, 0.9, 1000, 100);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.2, 0.8, 1000, 900);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.25, 0.75, 1000, 600);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.3, 0.7, 1000, 200);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.3, 0.85, 1000, 700);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.1, 0.85, 1000, 400);
  }
  {
    SCOPED_TRACE("");
    OneCategoryTest(0.05, 0.7, 1000, 300);
  }
}

}  // namespace rappor
}  // namespace cobalt

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  google::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);
  return RUN_ALL_TESTS();
}
