// Copyright 2020 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/pb/metadata_builder.h"

#include <chrono>
#include <memory>

#include <gtest/gtest.h>

#include "absl/strings/str_cat.h"
#include "src/lib/util/clock.h"
#include "src/lib/util/datetime_util.h"
#include "src/lib/util/posix_file_system.h"
#include "src/lib/util/testing/test_posix_file_system.h"
#include "src/lib/util/testing/test_with_files.h"
#include "src/logger/project_context.h"
#include "src/logging.h"
#include "src/registry/metric_definition.pb.h"
#include "src/registry/report_definition.pb.h"
#include "src/system_data/fake_system_data.h"

namespace cobalt {

class MetadataBuilderTest : public util::testing::TestWithFiles {
 public:
  void SetUp() override {
    util::testing::TestWithFiles::SetUp();

    system_clock_ = std::make_unique<util::IncrementingSystemClock>();
    system_clock_->set_increment(std::chrono::hours(1));
    test_clock_ = std::make_unique<util::FakeValidatedClock>(system_clock_.get());
    test_clock_->SetAccurate(true);

    SetupBuilder();
  }

  void SetupBuilder() {
    system_data_ = std::make_unique<system_data::FakeSystemData>();
    builder_ = std::make_unique<MetadataBuilder>(*system_data_, test_clock_.get(),
                                                 system_data_cache_path(), fs());
  }

  std::unique_ptr<ObservationMetadata> BuildForHour(const logger::MetricRef &metric,
                                                    const ReportDefinition &report,
                                                    uint32_t hour_id) {
    return builder_->Build(metric, report, util::TimeInfo::FromHourId(hour_id));
  }

  std::unique_ptr<ObservationMetadata> BuildForDay(const logger::MetricRef &metric,
                                                   const ReportDefinition &report,
                                                   uint32_t day_index) {
    return builder_->Build(metric, report, util::TimeInfo::FromDayIndex(day_index));
  }

 protected:
  std::unique_ptr<system_data::FakeSystemData> system_data_;
  std::unique_ptr<util::IncrementingSystemClock> system_clock_;
  std::unique_ptr<util::FakeValidatedClock> test_clock_;

  std::unique_ptr<MetadataBuilder> builder_;
};

TEST(MetadataBuilder, CanBeConstructedWithEmptySystemDataCachePath) {
  std::unique_ptr<util::IncrementingSystemClock> system_clock =
      std::make_unique<util::IncrementingSystemClock>();
  system_clock->set_increment(std::chrono::hours(1));
  std::unique_ptr<util::FakeValidatedClock> test_clock =
      std::make_unique<util::FakeValidatedClock>(system_clock.get());
  test_clock->SetAccurate(true);
  std::unique_ptr<system_data::FakeSystemData> system_data =
      std::make_unique<system_data::FakeSystemData>();
  util::PosixFileSystem fs;
  MetadataBuilder builder(*system_data, test_clock.get(), "", fs);
}

TEST_F(MetadataBuilderTest, FiltersAsExpected) {
  const auto kCustomerId = 12;
  const auto kProjectId = 34;
  const auto kMetricId = 56;
  const auto kReportId = 78;

  Project proj;
  proj.set_customer_id(kCustomerId);
  proj.set_project_id(kProjectId);

  MetricDefinition metric;
  metric.set_id(kMetricId);
  metric.set_time_zone_policy(MetricDefinition::UTC);

  ReportDefinition report;
  report.set_id(kReportId);
  report.add_experiment_id(2);
  report.add_system_profile_field(SystemProfileField::BOARD_NAME);
  report.add_system_profile_field(SystemProfileField::PRODUCT_NAME);
  report.add_system_profile_field(SystemProfileField::CHANNEL);
  report.add_system_profile_field(SystemProfileField::EXPERIMENT_IDS);
  report.add_system_profile_field(SystemProfileField::EXPERIMENT_TOKENS);

  logger::MetricRef metric_ref(&proj, &metric);
  auto metadata = BuildForDay(metric_ref, report, 0);
  EXPECT_EQ(metadata->customer_id(), kCustomerId);
  EXPECT_EQ(metadata->project_id(), kProjectId);
  EXPECT_EQ(metadata->metric_id(), kMetricId);
  EXPECT_EQ(metadata->report_id(), kReportId);

  // These fields should match, since they were selected.
  EXPECT_EQ(metadata->system_profile().board_name(), system_data_->system_profile().board_name());
  EXPECT_EQ(metadata->system_profile().product_name(),
            system_data_->system_profile().product_name());
  EXPECT_EQ(metadata->system_profile().channel(), system_data_->channel());

  // Only the one experiment ID listed in the report should be included.
  ASSERT_EQ(metadata->system_profile().experiment_ids_size(), 1);
  EXPECT_EQ(metadata->system_profile().experiment_ids(0), 2);

  ASSERT_EQ(metadata->system_profile().experiment_tokens_size(),
            system_data_->system_profile().experiment_tokens_size());
  for (int i = 0; i < metadata->system_profile().experiment_tokens_size(); ++i) {
    EXPECT_EQ(metadata->system_profile().experiment_tokens(i).ns(),
              system_data_->system_profile().experiment_tokens(i).ns());
    EXPECT_EQ(metadata->system_profile().experiment_tokens(i).token(),
              system_data_->system_profile().experiment_tokens(i).token());
  }

  // These fields should not match.
  EXPECT_NE(metadata->system_profile().os(), system_data_->system_profile().os());
  EXPECT_NE(metadata->system_profile().arch(), system_data_->system_profile().arch());
  EXPECT_NE(metadata->system_profile().realm(), system_data_->system_profile().realm());
}

TEST_F(MetadataBuilderTest, CollectsAsExpected) {
  Project proj;
  MetricDefinition metric;
  metric.set_time_zone_policy(MetricDefinition::UTC);
  ReportDefinition report;
  report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_FIRST);
  report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY);
  report.add_system_profile_field(SystemProfileField::SYSTEM_VERSION);
  for (int i = 0; i < 24 * 7; i++) {
    system_data_->SetVersion(absl::StrCat("Version ", i + 1));
  }

  logger::MetricRef metric_ref(&proj, &metric);
  auto metadata = BuildForDay(metric_ref, report, 0);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 1");

  metadata = BuildForDay(metric_ref, report, 1);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 24");

  metadata = BuildForDay(metric_ref, report, 2);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 48");

  report.set_local_aggregation_period(WindowSize::WINDOW_7_DAYS);
  metadata = BuildForDay(metric_ref, report, 6);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 1");

  report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_LAST);
  metadata = BuildForDay(metric_ref, report, 0);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 23");

  metadata = BuildForDay(metric_ref, report, 1);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 47");
}

