// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "src/logger/encoder.h"

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

#include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h>

#include "src/lib/util/testing/test_with_files.h"
#include "src/local_aggregation/aggregation_utils.h"
#include "src/logger/project_context.h"
#include "src/logger/project_context_factory.h"
#include "src/logger/status.h"
#include "src/logger/test_registries/encoder_test_registry.cb.h"
#include "src/logging.h"
#include "src/pb/common.pb.h"
#include "src/pb/metadata_builder.h"
#include "src/pb/observation.pb.h"
#include "src/pb/observation_batch.pb.h"
#include "src/registry/packed_event_codes.h"
#include "src/system_data/fake_system_data.h"
#include "third_party/abseil-cpp/absl/strings/escaping.h"

namespace cobalt {

using google::protobuf::RepeatedPtrField;
using local_aggregation::MakeDayWindow;
using local_aggregation::MakeHourWindow;
using system_data::ClientSecret;
using system_data::FakeSystemData;
using system_data::SystemDataInterface;

namespace logger {

namespace {

namespace registry = testing::encoder_test_registry;

constexpr uint32_t kCustomerId = 1;
constexpr uint32_t kProjectId = 1;
constexpr uint32_t kDayIndex = 111;
constexpr uint32_t kAggregationDays = 7;
constexpr uint32_t kValue = 314159;

bool PopulateCobaltRegistry(CobaltRegistry* cobalt_registry) {
  std::string cobalt_registry_bytes;
  if (!absl::Base64Unescape(registry::kCobaltRegistryBase64, &cobalt_registry_bytes)) {
    return false;
  }
  return cobalt_registry->ParseFromString(cobalt_registry_bytes);
}

HistogramPtr NewHistogram(std::vector<uint32_t> indices, std::vector<uint32_t> counts) {
  CHECK(indices.size() == counts.size());
  HistogramPtr histogram = std::make_unique<RepeatedPtrField<HistogramBucket>>();
  for (auto i = 0u; i < indices.size(); i++) {
    auto* bucket = histogram->Add();
    bucket->set_index(indices[i]);
    bucket->set_count(counts[i]);
  }
  return histogram;
}

EventValuesPtr NewCustomEvent(std::vector<std::string> dimension_names,
                              std::vector<CustomDimensionValue> values) {
  CHECK(dimension_names.size() == values.size());
  EventValuesPtr custom_event =
      std::make_unique<google::protobuf::Map<std::string, CustomDimensionValue>>();
  for (auto i = 0u; i < values.size(); i++) {
    (*custom_event)[dimension_names[i]] = values[i];
  }
  return custom_event;
}

void CheckSystemProfile(const Encoder::Result& result, SystemProfile::OS expected_os,
                        SystemProfile::ARCH expected_arch, const std::string& expected_board_name,
                        const std::string& expected_product, const std::string& expected_channel,
                        const std::string& expected_realm) {
  EXPECT_TRUE(result.metadata->has_system_profile());
  EXPECT_EQ(expected_os, result.metadata->system_profile().os());
  EXPECT_EQ(expected_arch, result.metadata->system_profile().arch());
  EXPECT_EQ(expected_board_name, result.metadata->system_profile().board_name());
  EXPECT_EQ(expected_product, result.metadata->system_profile().product_name());
  EXPECT_EQ(expected_channel, result.metadata->system_profile().channel());
  EXPECT_EQ(expected_realm, result.metadata->system_profile().realm());
}

void CheckResult(const Encoder::Result& result, uint32_t expected_metric_id,
                 uint32_t expected_report_id, uint32_t expected_day_index) {
  EXPECT_EQ(kOK, result.status);
  EXPECT_EQ(kCustomerId, result.metadata->customer_id());
  EXPECT_EQ(kProjectId, result.metadata->project_id());
  EXPECT_EQ(expected_metric_id, result.metadata->metric_id());
  EXPECT_EQ(expected_report_id, result.metadata->report_id());
  EXPECT_EQ(expected_day_index, result.metadata->day_index());
}

}  // namespace

class EncoderTest : public util::testing::TestWithFiles {
 protected:
  void SetUp() override {
    MakeTestFolder();

    auto cobalt_registry = std::make_unique<CobaltRegistry>();
    ASSERT_TRUE(PopulateCobaltRegistry(cobalt_registry.get()));
    ProjectContextFactory project_context_factory(std::move(cobalt_registry));
    ASSERT_TRUE(project_context_factory.is_single_project());
    project_context_ = project_context_factory.TakeSingleProjectContext();
    system_data_ = std::make_unique<FakeSystemData>();
    metadata_builder_ =
        std::make_unique<MetadataBuilder>(system_data_.get(), system_data_cache_path(), fs());
    encoder_ =
        std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), metadata_builder_.get());
  }

