// 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/forculus/forculus_analyzer.h"

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

#include "algorithms/forculus/forculus_encrypter.h"
#include "encoder/client_secret.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

namespace cobalt {
namespace forculus {

using encoder::ClientSecret;

static const uint32_t kThreshold = 20;

namespace {
// Encrypts the plaintext using Forculus encryption with the given day_index
// and EpochType and threshold = kThreshold and default values for the other
// parameters. A fresh ClientSecret will be generated each time this function
// is invoked. Returns a ForculusObservation containing the ciphertext.
ForculusObservation Encrypt(uint32_t day_index, const EpochType& epoch_type,
    const std::string& plaintext) {
  // Make a config with the given threshold
  ForculusConfig config;
  config.set_threshold(kThreshold);
  config.set_epoch_type(epoch_type);

  // Construct an Encrypter.
  ForculusEncrypter encrypter(config, 0, 0, 0, "",
      ClientSecret::GenerateNewSecret());

  // Invoke Encrypt() and check the status.
  ForculusObservation obs;
  EXPECT_EQ(ForculusEncrypter::kOK,
      encrypter.Encrypt(plaintext, day_index,
                        &obs));
  return obs;
}

// Creates and adds observations to |forculus_analyzer| based on the parameters.
void AddObservations(ForculusAnalyzer* forculus_analyzer, uint32_t day_index,
    const EpochType& epoch_type, const std::string& plaintext, int num_clients,
    int num_copies_per_client) {
  // Simulate num_clients different clients.
  for (int i = 0; i < num_clients; i++) {
    auto observation = Encrypt(day_index, epoch_type, plaintext);
    // Each client adds the same observation |num_copies_per_client| times.
    for (int i = 0; i < num_copies_per_client; i++) {
       EXPECT_TRUE(forculus_analyzer->AddObservation(day_index, observation));
    }
  }
}

}  // namespace

// Tests the use of a ForculusAnalyzer when used properly with no
// errors. We simulate multiple clients encrypting multpile plaintexts
// on multiple days. Each client can encrypt the same plaintext multiple
// times on the same day.
TEST(ForculusAnalyzerTest, NoErrors) {
  ForculusConfig forculus_config;
  forculus_config.set_threshold(kThreshold);
  ForculusAnalyzer forculus_analyzer(forculus_config);

  const std::string plaintext1("The woods are lovely, dark and deep,");
  const std::string plaintext2("But I have promises to keep,");
  const std::string plaintext3("And miles to go before I sleep,");
  const std::string plaintext4("And miles to go before I sleep.");

  // 20 * 5 observations of plaintext1 on day 0. (This means 20 different
  // clients each encrypting plaintext1 5 times on day 0.)
  AddObservations(&forculus_analyzer, 0, DAY, plaintext1, kThreshold, 5);
  // 20 * 5 observations of plaintext1 on day 1.
  AddObservations(&forculus_analyzer, 1, DAY, plaintext1, kThreshold, 5);

  // 21 * 6 observations of plaintext2 on day 0.
  AddObservations(&forculus_analyzer, 0, DAY, plaintext2, kThreshold + 1, 6);
  // 19 * 6 observations of plaintext2 on day 1. These will not be decrypted.
  AddObservations(&forculus_analyzer, 1, DAY, plaintext2, kThreshold - 1, 6);

  // 19 * 7 observations of plaintext3 on day 0. These will not be decrypted.
  AddObservations(&forculus_analyzer, 0,  DAY, plaintext3, kThreshold - 1, 7);
  // 19 * 7 observations of plaintext3 on day 1. These will not be decrypted.
  AddObservations(&forculus_analyzer, 1,  DAY, plaintext3, kThreshold - 1, 7);

  // 22 * 8 observations of plaintext4 on day 3.
  AddObservations(&forculus_analyzer, 3, DAY, plaintext4, kThreshold + 2, 8);

  EXPECT_EQ(0u, forculus_analyzer.observation_errors());
  static const size_t kExpectedNumObservations =
      kThreshold * 5 + kThreshold * 5 +
      (kThreshold + 1) * 6 + (kThreshold - 1) * 6 +
      (kThreshold - 1) * 7 + (kThreshold - 1) * 7 +
      (kThreshold + 2) * 8;
  EXPECT_EQ(kExpectedNumObservations, forculus_analyzer.num_observations());
  auto results = forculus_analyzer.TakeResults();

  // We should have decrypted plaintexts 1, 2 and 4.
  EXPECT_EQ(3u, results.size());

  // Check plaintext1
  EXPECT_EQ(kThreshold * 5 + kThreshold * 5, results[plaintext1]->total_count);
  EXPECT_EQ(2u, results[plaintext1]->num_epochs);

  // Check plaintext2
  EXPECT_EQ((kThreshold + 1) * 6, results[plaintext2]->total_count);
  EXPECT_EQ(1u, results[plaintext2]->num_epochs);

  // Check plaintext4
  EXPECT_EQ((kThreshold + 2) * 8, results[plaintext4]->total_count);
  EXPECT_EQ(1u, results[plaintext4]->num_epochs);

  // Plaintext3 should not be decrypted.
  EXPECT_EQ(nullptr, results[plaintext3]);
}

// We test Forculus encryption and analysis using DAY, WEEK and MONTH epochs.
TEST(ForculusAnalyzerTest, TestEpochTypes) {
  ForculusConfig forculus_config;
  forculus_config.set_threshold(kThreshold);
  std::unique_ptr<ForculusAnalyzer> forculus_analyzer(
      new ForculusAnalyzer(forculus_config));

  const std::string plaintext("Some text");

  // First we test with a DAY epoch, the default.

  // Add 10 observations on day 0,
  AddObservations(forculus_analyzer.get(), 0, DAY, plaintext, kThreshold - 10,
                  1);
  // and 10 observations on day 1.
  AddObservations(forculus_analyzer.get(), 1, DAY, plaintext, 10, 1);

  // Since day 0 and day 1 are different epochs we should not have decrypted the
  // plaintext.
  auto results = forculus_analyzer->TakeResults();
  EXPECT_EQ(0u, results.size());

  // Next we test with a WEEK epoch
  forculus_config.set_epoch_type(WEEK);
  forculus_analyzer.reset(new ForculusAnalyzer(forculus_config));

  // Add 10 observations on day 0,
  AddObservations(forculus_analyzer.get(), 0, WEEK, plaintext, kThreshold - 10,
                  1);
  // and 10 observations on day 1.
  AddObservations(forculus_analyzer.get(), 1, WEEK, plaintext, 10, 1);

  // Since day 0 and day 1 are in the same epoch we should have decrypted the
  // plaintext.
  results = forculus_analyzer->TakeResults();
  EXPECT_EQ(1u, results.size());

  // Next we test with a WEEK epoch but two days in different weeks.
  forculus_analyzer.reset(new ForculusAnalyzer(forculus_config));

  // Add 10 observations on day 0,
  AddObservations(forculus_analyzer.get(), 0, WEEK, plaintext, kThreshold - 10,
                  1);
  // and 10 observations on day 7.
  AddObservations(forculus_analyzer.get(), 7, WEEK, plaintext, 10, 1);

  // Since day 0 and day 7 are different epochs we should not have decrypted the
  // plaintext.
  results = forculus_analyzer->TakeResults();
  EXPECT_EQ(0u, results.size());

  // Next we test with a MONTH epoch
  forculus_config.set_epoch_type(MONTH);
  forculus_analyzer.reset(new ForculusAnalyzer(forculus_config));

  // Add 10 observations on day 0,
  AddObservations(forculus_analyzer.get(), 0, MONTH, plaintext, kThreshold - 10,
                  1);
  // and 10 observations on day 7.
  AddObservations(forculus_analyzer.get(), 7, MONTH, plaintext, 10, 1);

  // Since day 0 and day 7 are in the same epoch we should have decrypted the
  // plaintext.
  results = forculus_analyzer->TakeResults();
  EXPECT_EQ(1u, results.size());

  // Finally we test with a MONTH epoch but two days in different months.
  forculus_config.set_epoch_type(MONTH);
  forculus_analyzer.reset(new ForculusAnalyzer(forculus_config));

  // Add 10 observations on day 0,
  AddObservations(forculus_analyzer.get(), 0, MONTH, plaintext, kThreshold - 10,
                  1);
  // and 10 observations on day 31.
  AddObservations(forculus_analyzer.get(), 31, MONTH, plaintext, 10, 1);

  // Since day 0 and day 31 are in different epochs we should not have decrypted
  // the  plaintext.
  results = forculus_analyzer->TakeResults();
  EXPECT_EQ(0u, results.size());
}

// Tests the use of a ForculusAnalyzer when fed observations with errors.
TEST(ForculusAnalyzerTest, WithErrors) {
  ForculusConfig forculus_config;
  forculus_config.set_threshold(3);
  ForculusAnalyzer forculus_analyzer(forculus_config);

  ForculusObservation obs;
  obs.set_ciphertext("1 ciphertext fake");
  obs.set_point_x("1 x fake");
  obs.set_point_y("1 y fake");

  // Add an observation.
  EXPECT_TRUE(forculus_analyzer.AddObservation(0, obs));
  EXPECT_EQ(1u, forculus_analyzer.num_observations());
  EXPECT_EQ(0u, forculus_analyzer.observation_errors());

  // Now add another observation with the same ciphertext and x-value
  // but a different y-value. This causes an error.
  obs.set_point_y("2 y fake");
  EXPECT_FALSE(forculus_analyzer.AddObservation(0, obs));
  EXPECT_EQ(1u, forculus_analyzer.num_observations());
  EXPECT_EQ(1u, forculus_analyzer.observation_errors());

  // The whole ciphertext is considered corupt now so even changing to
  // a differnt x value still yields an error.
  obs.set_point_x("2 x fake");
  EXPECT_FALSE(forculus_analyzer.AddObservation(0, obs));
  EXPECT_EQ(1u, forculus_analyzer.num_observations());
  EXPECT_EQ(2u, forculus_analyzer.observation_errors());

  // Adding an observation for a different epoch succeeds.
  obs.set_point_x("1 x fake");
  obs.set_point_y("1 y fake");
  EXPECT_TRUE(forculus_analyzer.AddObservation(1, obs));
  EXPECT_EQ(2u, forculus_analyzer.num_observations());
  EXPECT_EQ(2u, forculus_analyzer.observation_errors());

  // Adding a second obseration for epoch 1 also succeeds.
  obs.set_point_x("2 x fake");
  obs.set_point_y("2 y fake");
  EXPECT_TRUE(forculus_analyzer.AddObservation(1, obs));
  EXPECT_EQ(3u, forculus_analyzer.num_observations());
  EXPECT_EQ(2u, forculus_analyzer.observation_errors());

  // Adding a third obseration for epoch 1 invokes a decryption which fails.
  obs.set_point_x("3 x fake");
  obs.set_point_y("3 y fake");
  EXPECT_FALSE(forculus_analyzer.AddObservation(1, obs));
  EXPECT_EQ(3u, forculus_analyzer.num_observations());
  EXPECT_EQ(3u, forculus_analyzer.observation_errors());

  // Adding a fourth obseration for epoch 1 also fails.
  obs.set_point_x("4 x fake");
  obs.set_point_y("4 y fake");
  EXPECT_FALSE(forculus_analyzer.AddObservation(1, obs));
  EXPECT_EQ(3u, forculus_analyzer.num_observations());
  EXPECT_EQ(4u, forculus_analyzer.observation_errors());

  // There should be no results.
  auto results = forculus_analyzer.TakeResults();
  EXPECT_EQ(0u, results.size());
}

}  // namespace forculus
}  // namespace cobalt

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