TEST_F(MetadataBuilderTest, CleanupWorks) {
  Project proj;
  MetricDefinition metric;
  metric.set_time_zone_policy(MetricDefinition::UTC);
  ReportDefinition report;
  report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_FIRST);
  report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY);
  report.add_system_profile_field(SystemProfileField::SYSTEM_VERSION);
  for (int i = 0; i < 24 * 7; i++) {
    system_data_->SetVersion(absl::StrCat("Version ", i + 1));
  }

  system_data_->SetVersion("Default Version");

  logger::MetricRef metric_ref(&proj, &metric);
  auto metadata = BuildForDay(metric_ref, report, 0);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 1");

  metadata = BuildForDay(metric_ref, report, 1);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 24");

  metadata = BuildForDay(metric_ref, report, 2);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 48");

  report.set_local_aggregation_period(WindowSize::WINDOW_7_DAYS);
  metadata = BuildForDay(metric_ref, report, 6);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 1");

  builder_->CleanupBefore(std::chrono::hours(4 * 24));

  report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY);
  metadata = BuildForDay(metric_ref, report, 2);
  EXPECT_EQ(metadata->system_profile().system_version(), "Default Version");

  report.set_local_aggregation_period(WindowSize::WINDOW_7_DAYS);
  metadata = BuildForDay(metric_ref, report, 6);
  EXPECT_EQ(metadata->system_profile().system_version(), "Default Version");

  report.set_local_aggregation_period(WindowSize::WINDOW_1_DAY);
  metadata = BuildForDay(metric_ref, report, 6);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 144");
}

TEST_F(MetadataBuilderTest, RestoresOnRestart) {
  Project proj;
  MetricDefinition metric;
  metric.set_time_zone_policy(MetricDefinition::UTC);
  ReportDefinition report;
  report.set_report_type(ReportDefinition::FLEETWIDE_OCCURRENCE_COUNTS);
  report.set_system_profile_selection(SystemProfileSelectionPolicy::SELECT_FIRST);
  report.add_system_profile_field(SystemProfileField::SYSTEM_VERSION);

  for (int i = 1; i <= 5; i += 2) {
    system_data_->SetVersion(absl::StrCat("Version ", i));
  }

  SetupBuilder();
  system_data_->SetVersion("Default Version");

  logger::MetricRef metric_ref(&proj, &metric);
  auto metadata = BuildForHour(metric_ref, report, 3);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 1");

  metadata = BuildForHour(metric_ref, report, 5);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 3");

  metadata = BuildForHour(metric_ref, report, 7);
  EXPECT_EQ(metadata->system_profile().system_version(), "Version 5");

  metadata = BuildForHour(metric_ref, report, 9);
  EXPECT_EQ(metadata->system_profile().system_version(), "Default Version");
}

}  // namespace cobalt