  std::pair<const MetricDefinition*, const ReportDefinition*> GetMetricAndReport(
      const std::string& metric_name, const std::string& report_name) {
    const auto* metric = project_context_->GetMetric(metric_name);
    CHECK(metric) << "No such metric: " << metric_name;
    const ReportDefinition* report = nullptr;
    for (const auto& rept : metric->reports()) {
      if (rept.report_name() == report_name) {
        report = &rept;
        break;
      }
    }
    CHECK(report) << "No such report: " << report_name;
    return {metric, report};
  }

  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<ProjectContext> project_context_;

 private:
  std::unique_ptr<SystemDataInterface> system_data_;
};

TEST_F(EncoderTest, EncodeBasicRapporObservation) {
  const char kMetricName[] = "ErrorOccurred";
  const char kReportName[] = "ErrorCountsByType";
  const uint32_t kExpectedMetricId = 1;

  auto pair = GetMetricAndReport(kMetricName, kReportName);
  const uint32_t day_index = 111;
  {
    const uint32_t value_index = 9;
    const uint32_t num_categories = 8;
    // This should fail with kInvalidArguments because 9 > 8.
    auto result =
        encoder_->EncodeBasicRapporObservation(project_context_->RefMetric(pair.first), pair.second,
                                               day_index, value_index, num_categories);
    EXPECT_EQ(kInvalidArguments, result.status);
  }

  {
    // This should fail with kInvalidConfig because num_categories is too large.
    const uint32_t value_index = 9;
    const uint32_t num_categories = 999999;
    auto result =
        encoder_->EncodeBasicRapporObservation(project_context_->RefMetric(pair.first), pair.second,
                                               day_index, value_index, num_categories);
    EXPECT_EQ(kInvalidConfig, result.status);
  }

  {
    // If we use the wrong report, it won't have local_privacy_noise_level
    // set and we should get InvalidConfig
    const uint32_t num_categories = 128;
    const uint32_t value_index = 10;
    pair = GetMetricAndReport("ReadCacheHits", "ReadCacheHitCounts");
    auto result =
        encoder_->EncodeBasicRapporObservation(project_context_->RefMetric(pair.first), pair.second,
                                               day_index, value_index, num_categories);
    EXPECT_EQ(kInvalidConfig, result.status);

    // Finally we pass all valid parameters and the operation should succeed.
    pair = GetMetricAndReport(kMetricName, kReportName);
    result =
        encoder_->EncodeBasicRapporObservation(project_context_->RefMetric(pair.first), pair.second,
                                               day_index, value_index, num_categories);
    CheckResult(result, kExpectedMetricId, registry::kErrorOccurredErrorCountsByTypeReportId,
                day_index);
    CheckSystemProfile(result, SystemProfile::UNKNOWN_OS, SystemProfile::UNKNOWN_ARCH,
                       "Testing Board", "Testing Product", "Testing Channel", "Testing Realm");
    ASSERT_TRUE(result.observation->has_basic_rappor());
    EXPECT_FALSE(result.observation->basic_rappor().data().empty());
  }
}

TEST_F(EncoderTest, EncodeIntegerEventObservation) {
  const char kMetricName[] = "ReadCacheHits";
  const char kReportName[] = "ReadCacheHitCounts";
  const uint32_t kExpectedMetricId = 2;
  const char kComponent[] = "My Component";
  const uint32_t kEventCode = 9;
  google::protobuf::RepeatedField<uint32_t> event_codes;
  *event_codes.Add() = kEventCode;

  auto pair = GetMetricAndReport(kMetricName, kReportName);
  auto result =
      encoder_->EncodeIntegerEventObservation(project_context_->RefMetric(pair.first), pair.second,
                                              kDayIndex, event_codes, kComponent, kValue);
  CheckResult(result, kExpectedMetricId, registry::kReadCacheHitsReadCacheHitCountsReportId,
              kDayIndex);
  // In the SystemProfile only the OS should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::UNKNOWN_ARCH, "", "", "", "");
  ASSERT_TRUE(result.observation->has_numeric_event());
  const IntegerEventObservation& obs = result.observation->numeric_event();
  EXPECT_EQ(kEventCode, obs.event_code());
  EXPECT_EQ(obs.component_name_hash().size(), 32u);
  EXPECT_EQ(kValue, obs.value());
}

