// Copyright 2017 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.

#ifndef COBALT_ANALYZER_REPORT_MASTER_REPORT_EXECUTOR_ABSTRACT_TEST_H_
#define COBALT_ANALYZER_REPORT_MASTER_REPORT_EXECUTOR_ABSTRACT_TEST_H_

#include "analyzer/report_master/report_executor.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "./observation.pb.h"
#include "encoder/client_secret.h"
#include "encoder/encoder.h"
#include "encoder/project_context.h"
#include "glog/logging.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

// This file contains type-parameterized tests of ReportGenerator.
//
// We use C++ templates along with the macros TYPED_TEST_CASE_P and
// TYPED_TEST_P in order to define test templates that may be instantiated to
// to produce concrete tests that use various implementations of Datastore.
//
// See report_generator_test.cc and report_generator_emulator_test.cc for the
// concrete instantiations.
//
// NOTE: If you add a new test to this file you must add its name to the
// invocation REGISTER_TYPED_TEST_CASE_P macro at the bottom of this file.

namespace cobalt {
namespace analyzer {

static const uint32_t kCustomerId = 1;
static const uint32_t kProjectId = 1;
static const uint32_t kMetricId1 = 1;
static const uint32_t kMetricId2 = 2;
static const uint32_t kReportConfigId1 = 1;
static const uint32_t kReportConfigId2 = 2;
static const uint32_t kForculusEncodingConfigId = 1;
static const uint32_t kBasicRapporStringEncodingConfigId = 2;
static const uint32_t kBasicRapporIntEncodingConfigId = 3;
static const char kPartName1[] = "Part1";
static const char kPartName2[] = "Part2";
static const size_t kForculusThreshold = 20;

// This unix timestamp corresponds to Friday Dec 2, 2016 in UTC
static const time_t kSomeTimestamp = 1480647356;
// This is the day index for Friday Dec 2, 2016
static const uint32_t kDayIndex = 17137;

static const char* kMetricConfigText = R"(
# Metric 1 has one string part and one integer part.
element {
  customer_id: 1
  project_id: 1
  id: 1
  time_zone_policy: UTC
  parts {
    key: "Part1"
    value {
    }
  }
  parts {
    key: "Part2"
    value {
      data_type: INT
    }
  }
}

# Metric 2 has one string part and one integer part.
element {
  customer_id: 1
  project_id: 1
  id: 2
  time_zone_policy: UTC
  parts {
    key: "Part1"
    value {
    }
  }
  parts {
    key: "Part2"
    value {
      data_type: INT
    }
  }
}

)";

static const char* kEncodingConfigText = R"(
# EncodingConfig 1 is Forculus.
element {
  customer_id: 1
  project_id: 1
  id: 1
  forculus {
    threshold: 20
  }
}

# EncodingConfig 2 is Basic RAPPOR with string candidates (non-stochastic)
element {
  customer_id: 1
  project_id: 1
  id: 2
  basic_rappor {
    prob_0_becomes_1: 0.0
    prob_1_stays_1: 1.0
    string_categories: {
      category: "Apple"
      category: "Banana"
      category: "Cantaloupe"
    }
  }
}

# EncodingConfig 3 is Basic RAPPOR with integer candidates (non-stochastic).
element {
  customer_id: 1
  project_id: 1
  id: 3
  basic_rappor {
    prob_0_becomes_1: 0.0
    prob_1_stays_1: 1.0
    int_range_categories: {
      first: 1
      last:  10
    }
  }
}

)";

static const char* kReportConfigText = R"(
# ReportConfig 1 specifies a report of both variables of Metric 1.
element {
  customer_id: 1
  project_id: 1
  id: 1
  metric_id: 1
  variable {
    metric_part: "Part1"
  }
  variable {
    metric_part: "Part2"
  }
}

# ReportConfig 2 specifies a report of both variables of Metric 2.
element {
  customer_id: 1
  project_id: 1
  id: 2
  metric_id: 2
  variable {
    metric_part: "Part1"
  }
  variable {
    metric_part: "Part2"
  }
}

)";

// ReportExecutorAbstractTest is templatized on the parameter
// |StoreFactoryClass| which must be the name of a class that contains the
// following method: static DataStore* NewStore()
// See MemoryStoreFactory in store/memory_store_test_helper.h and
// BigtableStoreEmulatorFactory in store/bigtable_emulator_helper.h.
template <class StoreFactoryClass>
class ReportExecutorAbstractTest : public ::testing::Test {
 protected:
  ReportExecutorAbstractTest()
      : data_store_(StoreFactoryClass::NewStore()),
        observation_store_(new store::ObservationStore(data_store_)),
        report_store_(new store::ReportStore(data_store_)) {
    report_id1_.set_customer_id(kCustomerId);
    report_id1_.set_project_id(kProjectId);
    report_id1_.set_report_config_id(kReportConfigId1);
    report_id2_.set_customer_id(kCustomerId);
    report_id2_.set_project_id(kProjectId);
    report_id2_.set_report_config_id(kReportConfigId2);
  }

