// 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_GENERATOR_ABSTRACT_TEST_H_
#define COBALT_ANALYZER_REPORT_MASTER_REPORT_GENERATOR_ABSTRACT_TEST_H_

#include "analyzer/report_master/report_generator.h"

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

#include "./observation.pb.h"
#include "analyzer/report_master/report_exporter.h"
#include "config/config_text_parser.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 {

namespace testing {

const uint32_t kCustomerId = 1;
const uint32_t kProjectId = 1;
const uint32_t kMetricId = 1;
const uint32_t kJointReportConfigId = 1;
const uint32_t kRawDumpReportConfigId = 1;
const uint32_t kGroupedReportConfigId = 3;
const uint32_t kGroupedRawDumpReportConfigId = 4;
const uint32_t kForculusEncodingConfigId = 1;
const uint32_t kBasicRapporEncodingConfigId = 2;
const uint32_t kNoOpEncodingConfigId = 3;
const char kPartName1[] = "Part1";
const char kPartName2[] = "Part2";
const size_t kForculusThreshold = 20;

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

const char* kMetricConfigText = R"(
# Metric 1 has two string parts.
element {
  customer_id: 1
  project_id: 1
  id: 1
  time_zone_policy: UTC
  parts {
    key: "Part1"
    value {
    }
  }
  parts {
    key: "Part2"
    value {
    }
  }
}

)";

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.
element {
  customer_id: 1
  project_id: 1
  id: 2
  basic_rappor {
    prob_0_becomes_1: 0.25
    prob_1_stays_1: 0.75
    string_categories: {
      category: "Apple"
      category: "Banana"
      category: "Cantaloupe"
    }
  }
}

# EncodingConfig 3 is NoOp.
element {
  customer_id: 1
  project_id: 1
  id: 3
  no_op_encoding {
  }
}

)";

const char* kReportConfigText = R"(
# ReportConfig 1 specifies a JOINT report of both variables of Metric 1.
# We use this config only in order to run HISTOGRAM reports on the
# two variables separately since JOINT reports are not currently
# implemented.
element {
  customer_id: 1
  project_id: 1
  id: 1
  metric_id: 1
  variable {
    metric_part: "Part1"
  }
  variable {
    metric_part: "Part2"
  }
  report_type: JOINT
  export_configs {
    csv {}
    gcs {
      bucket: "BUCKET-NAME"
    }
  }
}

# ReportConfig 2 specifies a RAW_DUMP report of both variables of Metric 1.
element {
  customer_id: 1
  project_id: 1
  id: 2
  metric_id: 1
  variable {
    metric_part: "Part1"
  }
  variable {
    metric_part: "Part2"
  }
  report_type: RAW_DUMP
  export_configs {
    csv {}
    gcs {
      bucket: "BUCKET-NAME"
    }
  }
}

element {
  customer_id: 1
  project_id: 1
  id: 3
  metric_id: 1
  variable {
    metric_part: "Part1"
  }
  variable {
    metric_part: "Part2"
  }
  system_profile_field: [BOARD_NAME]
  report_type: JOINT
  export_configs {
    csv {}
    gcs {
      bucket: "BUCKET-NAME"
    }
  }
}

element {
  customer_id: 1
  project_id: 1
  id: 4
  metric_id: 1
  variable {
    metric_part: "Part1"
  }
  variable {
    metric_part: "Part2"
  }
  system_profile_field: [BOARD_NAME]
  report_type: RAW_DUMP
  export_configs {
    csv {}
    gcs {
      bucket: "BUCKET-NAME"
    }
  }
}


)";

// An implementation of GcsUploadInterface that saves its parameters and
// returns OK.
struct FakeGcsUploader : public GcsUploadInterface {
  grpc::Status UploadToGCS(const std::string& bucket, const std::string& path,
                           const std::string& mime_type,
                           ReportStream* report_stream) override {
    this->upload_was_invoked = true;
    this->bucket = bucket;
    this->path = path;
    this->mime_type = mime_type;
    this->serialized_report =
        std::string(std::istreambuf_iterator<char>(*report_stream), {});
    return grpc::Status::OK;
  }