TEST_F(EncoderTest, MultipleEventCodes) {
  const char kMetricName[] = "MultiEventCodeTest";
  const char kReportName[] = "MultiEventCodeCounts";
  const uint32_t kExpectedMetricId = 11;
  const char kComponent[] = "My Component";
  const uint32_t kEventCode1 = 7;
  const uint32_t kEventCode2 = 5;
  google::protobuf::RepeatedField<uint32_t> event_codes;
  *event_codes.Add() = kEventCode1;
  *event_codes.Add() = kEventCode2;

  auto pair = GetMetricAndReport(kMetricName, kReportName);
  auto result =
      encoder_->EncodeIntegerEventObservation(project_context_->RefMetric(pair.first), pair.second,
                                              kDayIndex, event_codes, kComponent, kValue);
  CheckResult(result, kExpectedMetricId, registry::kMultiEventCodeTestMultiEventCodeCountsReportId,
              kDayIndex);
  // In the SystemProfile only the OS should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::UNKNOWN_ARCH, "", "", "", "");
  ASSERT_TRUE(result.observation->has_numeric_event());
  const IntegerEventObservation& obs = result.observation->numeric_event();
  auto codes = config::UnpackEventCodes(obs.event_code());
  EXPECT_EQ(kEventCode1, codes[0]);
  EXPECT_EQ(kEventCode2, codes[1]);
  EXPECT_EQ(obs.component_name_hash().size(), 32u);
  EXPECT_EQ(kValue, obs.value());
}

TEST_F(EncoderTest, EncodeHistogramObservation) {
  const char kMetricName[] = "FileSystemWriteTimes";
  const char kReportName[] = "FileSystemWriteTimes_Histogram";
  const uint32_t kExpectedMetricId = 6;
  const std::string kComponent;
  const uint32_t kEventCode = 9;
  google::protobuf::RepeatedField<uint32_t> event_codes;
  *event_codes.Add() = kEventCode;

  const std::vector<uint32_t> indices = {0, 1, 2};
  const std::vector<uint32_t> counts = {100, 200, 300};
  auto histogram = NewHistogram(indices, counts);
  auto pair = GetMetricAndReport(kMetricName, kReportName);
  auto result = encoder_->EncodeHistogramObservation(project_context_->RefMetric(pair.first),
                                                     pair.second, kDayIndex, event_codes,
                                                     kComponent, std::move(histogram));
  CheckResult(result, kExpectedMetricId,
              registry::kFileSystemWriteTimesFileSystemWriteTimesHistogramReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "", "");
  ASSERT_TRUE(result.observation->has_histogram());
  const HistogramObservation& obs = result.observation->histogram();
  EXPECT_EQ(kEventCode, obs.event_code());
  EXPECT_TRUE(obs.component_name_hash().empty());
  EXPECT_EQ(static_cast<size_t>(obs.buckets_size()), indices.size());
  for (auto i = 0u; i < indices.size(); i++) {
    const auto& bucket = obs.buckets(i);
    EXPECT_EQ(bucket.index(), indices[i]);
    EXPECT_EQ(bucket.count(), counts[i]);
  }
}

TEST_F(EncoderTest, EncodeCustomObservation) {
  const char kMetricName[] = "ModuleInstalls";
  const char kReportName[] = "ModuleInstalls_DetailedData";
  const uint32_t kExpectedMetricId = 8;

  CustomDimensionValue module_value, number_value;
  module_value.set_string_value("gmail");
  number_value.set_int_value(3);
  std::vector<std::string> dimension_names = {"module", "number"};
  std::vector<CustomDimensionValue> values = {module_value, number_value};
  auto custom_event = NewCustomEvent(dimension_names, values);
  auto pair = GetMetricAndReport(kMetricName, kReportName);

  auto result = encoder_->EncodeCustomObservation(project_context_->RefMetric(pair.first),
                                                  pair.second, kDayIndex, std::move(custom_event));
  CheckResult(result, kExpectedMetricId,
              registry::kModuleInstallsModuleInstallsDetailedDataReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "", "");
  ASSERT_TRUE(result.observation->has_custom());
  const CustomObservation& obs = result.observation->custom();
  for (auto i = 0u; i < values.size(); i++) {
    auto obs_dimension = obs.values().at(dimension_names[i]);
    EXPECT_EQ(obs_dimension.SerializeAsString(), values[i].SerializeAsString());
  }
}