  void SetUp() {
    // Clear the DataStore.
    EXPECT_EQ(store::kOK,
              data_store_->DeleteAllRows(store::DataStore::kObservations));
    EXPECT_EQ(store::kOK,
              data_store_->DeleteAllRows(store::DataStore::kReportMetadata));
    EXPECT_EQ(store::kOK,
              data_store_->DeleteAllRows(store::DataStore::kReportRows));

    // Parse the metric config string
    auto metric_parse_result =
        config::MetricRegistry::FromString(kMetricConfigText, nullptr);
    EXPECT_EQ(config::kOK, metric_parse_result.second);
    std::shared_ptr<config::MetricRegistry> metric_registry(
        metric_parse_result.first.release());

    // Parse the encoding config string
    auto encoding_parse_result =
        config::EncodingRegistry::FromString(kEncodingConfigText, nullptr);
    EXPECT_EQ(config::kOK, encoding_parse_result.second);
    std::shared_ptr<config::EncodingRegistry> encoding_config_registry(
        encoding_parse_result.first.release());

    // Parse the report config string
    auto report_parse_result =
        config::ReportRegistry::FromString(kReportConfigText, nullptr);
    EXPECT_EQ(config::kOK, report_parse_result.second);
    std::shared_ptr<config::ReportRegistry> report_config_registry(
        report_parse_result.first.release());

    // Make a ProjectContext
    project_.reset(new encoder::ProjectContext(
        kCustomerId, kProjectId, metric_registry, encoding_config_registry));

    std::shared_ptr<config::AnalyzerConfig> analyzer_config(
        new config::AnalyzerConfig(encoding_config_registry, metric_registry,
                                   report_config_registry));

    // Make a ReportGenerator
    std::unique_ptr<ReportGenerator> report_generator(new ReportGenerator(
        analyzer_config, observation_store_, report_store_));

    // Make a ReportExecutor
    report_executor_.reset(
        new ReportExecutor(report_store_, std::move(report_generator)));
  }
  // Makes an Observation with one string part and one int part, using the
  // two given values and the two given encodings for the given metric.
  std::unique_ptr<Observation> MakeObservation(std::string part1_value,
                                               int part2_value,
                                               uint32_t metric_id,
                                               uint32_t encoding_config_id1,
                                               uint32_t encoding_config_id2) {
    // Construct a new Encoder with a new client secret.
    encoder::Encoder encoder(project_,
                             encoder::ClientSecret::GenerateNewSecret());
    // Set a static current time so we know we have a static day_index.
    encoder.set_current_time(kSomeTimestamp);

    // Construct the two-part value to add.
    encoder::Encoder::Value value;
    value.AddStringPart(encoding_config_id1, kPartName1, part1_value);
    value.AddIntPart(encoding_config_id2, kPartName2, part2_value);

    // Encode an observation.
    encoder::Encoder::Result result = encoder.Encode(metric_id, value);
    EXPECT_EQ(encoder::Encoder::kOK, result.status);
    EXPECT_TRUE(result.observation.get() != nullptr);
    EXPECT_EQ(2, result.observation->parts_size());
    return std::move(result.observation);
  }

  // Adds to the ObservationStore |num_clients| two-part observations that each
  // encode the given two values using the given metric and the
  // given two encodings. Each Observation is generated as if from a different
  // client.
  void AddObservations(std::string part1_value, int part2_value,
                       uint32_t metric_id, uint32_t encoding_config_id1,
                       uint32_t encoding_config_id2, int num_clients) {
    std::vector<Observation> observations;
    for (int i = 0; i < num_clients; i++) {
      observations.emplace_back(*MakeObservation(part1_value, part2_value,
                                                 metric_id, encoding_config_id1,
                                                 encoding_config_id2));
    }
    ObservationMetadata metadata;
    metadata.set_customer_id(kCustomerId);
    metadata.set_project_id(kProjectId);
    metadata.set_metric_id(metric_id);
    metadata.set_day_index(kDayIndex);
    EXPECT_EQ(store::kOK,
              observation_store_->AddObservationBatch(metadata, observations));
  }

  // Checks that the report with the given ID completed successfully and has
  // the expected number of rows.
  void CheckReport(const ReportId report_id, int expected_num_rows) {
    ReportMetadataLite metadata;
    ReportRows rows;
    ASSERT_EQ(store::kOK, report_store_->GetReport(report_id, &metadata, &rows))
        << "report_id=" << store::ReportStore::ToString(report_id);
    ASSERT_EQ(COMPLETED_SUCCESSFULLY, metadata.state())
        << "report_id=" << store::ReportStore::ToString(report_id);
    EXPECT_EQ(expected_num_rows, rows.rows_size())
        << "report_id=" << store::ReportStore::ToString(report_id);
  }