  bool upload_was_invoked = false;
  std::string bucket;
  std::string path;
  std::string mime_type;
  std::string serialized_report;
};

}  // namespace testing

// ReportGeneratorAbstractTest 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 sotre/memory_store_test_helper.h and
// BigtableStoreEmulatorFactory in store/bigtable_emulator_helper.h.
template <class StoreFactoryClass>
class ReportGeneratorAbstractTest : public ::testing::Test {
 protected:
  ReportGeneratorAbstractTest()
      : data_store_(StoreFactoryClass::NewStore()),
        observation_store_(new store::ObservationStore(data_store_)),
        report_store_(new store::ReportStore(data_store_)),
        fake_uploader_(new testing::FakeGcsUploader()) {
    report_id_.set_customer_id(testing::kCustomerId);
    report_id_.set_project_id(testing::kProjectId);
    report_id_.set_report_config_id(testing::kJointReportConfigId);
  }

  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::FromString<RegisteredMetrics>(
        testing::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::FromString<RegisteredEncodings>(
        testing::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::FromString<RegisteredReports>(
        testing::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(testing::kCustomerId, testing::kProjectId,
                                    metric_registry, encoding_config_registry));

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

    // Make the ReportGenerator
    std::unique_ptr<ReportExporter> report_exporter(
        new ReportExporter(fake_uploader_));
    report_generator_.reset(
        new ReportGenerator(analyzer_config_manager, observation_store_,
                            report_store_, std::move(report_exporter)));
  }

  // Makes an Observation with two string parts, both of which have the
  // given |string_value|, using the encoding with the given encoding_config_id.
  std::unique_ptr<Observation> MakeObservation(std::string string_value,
                                               uint32_t encoding_config_id) {
    // 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(testing::kSomeTimestamp);

    // Construct the two-part value to add.
    encoder::Encoder::Value value;
    value.AddStringPart(encoding_config_id, testing::kPartName1, string_value);
    value.AddStringPart(encoding_config_id, testing::kPartName2, string_value);

    // Encode an observation.
    encoder::Encoder::Result result = encoder.Encode(testing::kMetricId, 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| observations of our test metric
  // that each encode the given string |value| using the given
  // |encoding_config_id|. Each Observation is generated as if from a different
  // client.
  void AddObservations(std::string value, uint32_t encoding_config_id,
                       int num_clients) {
    AddObservations(value, encoding_config_id, num_clients,
                    std::make_unique<SystemProfile>());
  }
  void AddObservations(std::string value, uint32_t encoding_config_id,
                       int num_clients,
                       std::unique_ptr<SystemProfile> profile) {
    std::vector<Observation> observations;
    for (int i = 0; i < num_clients; i++) {
      observations.emplace_back(*MakeObservation(value, encoding_config_id));
    }
    ObservationMetadata metadata;
    metadata.set_customer_id(testing::kCustomerId);
    metadata.set_project_id(testing::kProjectId);
    metadata.set_metric_id(testing::kMetricId);
    metadata.set_day_index(testing::kDayIndex);
    metadata.set_allocated_system_profile(profile.release());
    EXPECT_EQ(store::kOK,
              observation_store_->AddObservationBatch(metadata, observations));
  }

  struct GeneratedReport {
    ReportMetadataLite metadata;
    ReportRows rows;
  };

  // Uses the ReportGenerator to generate a HISTOGRAM report that analyzes the
  // specified variable of our two-variable test metric. |variable_index| must
  // be either 0 or 1. It will also be used for the sequence_num.
  // If |export_report| is true then the report will be exported using
  // our FakeGcsUploader. If |in_store| is true the report will be saved
  // to the ReportStore.
  GeneratedReport GenerateHistogramReport(int variable_index,
                                          bool export_report, bool in_store) {
    // Complete the report_id by specifying the sequence_num.
    report_id_.set_sequence_num(variable_index);

    // Start a report for the specified variable, for the interval of days
    // [kDayIndex, kDayIndex].
    std::string export_name = export_report ? "export_name" : "";
    EXPECT_EQ(store::kOK, report_store_->StartNewReport(
                              testing::kDayIndex, testing::kDayIndex, true,
                              export_name, in_store, HISTOGRAM,
                              {(uint32_t)variable_index}, &report_id_));

    // Generate the report
    EXPECT_TRUE(report_generator_->GenerateReport(report_id_).ok());

    // Fetch the report from the ReportStore.
    GeneratedReport report;
    EXPECT_EQ(store::kOK, report_store_->GetReport(report_id_, &report.metadata,
                                                   &report.rows));

    return report;
  }

  GeneratedReport GenerateGroupedHistogramReport(int variable_index,
                                                 bool export_report,
                                                 bool in_store) {
    report_id_.set_report_config_id(testing::kGroupedReportConfigId);
    report_id_.set_sequence_num(variable_index);
    std::string export_name = export_report ? "export_name" : "";
    EXPECT_EQ(store::kOK, report_store_->StartNewReport(
                              testing::kDayIndex, testing::kDayIndex, true,
                              export_name, in_store, HISTOGRAM,
                              {(uint32_t)variable_index}, &report_id_));
    EXPECT_TRUE(report_generator_->GenerateReport(report_id_).ok());

    GeneratedReport report;
    EXPECT_EQ(store::kOK, report_store_->GetReport(report_id_, &report.metadata,
                                                   &report.rows));

    return report;
  }

  GeneratedReport GenerateRawDumpReport(bool export_report, bool in_store) {
    report_id_.set_sequence_num(0);

    // Start a report for the specified variable, for the interval of days
    // [kDayIndex, kDayIndex].
    std::string export_name = export_report ? "export_name" : "";
    EXPECT_EQ(store::kOK,
              report_store_->StartNewReport(
                  testing::kDayIndex, testing::kDayIndex, true, export_name,
                  in_store, RAW_DUMP, {0, 1}, &report_id_));

    // Generate the report
    EXPECT_TRUE(report_generator_->GenerateReport(report_id_).ok());

    // Fetch the report from the ReportStore.
    GeneratedReport report;
    EXPECT_EQ(store::kOK, report_store_->GetReport(report_id_, &report.metadata,
                                                   &report.rows));

    return report;
  }

  GeneratedReport GenerateGroupedRawDumpReport(bool export_report,
                                               bool in_store) {
    report_id_.set_report_config_id(testing::kGroupedRawDumpReportConfigId);
    report_id_.set_sequence_num(0);
    // Start a report for the specified variable, for the interval of days
    // [kDayIndex, kDayIndex].
    std::string export_name = export_report ? "export_name" : "";
    EXPECT_EQ(store::kOK,
              report_store_->StartNewReport(
                  testing::kDayIndex, testing::kDayIndex, true, export_name,
                  in_store, RAW_DUMP, {0, 1}, &report_id_));

    // Generate the report
    EXPECT_TRUE(report_generator_->GenerateReport(report_id_).ok());

    // Fetch the report from the ReportStore.
    GeneratedReport report;
    EXPECT_EQ(store::kOK, report_store_->GetReport(report_id_, &report.metadata,
                                                   &report.rows));

    return report;
  }

  // Adds to the ObservationStore a bunch of Observations of our test metric
  // that use our test Forculus encoding config in which the Forculus threshold
  // is 20. Each Observation is generated as if from a different client.
  // We simulate 20 clients adding "hello", 19 clients adding "goodbye", and
  // 21 clients adding "peace". Thus we expect "hello" and "peace" to appear
  // in the generated report but not "goodybe".
  void AddForculusObservations() {
    // Add 20 copies of the Observation "hello"
    AddObservations("hello", testing::kForculusEncodingConfigId,
                    testing::kForculusThreshold);

    // Add 19 copies of the Observation "goodbye"
    AddObservations("goodbye", testing::kForculusEncodingConfigId,
                    testing::kForculusThreshold - 1);

    // Add 21 copies of the Observation "peace"
    AddObservations("peace", testing::kForculusEncodingConfigId,
                    testing::kForculusThreshold + 1);
  }

  // This is the CSV that should be generated when the report for metric part 2
  // is exported, when Forculus Observations are added, based on the
  // Observations that are added in AddForculusObservations() above.
  const char* const kExpectedPart2ForculusCSV = R"(date,Part2,count,err
2016-12-2,"hello",20.000,0
2016-12-2,"peace",21.000,0
)";

  // This method should be invoked after invoking AddForculusObservations()
  // and then GenerateReport. It checks the generated Report to make sure
  // it is correct given the Observations that were added and the Forculus
  // config.
  void CheckForculusReport(const GeneratedReport& report, uint variable_index,
                           const std::string& expected_export_csv) {
    EXPECT_EQ(HISTOGRAM, report.metadata.report_type());
    EXPECT_EQ(1, report.metadata.variable_indices_size());
    EXPECT_EQ(variable_index, report.metadata.variable_indices(0));
    if (report.metadata.in_store()) {
      EXPECT_EQ(2, report.rows.rows_size());
      for (const auto& report_row : report.rows.rows()) {
        EXPECT_EQ(0, report_row.histogram().std_error());
        ValuePart recovered_value;
        EXPECT_TRUE(report_row.histogram().has_value());
        recovered_value = report_row.histogram().value();

        EXPECT_EQ(ValuePart::kStringValue, recovered_value.data_case());
        std::string string_value = recovered_value.string_value();
        int count_estimate = report_row.histogram().count_estimate();
        switch (count_estimate) {
          case 20:
            EXPECT_EQ("hello", string_value);
            break;
          case 21:
            EXPECT_EQ("peace", string_value);
            break;
          default:
            FAIL();
        }
      }
    } else {
      EXPECT_EQ(0, report.rows.rows_size());
    }
    if (report.metadata.export_name() == "") {
      EXPECT_FALSE(this->fake_uploader_->upload_was_invoked);
    } else {
      EXPECT_TRUE(this->fake_uploader_->upload_was_invoked);
      // Reset for next time
      this->fake_uploader_->upload_was_invoked = false;
      EXPECT_EQ("BUCKET-NAME", fake_uploader_->bucket);
      EXPECT_EQ("1_1_1/export_name.csv", fake_uploader_->path);
      EXPECT_EQ("text/csv", fake_uploader_->mime_type);
      EXPECT_EQ(expected_export_csv, fake_uploader_->serialized_report);
    }
  }

  // Adds to the ObservationStore a bunch of Observations of our test metric
  // that use our test BasicRappor encoding config. We add 100 observations of
  // "Apple", 200 observations of "Banana", and 300 observations of
  // "Cantaloupe".
  void AddBasicRapporObservations() {
    AddObservations("Apple", testing::kBasicRapporEncodingConfigId, 100);
    AddObservations("Banana", testing::kBasicRapporEncodingConfigId, 200);
    AddObservations("Cantaloupe", testing::kBasicRapporEncodingConfigId, 300);
  }

  std::unique_ptr<SystemProfile> MakeProfile(std::string board_name) {
    auto profile = std::make_unique<SystemProfile>();
    *profile->mutable_board_name() = board_name;
    return profile;
  }
  void AddGroupedBasicRapporObservations() {
    AddObservations("Apple", testing::kBasicRapporEncodingConfigId, 50,
                    MakeProfile("foo"));
    AddObservations("Apple", testing::kBasicRapporEncodingConfigId, 50,
                    MakeProfile("bar"));
    AddObservations("Banana", testing::kBasicRapporEncodingConfigId, 100,
                    MakeProfile("foo"));
    AddObservations("Banana", testing::kBasicRapporEncodingConfigId, 100,
                    MakeProfile("bar"));
    AddObservations("Cantaloupe", testing::kBasicRapporEncodingConfigId, 150,
                    MakeProfile("foo"));
    AddObservations("Cantaloupe", testing::kBasicRapporEncodingConfigId, 150,
                    MakeProfile("bar"));
  }

  void AddUnencodedObservations() {
    AddObservations("Apple", testing::kNoOpEncodingConfigId, 1);
    AddObservations("Banana", testing::kNoOpEncodingConfigId, 2);
    AddObservations("Cantaloupe", testing::kNoOpEncodingConfigId, 3);
  }

  void AddGroupedUnencodedObservations() {
    AddObservations("Apple", testing::kNoOpEncodingConfigId, 1,
                    MakeProfile("foo"));
    AddObservations("Apple", testing::kNoOpEncodingConfigId, 1,
                    MakeProfile("bar"));
    AddObservations("Banana", testing::kNoOpEncodingConfigId, 2,
                    MakeProfile("foo"));
    AddObservations("Banana", testing::kNoOpEncodingConfigId, 2,
                    MakeProfile("bar"));
    AddObservations("Cantaloupe", testing::kNoOpEncodingConfigId, 3,
                    MakeProfile("foo"));
    AddObservations("Cantaloupe", testing::kNoOpEncodingConfigId, 3,
                    MakeProfile("bar"));
  }

  // This method should be invoked after invoking AddBasicRapporObservations()
  // and then GenerateReport. It checks the generated Report to make sure
  // it is correct given the Observations that were added. We are not attempting
  // to validate the Basic RAPPOR algorithm here so we simply test that the
  // all three strings appear with a non-zero count and under the correct
  // variable index.
  void CheckBasicRapporReport(const GeneratedReport& report,
                              uint variable_index) {
    EXPECT_EQ(HISTOGRAM, report.metadata.report_type());
    EXPECT_EQ(1, report.metadata.variable_indices_size());
    EXPECT_EQ(variable_index, report.metadata.variable_indices(0));
    if (report.metadata.in_store()) {
      EXPECT_EQ(3, report.rows.rows_size());
      for (const auto& report_row : report.rows.rows()) {
        EXPECT_NE(0, report_row.histogram().std_error());
        ValuePart recovered_value;
        EXPECT_TRUE(report_row.histogram().has_value());
        recovered_value = report_row.histogram().value();
        break;

        EXPECT_EQ(ValuePart::kStringValue, recovered_value.data_case());
        std::string string_value = recovered_value.string_value();
        EXPECT_TRUE(string_value == "Apple" || string_value == "Banana" ||
                    string_value == "Cantaloupe");

        EXPECT_GT(report_row.histogram().count_estimate(), 0);
      }
    } else {
      EXPECT_EQ(0, report.rows.rows_size());
    }
    if (report.metadata.export_name() == "") {
      EXPECT_FALSE(this->fake_uploader_->upload_was_invoked);
    } else {
      EXPECT_TRUE(this->fake_uploader_->upload_was_invoked);
      // Reset for next time
      this->fake_uploader_->upload_was_invoked = false;
      EXPECT_EQ("BUCKET-NAME", fake_uploader_->bucket);
      EXPECT_EQ("1_1_1/export_name.csv", fake_uploader_->path);
      EXPECT_EQ("text/csv", fake_uploader_->mime_type);
      EXPECT_FALSE(fake_uploader_->serialized_report.empty());
    }
  }

  void CheckGroupedRapporReport(const GeneratedReport& report,
                                uint variable_index) {
    EXPECT_EQ(HISTOGRAM, report.metadata.report_type());
    EXPECT_EQ(1, report.metadata.variable_indices_size());
    EXPECT_EQ(variable_index, report.metadata.variable_indices(0));
    int foo_count = 0;
    int bar_count = 0;
    if (report.metadata.in_store()) {
      EXPECT_EQ(6, report.rows.rows_size());
      for (const auto& report_row : report.rows.rows()) {
        EXPECT_NE(0, report_row.histogram().std_error());
        EXPECT_TRUE(report_row.histogram().has_value());
        std::string board_name =
            report_row.histogram().system_profile().board_name();
        if (board_name == "foo") foo_count += 1;
        if (board_name == "bar") bar_count += 1;
      }
      EXPECT_EQ(3, foo_count);
      EXPECT_EQ(3, bar_count);
    } else {
      EXPECT_EQ(0, report.rows.rows_size());
    }
    if (report.metadata.export_name() == "") {
      EXPECT_FALSE(this->fake_uploader_->upload_was_invoked);
    } else {
      EXPECT_TRUE(this->fake_uploader_->upload_was_invoked);
      this->fake_uploader_->upload_was_invoked = false;
      EXPECT_EQ("BUCKET-NAME", fake_uploader_->bucket);
      EXPECT_EQ("1_1_3/export_name.csv", fake_uploader_->path);
      EXPECT_EQ("text/csv", fake_uploader_->mime_type);
      EXPECT_FALSE(fake_uploader_->serialized_report.empty());
    }
  }

  void CheckRawDumpReport(const GeneratedReport& report) {
    EXPECT_EQ(RAW_DUMP, report.metadata.report_type());
    EXPECT_EQ(2, report.metadata.variable_indices_size());
    EXPECT_EQ(0u, report.metadata.variable_indices(0));
    EXPECT_EQ(1u, report.metadata.variable_indices(1));
    if (report.metadata.in_store()) {
      EXPECT_EQ(6, report.rows.rows_size());
    } else {
      EXPECT_EQ(0, report.rows.rows_size());
    }
    if (report.metadata.export_name() == "") {
      EXPECT_FALSE(this->fake_uploader_->upload_was_invoked);
    } else {
      EXPECT_TRUE(this->fake_uploader_->upload_was_invoked);
      // Reset for next time
      this->fake_uploader_->upload_was_invoked = false;
      EXPECT_EQ("BUCKET-NAME", fake_uploader_->bucket);
      EXPECT_EQ("1_1_1/export_name.csv", fake_uploader_->path);
      EXPECT_EQ("text/csv", fake_uploader_->mime_type);
      // Take the export CSV file and split it into lines.
      std::stringstream csv_stream(fake_uploader_->serialized_report);
      std::vector<std::string> csv_lines;
      std::string line;
      while (std::getline(csv_stream, line)) {
        csv_lines.push_back(line);
      }
      EXPECT_EQ(7u, csv_lines.size());
      // Check the header line.
      EXPECT_EQ("date,Part1,Part2", csv_lines[0]);
      // Check the body of the report. They are in random order so we
      // need to count them and check the totals.
      size_t apple_lines = 0;
      size_t banana_lines = 0;
      size_t cantaloupe_lines = 0;
      for (auto i = 1ul; i < csv_lines.size(); i++) {
        if (csv_lines[i] == "2016-12-2,\"Apple\",\"Apple\"") {
          apple_lines++;
        } else if (csv_lines[i] == "2016-12-2,\"Banana\",\"Banana\"") {
          banana_lines++;
        } else if (csv_lines[i] == "2016-12-2,\"Cantaloupe\",\"Cantaloupe\"") {
          cantaloupe_lines++;
        }
      }
      EXPECT_EQ(1u, apple_lines);
      EXPECT_EQ(2u, banana_lines);
      EXPECT_EQ(3u, cantaloupe_lines);
    }
  }

  void CheckGroupedRawDumpReport(const GeneratedReport& report) {
    EXPECT_EQ(RAW_DUMP, report.metadata.report_type());
    EXPECT_EQ(2, report.metadata.variable_indices_size());
    EXPECT_EQ(0u, report.metadata.variable_indices(0));
    EXPECT_EQ(1u, report.metadata.variable_indices(1));
    if (report.metadata.in_store()) {
      EXPECT_EQ(6, report.rows.rows_size());
    } else {
      EXPECT_EQ(0, report.rows.rows_size());
    }
    if (report.metadata.export_name() == "") {
      EXPECT_FALSE(this->fake_uploader_->upload_was_invoked);
    } else {
      EXPECT_TRUE(this->fake_uploader_->upload_was_invoked);
      // Reset for next time
      this->fake_uploader_->upload_was_invoked = false;
      EXPECT_EQ("BUCKET-NAME", fake_uploader_->bucket);
      EXPECT_EQ("1_1_4/export_name.csv", fake_uploader_->path);
      EXPECT_EQ("text/csv", fake_uploader_->mime_type);
      LOG(INFO) << "COUNT OF ROWS: " << report.rows.rows_size();
      for (const auto& row : report.rows.rows()) {
        LOG(INFO) << row.raw_dump().system_profile().board_name();
      }
      // Take the export CSV file and split it into lines.
      std::stringstream csv_stream(fake_uploader_->serialized_report);
      std::vector<std::string> csv_lines;
      std::string line;
      while (std::getline(csv_stream, line)) {
        csv_lines.push_back(line);
      }
      EXPECT_EQ(13u, csv_lines.size());
      // Check the header line.
      EXPECT_EQ("date,Part1,Part2,Board_Name", csv_lines[0]);
      // Check the body of the report. They are in random order so we
      // need to count them and check the totals.
      size_t apple_foo_lines = 0;
      size_t banana_foo_lines = 0;
      size_t cantaloupe_foo_lines = 0;
      size_t apple_bar_lines = 0;
      size_t banana_bar_lines = 0;
      size_t cantaloupe_bar_lines = 0;
      for (auto i = 1ul; i < csv_lines.size(); i++) {
        LOG(INFO) << csv_lines[i];
        if (csv_lines[i] == "2016-12-2,\"Apple\",\"Apple\",\"foo\"") {
          apple_foo_lines++;
        } else if (csv_lines[i] == "2016-12-2,\"Banana\",\"Banana\",\"foo\"") {
          banana_foo_lines++;
        } else if (csv_lines[i] ==
                   "2016-12-2,\"Cantaloupe\",\"Cantaloupe\",\"foo\"") {
          cantaloupe_foo_lines++;
        } else if (csv_lines[i] == "2016-12-2,\"Apple\",\"Apple\",\"bar\"") {
          apple_bar_lines++;
        } else if (csv_lines[i] == "2016-12-2,\"Banana\",\"Banana\",\"bar\"") {
          banana_bar_lines++;
        } else if (csv_lines[i] ==
                   "2016-12-2,\"Cantaloupe\",\"Cantaloupe\",\"bar\"") {
          cantaloupe_bar_lines++;
        }
      }
      EXPECT_EQ(1u, apple_foo_lines);
      EXPECT_EQ(2u, banana_foo_lines);
      EXPECT_EQ(3u, cantaloupe_foo_lines);
      EXPECT_EQ(1u, apple_bar_lines);
      EXPECT_EQ(2u, banana_bar_lines);
      EXPECT_EQ(3u, cantaloupe_bar_lines);
    }
  }

  ReportId report_id_;
  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<ReportGenerator> report_generator_;
  std::shared_ptr<testing::FakeGcsUploader> fake_uploader_;
};

TYPED_TEST_CASE_P(ReportGeneratorAbstractTest);

// Tests that the ReportGenerator correctly generates a report for both
// variables of our two-variable metric when the ObservationStore has been
// filled with Observations of that metric that use our Forculus encoding.
// Note that *joint* reports have not yet been implemented.
TYPED_TEST_P(ReportGeneratorAbstractTest, Forculus) {
  this->AddForculusObservations();
  {
    SCOPED_TRACE("variable_index = 0");
    int variable_index = 0;
    // Don't export the report. Do store it to the store.
    bool in_store = true;
    auto report =
        this->GenerateHistogramReport(variable_index, false, in_store);
    this->CheckForculusReport(report, variable_index, "");
  }
  {
    SCOPED_TRACE("variable_index = 1");
    int variable_index = 1;
    // Do export the report. Do store it to the store.
    bool in_store = true;
    auto report = this->GenerateHistogramReport(variable_index, true, in_store);
    this->CheckForculusReport(report, variable_index,
                              this->kExpectedPart2ForculusCSV);
  }
  {
    SCOPED_TRACE("variable_index = 0");
    int variable_index = 0;
    // Don't export the report. Don't store it to the store.
    bool in_store = false;
    auto report =
        this->GenerateHistogramReport(variable_index, false, in_store);
    this->CheckForculusReport(report, variable_index, "");
  }
  {
    SCOPED_TRACE("variable_index = 1");
    int variable_index = 1;
    // Do export the report. Don't store it to the store.
    bool in_store = false;
    auto report = this->GenerateHistogramReport(variable_index, true, in_store);
    this->CheckForculusReport(report, variable_index,
                              this->kExpectedPart2ForculusCSV);
  }
}

// Tests that the ReportGenerator correctly generates a report for both
// variables of our two-variable metric when the ObservationStore has been
// filled with Observations of that metric that use our Basic RAPPOR encoding.
// Note that *joint* reports have not yet been implemented.
TYPED_TEST_P(ReportGeneratorAbstractTest, BasicRappor) {
  this->AddBasicRapporObservations();
  {
    SCOPED_TRACE("variable_index = 0");
    int variable_index = 0;
    // Do exort the report. Do store it to the store.
    bool in_store = true;
    auto report = this->GenerateHistogramReport(variable_index, true, in_store);
    this->CheckBasicRapporReport(report, variable_index);
  }
  {
    SCOPED_TRACE("variable_index = 1");
    int variable_index = 1;
    // Don't export the report. Do store it to the store.
    bool in_store = true;
    auto report =
        this->GenerateHistogramReport(variable_index, false, in_store);
    this->CheckBasicRapporReport(report, variable_index);
  }
}

TYPED_TEST_P(ReportGeneratorAbstractTest, GroupedBasicRappor) {
  this->AddGroupedBasicRapporObservations();
  {
    SCOPED_TRACE("variable_index = 0");
    int variable_index = 0;
    // Don't export the report. Do store it to the store.
    bool in_store = true;
    auto report =
        this->GenerateGroupedHistogramReport(variable_index, true, in_store);
    this->CheckGroupedRapporReport(report, variable_index);
  }
  {
    SCOPED_TRACE("variable_index = 1");
    int variable_index = 1;
    // Don't export the report. Do store it to the store.
    bool in_store = true;
    auto report =
        this->GenerateGroupedHistogramReport(variable_index, true, in_store);
    this->CheckGroupedRapporReport(report, variable_index);
  }
}

TYPED_TEST_P(ReportGeneratorAbstractTest, RawDump) {
  this->AddUnencodedObservations();
  // Do exort the report. Don't store it to the store.
  bool in_store = false;
  auto report = this->GenerateRawDumpReport(true, in_store);
  this->CheckRawDumpReport(report);
}

TYPED_TEST_P(ReportGeneratorAbstractTest, GroupedRawDump) {
  this->AddGroupedUnencodedObservations();
  // Do exort the report. Don't store it to the store.
  bool in_store = false;
  auto report = this->GenerateGroupedRawDumpReport(true, in_store);
  this->CheckGroupedRawDumpReport(report);
}

REGISTER_TYPED_TEST_CASE_P(ReportGeneratorAbstractTest, Forculus, BasicRappor,
                           RawDump, GroupedBasicRappor, GroupedRawDump);

}  // namespace analyzer
}  // namespace cobalt

#endif  // COBALT_ANALYZER_REPORT_MASTER_REPORT_GENERATOR_ABSTRACT_TEST_H_