TEST_F(EncoderTest, EncodeSerializedCustomObservation) {
  const char kMetricName[] = "ModuleInstalls";
  const char kReportName[] = "ModuleInstalls_DetailedData";
  const uint32_t kExpectedMetricId = 8;

  std::string serialized_proto = "serialized proto";
  auto serialized_proto_ptr = std::make_unique<std::string>(serialized_proto);
  auto pair = GetMetricAndReport(kMetricName, kReportName);

  auto result = encoder_->EncodeSerializedCustomObservation(project_context_->RefMetric(pair.first),
                                                            pair.second, kDayIndex,
                                                            std::move(serialized_proto_ptr));
  CheckResult(result, kExpectedMetricId,
              registry::kModuleInstallsModuleInstallsDetailedDataReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "", "");
  ASSERT_TRUE(result.observation->has_custom());
  const CustomObservation& obs = result.observation->custom();
  EXPECT_EQ(serialized_proto, obs.serialized_proto());
}

TEST_F(EncoderTest, EncodeUniqueActivesObservation) {
  const char kMetricName[] = "DeviceBoots";
  const char kReportName[] = "DeviceBoots_UniqueDevices";
  const uint32_t kExpectedMetricId = 9;
  const uint32_t kEventCode = 0;
  const int kAggregationHours = 1;
  auto pair = GetMetricAndReport(kMetricName, kReportName);

  // Encode a valid UniqueActivesObservation of activity for a 7-day window.
  auto result_active = encoder_->EncodeUniqueActivesObservation(
      project_context_->RefMetric(pair.first), pair.second, kDayIndex, kEventCode, true,
      MakeDayWindow(kAggregationDays));
  CheckResult(result_active, kExpectedMetricId,
              registry::kDeviceBootsDeviceBootsUniqueDevicesReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result_active, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "", "");
  ASSERT_TRUE(result_active.observation->has_unique_actives());
  auto active_obs = result_active.observation->unique_actives();
  ASSERT_EQ(OnDeviceAggregationWindow::kDays, active_obs.aggregation_window().units_case());
  EXPECT_EQ(kAggregationDays, active_obs.aggregation_window().days());
  EXPECT_EQ(kEventCode, active_obs.event_code());
  ASSERT_TRUE(active_obs.has_basic_rappor_obs());
  EXPECT_EQ(1u, active_obs.basic_rappor_obs().data().size());

  // Encode a valid UniqueActivesObservation of inactivity for a 1-hour window.
  auto result_inactive = encoder_->EncodeUniqueActivesObservation(
      project_context_->RefMetric(pair.first), pair.second, kDayIndex, kEventCode, false,
      MakeHourWindow(kAggregationHours));
  CheckResult(result_inactive, kExpectedMetricId,
              registry::kDeviceBootsDeviceBootsUniqueDevicesReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result_inactive, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "",
                     "");
  ASSERT_TRUE(result_inactive.observation->has_unique_actives());
  auto inactive_obs = result_inactive.observation->unique_actives();
  ASSERT_EQ(OnDeviceAggregationWindow::kHours, inactive_obs.aggregation_window().units_case());
  EXPECT_EQ(kAggregationHours, inactive_obs.aggregation_window().hours());
  EXPECT_EQ(kEventCode, inactive_obs.event_code());
  ASSERT_TRUE(inactive_obs.has_basic_rappor_obs());
  EXPECT_EQ(1u, inactive_obs.basic_rappor_obs().data().size());
}