  ReportId report_id1_, report_id2_;
  std::shared_ptr<encoder::ProjectContext> project_;
  std::shared_ptr<store::DataStore> data_store_;
  std::shared_ptr<store::ObservationStore> observation_store_;
  std::shared_ptr<store::ReportStore> report_store_;
  std::unique_ptr<ReportExecutor> report_executor_;
};

TYPED_TEST_CASE_P(ReportExecutorAbstractTest);

// We load up the ObservationStore with observations for our two metrics.
// Then we start a ReportExecutor and invoke EnqueueReportGeneration() on
// two dependency chains of reports-- one for parts 1 and 2 of ReportConfig 1
// and one for parts 1 and 2 of ReportConfig 2. We expect 4 reports to
// complete successfully and contain the expected number of rows.
TYPED_TEST_P(ReportExecutorAbstractTest, EnqueueReportGeneration) {
  // Add some observations for metric 1. We use Basic RAPPOR for
  // both parts.
  this->AddObservations("Apple", 10, kMetricId1,
                        kBasicRapporStringEncodingConfigId,
                        kBasicRapporIntEncodingConfigId, 20);

  // Add some observations for metric 2. We use Forculus for part 1
  // and BasicRappor for part 2. For the Forculus part there will be
  // 20 observations of "Apple" but only 19 observations of "Banana" so
  // we expect to see only Apple in the report.
  this->AddObservations("Apple", 10, kMetricId2, kForculusEncodingConfigId,
                        kBasicRapporIntEncodingConfigId, kForculusThreshold);
  this->AddObservations("Banana", 10, kMetricId2, kForculusEncodingConfigId,
                        kBasicRapporIntEncodingConfigId,
                        kForculusThreshold - 1);

  // Register the start of report 1, sequence_num 0, variable 0.
  ReportId report_id11 = this->report_id1_;
  this->report_store_->StartNewReport(kDayIndex, kDayIndex, true, HISTOGRAM,
                                      {0}, &report_id11);

  // Register the creation of report1, sequence_num 1, variable 1.
  ReportId report_id12 = report_id11;
  this->report_store_->CreateDependentReport(1, HISTOGRAM, {1}, &report_id12);

  // Register the start of report2, sequence_num 0, variable 0.
  ReportId report_id21 = this->report_id2_;
  this->report_store_->StartNewReport(kDayIndex, kDayIndex, true, HISTOGRAM,
                                      {0}, &report_id21);

  // Register the creation of report2, sequence_num 1, variable 1.
  ReportId report_id22 = report_id21;
  this->report_store_->CreateDependentReport(1, HISTOGRAM, {1}, &report_id22);

  // Create two dependency chains of reports. We have the variable 1 report
  // depend on the variable 0 report for both report IDs.
  std::vector<ReportId> chain1;
  chain1.push_back(report_id11);
  chain1.push_back(report_id12);

  std::vector<ReportId> chain2;
  chain2.push_back(report_id21);
  chain2.push_back(report_id22);

  // Start the ReportExecutor
  this->report_executor_->Start();

  // Enqueue chain 1.
  auto status =
      this->report_executor_->EnqueueReportGeneration(std::move(chain1));
  EXPECT_TRUE(status.ok()) << status.error_code() << " "
                           << status.error_message();

  // Enqueue chain 2.
  status = this->report_executor_->EnqueueReportGeneration(std::move(chain2));
  EXPECT_TRUE(status.ok()) << status.error_code() << " "
                           << status.error_message();

  // Wait for the processing to stop.
  this->report_executor_->WaitUntilIdle();

  // report_id11 analyzed Part 1 of metric 1 which received
  // Basic RAPPOR string observations with 3 categories.
  this->CheckReport(report_id11, 3);

  // report_id12 analyzed Part 2 of metric 1 which received
  // Basic RAPPOR int observations with 10 categories.
  this->CheckReport(report_id12, 10);

  // report_id21 analyzed Part 1 of metric 1 which received
  // Forculus observations in which there were 20 observations of Apple
  // but only 19 observations of Banana. So there should only be 1 row in
  // the report.
  this->CheckReport(report_id21, 1);

  // report_id22 of report 2 analyzes Part 2 of metric 2 which received
  // Basic RAPPOR int observations with 10 categories.
  this->CheckReport(report_id22, 10);
}

REGISTER_TYPED_TEST_CASE_P(ReportExecutorAbstractTest, EnqueueReportGeneration);

}  // namespace analyzer
}  // namespace cobalt

#endif  // COBALT_ANALYZER_REPORT_MASTER_REPORT_EXECUTOR_ABSTRACT_TEST_H_
