// 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 <memory>
#include <utility>
#include <vector>

#include "config/config_text_parser.h"
#include "config/encoding_config.h"
#include "config/metric_config.h"
#include "config/report_config.h"
#include "third_party/googletest/googletest/include/gtest/gtest.h"

namespace cobalt {
namespace config {

using google::protobuf::io::ColumnNumber;
using google::protobuf::io::ErrorCollector;

class TestErrorCollector : public ErrorCollector {
 public:
  virtual ~TestErrorCollector() {}

  void AddError(int line, ColumnNumber column,
                const std::string& message) override {
    line_numbers_.push_back(line);
  }

  void AddWarning(int line, ColumnNumber column,
                  const std::string& message) override {
    line_numbers_.push_back(line);
  }

  const std::vector<int>& line_numbers() { return line_numbers_; }

  std::vector<int> line_numbers_;
};

// TODO(rudominer) The tests in this file find the text files to read using
// file paths that are expressed relative to the Cobalt source root directory.
// This technique works because when the tests are run via the Python script
// cobaltb.py then the current working directory is that root directory.
// This technique is fragile. We should instead pass the path to the root
// directory as a command-line argument into the test. Currently there is no
// Cobalt infrastructure for passing command-line arguments to unit tests.

// Tests EncodingRegistryFromFile<RegisteredEncodings>() when a bad file path is
// used.
TEST(EncodingRegistryFromFile, BadFilePath) {
  auto result = FromFile<RegisteredEncodings>("not a valid path", nullptr);
  EXPECT_EQ(kFileOpenError, result.second);
}

// Tests FromFile<RegisteredMetrics>() when a bad file path is used.
TEST(MetricRegistryFromFile, BadFilePath) {
  auto result = FromFile<RegisteredMetrics>("not a valid path", nullptr);
  EXPECT_EQ(kFileOpenError, result.second);
}

// Tests FromFile<RegisteredReports>() when a bad file path is used.
TEST(ReportRegistryFromFile, BadFilePath) {
  auto result = FromFile<RegisteredReports>("not a valid path", nullptr);
  EXPECT_EQ(kFileOpenError, result.second);
}

// Tests EncodingRegistryFromFile<RegisteredEncodings>() when a valid file path
// is used but the file is not a valid ASCII proto file.
TEST(EncodingRegistryFromFile, NotValidAsciiProtoFile) {
  TestErrorCollector collector;
  EXPECT_EQ(0u, collector.line_numbers().size());
  auto result =
      FromFile<RegisteredEncodings>("config/config_test.cc", &collector);
  EXPECT_EQ(kParsingError, result.second);
  EXPECT_EQ(1u, collector.line_numbers().size());
  EXPECT_EQ(0, collector.line_numbers()[0]);
}

// Tests FromFile<RegisteredMetrics>() when a valid file path is used but the
// file is not a valid ASCII proto file.
TEST(MetricRegistryFromFile, NotValidAsciiProtoFile) {
  TestErrorCollector collector;
  EXPECT_EQ(0u, collector.line_numbers().size());
  auto result =
      FromFile<RegisteredMetrics>("config/config_test.cc", &collector);
  EXPECT_EQ(kParsingError, result.second);
  EXPECT_EQ(1u, collector.line_numbers().size());
  EXPECT_EQ(0, collector.line_numbers()[0]);
}

// Tests FromFile<RegisteredReports>() when a valid file path is used but the
// file is not a valid ASCII proto file.
TEST(ReportRegistryFromFile, NotValidAsciiProtoFile) {
  TestErrorCollector collector;
  EXPECT_EQ(0u, collector.line_numbers().size());
  auto result =
      FromFile<RegisteredReports>("config/config_test.cc", &collector);
  EXPECT_EQ(kParsingError, result.second);
  EXPECT_EQ(1u, collector.line_numbers().size());
  EXPECT_EQ(0, collector.line_numbers()[0]);
}

// Tests EncodingRegistryFromFile<RegisteredEncodings>() when a valid ASCII
// proto file is read but there is a duplicate registration.
TEST(EncodingRegistryFromFile, DuplicateRegistration) {
  auto result = FromFile<RegisteredEncodings>(
      "config/test_files/registered_encodings_contains_duplicate.txt", nullptr);
  EXPECT_EQ(kDuplicateRegistration, result.second);
}

// Tests FromFile<RegisteredMetrics>() when a valid ASCII proto file is
// read but there is a duplicate registration.
TEST(MetricRegistryFromFile, DuplicateRegistration) {
  auto result = FromFile<RegisteredMetrics>(
      "config/test_files/registered_metrics_contains_duplicate.txt", nullptr);
  EXPECT_EQ(kDuplicateRegistration, result.second);
}

// Tests FromFile<RegisteredReports>() when a valid ASCII proto file is
// read but there is a duplicate registration.
TEST(ReportRegistryFromFile, DuplicateRegistration) {
  auto result = FromFile<RegisteredReports>(
      "config/test_files/registered_reports_contains_duplicate.txt", nullptr);
  EXPECT_EQ(kDuplicateRegistration, result.second);
}

// Tests EncodingRegistryFromFile<RegisteredEncodings>() on a fully valid file.
TEST(EncodingRegistryFromFile, ValidFile) {
  auto result = FromFile<RegisteredEncodings>(
      "config/test_files/registered_encodings_valid.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
  auto& registry = result.first;
  EXPECT_EQ(6u, registry->size());

  // (1, 1, 1) Should be Forculus 20
  auto* encoding_config = registry->Get(1, 1, 1);
  EXPECT_EQ(20u, encoding_config->forculus().threshold());

  // (1, 1, 2) Should be RAPPOR
  encoding_config = registry->Get(1, 1, 2);
  EXPECT_FLOAT_EQ(0.8, encoding_config->rappor().prob_1_stays_1());

  // (1, 1, 3) Should be Basic RAPPOR with integer categories
  encoding_config = registry->Get(1, 1, 3);
  int64_t num_categories =
      encoding_config->basic_rappor().int_range_categories().last() -
      encoding_config->basic_rappor().int_range_categories().first() + 1;
  EXPECT_EQ(3, num_categories);

  // (1, 1, 4) Should be Basic RAPPOR with indexed categories
  encoding_config = registry->Get(1, 1, 4);
  num_categories =
      encoding_config->basic_rappor().indexed_categories().num_categories();
  EXPECT_EQ(100, num_categories);

  // (1, 1, 5) Should be not present
  EXPECT_EQ(nullptr, registry->Get(1, 1, 5));

  // (2, 1, 1) Should be Basic RAPPOR with string categories
  encoding_config = registry->Get(2, 1, 1);
  EXPECT_EQ(
      3, encoding_config->basic_rappor().string_categories().category_size());
}

// Tests FromFile<RegisteredMetrics>() on a fully valid file.
TEST(MetricRegistryFromFile, ValidFile) {
  auto result = FromFile<RegisteredMetrics>(
      "config/test_files/registered_metrics_valid.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
  auto& registry = result.first;
  EXPECT_EQ(5u, registry->size());

  // (1, 1, 1) Should have 2 parts
  auto* metric_config = registry->Get(1, 1, 1);
  EXPECT_EQ(2, metric_config->parts_size());

  // (1, 1, 2) Should be "Fuschsia Usage by Hour"
  metric_config = registry->Get(1, 1, 2);
  EXPECT_EQ("Fuschsia Usage by Hour", metric_config->name());

  // (1, 1, 3) Should be "Fuschsia System Events"
  metric_config = registry->Get(1, 1, 3);
  EXPECT_EQ("Fuschsia System Events", metric_config->name());
  // There should be one part named "event" of type INDEX.
  EXPECT_EQ(MetricPart::INDEX, metric_config->parts().at("event").data_type());

  // (1, 1, 4) Should be not present
  EXPECT_EQ(nullptr, registry->Get(1, 1, 4));
}

// Tests FromFile<RegisteredReports>() on a fully valid file.
TEST(ReportRegistryFromFile, ValidFile) {
  auto result = FromFile<RegisteredReports>(
      "config/test_files/registered_reports_valid.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
  auto& registry = result.first;
  EXPECT_EQ(6u, registry->size());

  // (1, 1, 1) should have 2 variables
  auto* report_config = registry->Get(1, 1, 1);
  EXPECT_EQ(2, report_config->variable_size());

  // Examine the first varaible of (1, 1, 1)
  const auto& variable = report_config->variable(0);
  EXPECT_EQ(2, variable.rappor_candidates().candidates_size());
  EXPECT_EQ("San Francisco", variable.rappor_candidates().candidates(0));

  // (1, 1, 2) Should be "Fuschsia Usage by Hour"
  report_config = registry->Get(1, 1, 2);
  EXPECT_EQ("Fuschsia Usage by Hour", report_config->name());
  EXPECT_EQ("bucket-1", report_config->export_configs(0).gcs().bucket());

  // (1, 1, 3) Should be "Fuschsia Daily System Event Counts"
  report_config = registry->Get(1, 1, 3);
  EXPECT_EQ("Fuschsia Daily System Event Counts", report_config->name());

  // Examine the first varaible of (1, 1, 3)
  const auto& variable0 = report_config->variable(0);
  ASSERT_TRUE(variable0.has_index_labels());
  ASSERT_EQ(3, variable0.index_labels().labels_size());
  EXPECT_EQ("Event A", variable0.index_labels().labels().at(0));
  EXPECT_EQ("Event B", variable0.index_labels().labels().at(1));
  EXPECT_EQ("Event Z", variable0.index_labels().labels().at(25));

  // (1, 1, 5) Should be not present
  EXPECT_EQ(nullptr, registry->Get(1, 1, 5));
}

// This test runs EncodingRegistryFromFile<RegisteredEncodings>() on our demo
// file, registered_encodings.txt. The purpose is to validate that file.
TEST(EncodingRegistryFromFile, CheckDemoEncodings) {
  auto result = FromFile<RegisteredEncodings>(
      "config/demo/registered_encodings.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
}

// This test runs EncodingRegistryFromFile<RegisteredEncodings>() on our
// official registration file, registered_encodings.txt. The purpose is to
// validate that file.
TEST(EncodingRegistryFromFile, CheckProductionEncodings) {
  auto result = FromFile<RegisteredEncodings>(
      "config/production/registered_encodings.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
}

// This test runs FromFile<RegisteredMetrics>() on our demo
// file, registered_metrics.txt. The purpose is to validate that file.
TEST(MetricRegistryFromFile, CheckDemoMetrics) {
  auto result = FromFile<RegisteredMetrics>(
      "config/demo/registered_metrics.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
}

// This test runs FromFile<RegisteredMetrics>() on our official registration
// file, registered_metrics.txt. The purpose is to validate that file.
TEST(MetricRegistryFromFile, CheckProductionMetrics) {
  auto result = FromFile<RegisteredMetrics>(
      "config/production/registered_metrics.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
}

// This test runs FromFile<RegisteredReports>() on our demo
// file, registered_reports.txt. The purpose is to validate that file.
TEST(ReportRegistryFromFile, CheckDemodReports) {
  auto result = FromFile<RegisteredReports>(
      "config/demo/registered_reports.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
}

// This test runs FromFile<RegisteredReports>() on our official registration
// file, registered_reports.txt. The purpose is to validate that file.
TEST(ReportRegistryFromFile, CheckProductionReports) {
  auto result = FromFile<RegisteredReports>(
      "config/production/registered_reports.txt", nullptr);
  EXPECT_EQ(kOK, result.second);
}

//////////////  Tests of the FromString() functions. //////////////

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

# EncodingConfig 2 is String RAPPOR.
element {
  customer_id: 1
  project_id: 1
  id: 2
  rappor {
    num_bloom_bits: 8
    num_hashes: 2
    num_cohorts: 20
    prob_0_becomes_1: 0.25
    prob_1_stays_1: 0.75
  }
}
)";
TEST(EncodingRegistryFromString, ValidString) {
  auto result = FromString<RegisteredEncodings>(kEncodingConfigText, nullptr);
  EXPECT_EQ(kOK, result.second);
  auto& registry = result.first;
  EXPECT_EQ(2u, registry->size());
  // Test iteration.
  int count = 0;
  for (const EncodingConfig& encoding : *registry) {
    EXPECT_EQ(1u, encoding.customer_id());
    count++;
  }
  EXPECT_EQ(2, count);
}

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

# Metric 2 has one String part and one int part.
element {
  customer_id: 1
  project_id: 1
  id: 4
  parts {
    key: "city"
    value {
    }
  }
  parts {
    key: "rating"
    value {
      data_type: INT
    }
  }
}
)";
TEST(MetricRegistryFromString, ValidString) {
  auto result = FromString<RegisteredMetrics>(kMetricConfigText, nullptr);
  EXPECT_EQ(kOK, result.second);
  auto& registry = result.first;
  EXPECT_EQ(2u, registry->size());
  // Test iteration.
  int count = 0;
  for (const Metric& metric : *registry) {
    EXPECT_EQ(1u, metric.customer_id());
    count++;
  }
  EXPECT_EQ(2, count);
}

//////////////  Tests of the FromProto() functions. //////////////
// We reuse the strings used to test FromString.

TEST(EncodingRegistryFromProto, ValidProto) {
  RegisteredEncodings registered_encodings;
  google::protobuf::TextFormat::Parser parser;
  EXPECT_TRUE(
      parser.ParseFromString(kEncodingConfigText, &registered_encodings));

  auto result = EncodingRegistry::TakeFrom(&registered_encodings, nullptr);
  EXPECT_EQ(kOK, result.second);
  auto& registry = result.first;
  EXPECT_EQ(2u, registry->size());
  // Test iteration.
  int count = 0;
  for (const EncodingConfig& encoding : *registry) {
    EXPECT_EQ(1u, encoding.customer_id());
    count++;
  }
  EXPECT_EQ(2, count);
}

TEST(MetricsRegistryFromProto, ValidProto) {
  RegisteredMetrics registered_metrics;
  google::protobuf::TextFormat::Parser parser;
  EXPECT_TRUE(parser.ParseFromString(kMetricConfigText, &registered_metrics));

  auto result = MetricRegistry::TakeFrom(&registered_metrics, nullptr);
  EXPECT_EQ(kOK, result.second);
  auto& registry = result.first;
  EXPECT_EQ(2u, registry->size());
  // Test iteration.
  int count = 0;
  for (const Metric& metric : *registry) {
    EXPECT_EQ(1u, metric.customer_id());
    count++;
  }
  EXPECT_EQ(2, count);
}

}  // namespace config
}  // namespace cobalt