TEST_F(EncoderTest, EncodePerDeviceNumericObservation) {
  const char kMetricName[] = "ConnectionFailures";
  const char kReportName[] = "ConnectionFailures_PerDeviceCount";
  const uint32_t kExpectedMetricId = 10;
  const char kComponent[] = "Some Component";
  const uint32_t kEventCode = 0;
  const int64_t kCount = 1728;
  auto pair = GetMetricAndReport(kMetricName, kReportName);

  google::protobuf::RepeatedField<uint32_t> event_codes;
  *event_codes.Add() = kEventCode;

  auto result = encoder_->EncodePerDeviceNumericObservation(
      project_context_->RefMetric(pair.first), pair.second, kDayIndex, kComponent, event_codes,
      kCount, MakeDayWindow(kAggregationDays));
  CheckResult(result, kExpectedMetricId,
              registry::kConnectionFailuresConnectionFailuresPerDeviceCountReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "", "");
  ASSERT_TRUE(result.observation->has_per_device_numeric());
  const auto& per_device_numeric_obs = result.observation->per_device_numeric();
  ASSERT_EQ(OnDeviceAggregationWindow::kDays,
            per_device_numeric_obs.aggregation_window().units_case());
  EXPECT_EQ(kAggregationDays, per_device_numeric_obs.aggregation_window().days());
  ASSERT_TRUE(per_device_numeric_obs.has_integer_event_obs());
  const auto& integer_obs = per_device_numeric_obs.integer_event_obs();
  EXPECT_EQ(kEventCode, integer_obs.event_code());
  EXPECT_EQ(32u, integer_obs.component_name_hash().size());
  EXPECT_EQ(kCount, integer_obs.value());
}

TEST_F(EncoderTest, EncodePerDeviceNumericHistogramObservation) {
  const char kMetricName[] = "ConnectionFailures";
  const char kReportName[] = "ConnectionFailures_PerDeviceHistogram";
  const uint32_t kExpectedMetricId = 10;
  const char kComponent[] = "Some Component";
  const uint32_t kEventCode = 0;
  const int64_t kCount = 41;
  const int64_t kExpectedBucket = 5;
  auto pair = GetMetricAndReport(kMetricName, kReportName);

  google::protobuf::RepeatedField<uint32_t> event_codes;
  *event_codes.Add() = kEventCode;

  auto result = encoder_->EncodePerDeviceHistogramObservation(
      project_context_->RefMetric(pair.first), pair.second, kDayIndex, kComponent, event_codes,
      kCount, MakeDayWindow(kAggregationDays));
  CheckResult(result, kExpectedMetricId,
              registry::kConnectionFailuresConnectionFailuresPerDeviceHistogramReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "", "");
  ASSERT_TRUE(result.observation->has_per_device_histogram());
  auto per_device_histogram_obs = result.observation->per_device_histogram();
  ASSERT_EQ(OnDeviceAggregationWindow::kDays,
            per_device_histogram_obs.aggregation_window().units_case());
  EXPECT_EQ(kAggregationDays, per_device_histogram_obs.aggregation_window().days());
  ASSERT_TRUE(result.observation->per_device_histogram().has_histogram());
  auto histogram = result.observation->per_device_histogram().histogram();
  EXPECT_EQ(kEventCode, histogram.event_code());
  EXPECT_EQ(32u, histogram.component_name_hash().size());
  EXPECT_EQ(1, histogram.buckets_size());
  EXPECT_EQ(kExpectedBucket, histogram.buckets(0).index());
  EXPECT_EQ(1, histogram.buckets(0).count());
}

TEST_F(EncoderTest, EncodeReportParticipationObservation) {
  const char kMetricName[] = "ConnectionFailures";
  const char kReportName[] = "ConnectionFailures_PerDeviceCount";
  const uint32_t kExpectedMetricId = 10;
  auto pair = GetMetricAndReport(kMetricName, kReportName);

  auto result = encoder_->EncodeReportParticipationObservation(
      project_context_->RefMetric(pair.first), pair.second, kDayIndex);
  CheckResult(result, kExpectedMetricId,
              registry::kConnectionFailuresConnectionFailuresPerDeviceCountReportId, kDayIndex);
  // In the SystemProfile only the OS and ARCH should be set.
  CheckSystemProfile(result, SystemProfile::FUCHSIA, SystemProfile::ARM_64, "", "", "", "");
  ASSERT_TRUE(result.observation->has_report_participation());
}

}  // namespace logger
}  // namespace cobalt
