// 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/local_aggregation_1_1/observation_generator.h"

#include <memory>

#include <gtest/gtest.h>

#include "absl/strings/escaping.h"
#include "src/algorithms/random/test_secure_random.h"
#include "src/lib/util/clock.h"
#include "src/lib/util/datetime_util.h"
#include "src/lib/util/hash.h"
#include "src/lib/util/testing/test_with_files.h"
#include "src/local_aggregation_1_1/aggregation_procedures/aggregation_procedure.h"
#include "src/local_aggregation_1_1/backfill_manager.h"
#include "src/local_aggregation_1_1/local_aggregate_storage/immediate_local_aggregate_storage.h"
#include "src/local_aggregation_1_1/local_aggregate_storage/local_aggregate_storage.h"
#include "src/local_aggregation_1_1/local_aggregation.pb.h"
#include "src/local_aggregation_1_1/testing/test_registry.cb.h"
#include "src/logger/fake_logger.h"
#include "src/logger/internal_metrics.h"
#include "src/logger/internal_metrics_config.cb.h"
#include "src/logger/observation_writer.h"
#include "src/logger/privacy_encoder.h"
#include "src/logger/project_context_factory.h"
#include "src/logger/types.h"
#include "src/observation_store/file_observation_store.h"
#include "src/observation_store/observation_store.h"
#include "src/observation_store/observation_store_internal.pb.h"
#include "src/pb/metadata_builder.h"
#include "src/pb/observation_batch.pb.h"
#include "src/public/lib/registry_identifiers.h"
#include "src/public/lib/status.h"
#include "src/public/lib/statusor/status_macros.h"
#include "src/registry/testing/testing.h"
#include "src/system_data/client_secret.h"
#include "src/system_data/fake_system_data.h"

namespace cobalt::local_aggregation {

using TimeInfo = util::TimeInfo;
using MetricAggregateRef = LocalAggregateStorage::MetricAggregateRef;

// The expected size in bytes of an Observation's |random_id| field.
constexpr size_t kRandomIdSize = 8u;

const lib::ProjectIdentifier kProjectIdentifier =
    lib::CustomerIdentifier(kCustomerId).ForProject(kProjectId);

namespace {

std::unique_ptr<CobaltRegistry> GetRegistry() {
  std::string bytes;
  if (!absl::Base64Unescape(kCobaltRegistryBase64, &bytes)) {
    LOG(ERROR) << "Unable to decode Base64 String";
    return nullptr;
  }

  auto registry = std::make_unique<CobaltRegistry>();
  if (!registry->ParseFromString(bytes)) {
    LOG(ERROR) << "Unable to parse registry from bytes";
    return nullptr;
  }

  return registry;
}

class FakePrivacyEncoder : public logger::PrivacyEncoder {
 public:
  explicit FakePrivacyEncoder(bool return_private_observations, int num_private_observations = 0)
      : PrivacyEncoder(std::make_unique<TestSecureRandomNumberGenerator>(0),
                       std::make_unique<RandomNumberGenerator>(0)),
        return_private_observations_(return_private_observations),
        num_private_observations_(num_private_observations) {}

  lib::statusor::StatusOr<std::vector<std::unique_ptr<Observation>>> MaybeMakePrivateObservations(
      std::unique_ptr<Observation> observation, const MetricDefinition& /*metric_def*/,
      const ReportDefinition& /*report_def*/) override {
    std::vector<std::unique_ptr<Observation>> observations;

    if (!return_private_observations_) {
      observations.push_back(std::move(observation));
      return observations;
    }

    for (int i = 0; i < num_private_observations_; i++) {
      auto observation = std::make_unique<Observation>();
      observations.push_back(std::move(observation));
    }

    return observations;
  }

 private:
  bool return_private_observations_;
  int num_private_observations_;
};

}  // namespace

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

    system_clock_ = std::make_unique<util::IncrementingSystemClock>();
    system_clock_->increment_by(std::chrono::hours(util::kNumHoursPerDay * 100));
    starting_time_ = system_clock_->now();
    test_clock_ = std::make_unique<util::FakeValidatedClock>(system_clock_.get());
    test_clock_->SetAccurate(true);
    metadata_builder_ = std::make_unique<MetadataBuilder>(system_data_, test_clock_.get(),
                                                          system_data_cache_path(), fs());
    // The current SystemProfile has a system version of 101 and 1 experiment token.
    system_data_.SetVersion("101");
    metadata_builder_->SnapshotSystemData();
    SetRegistry();
  }

  void SetRegistry(std::unique_ptr<CobaltRegistry> registry = GetRegistry()) {
    project_context_factory_ = std::make_unique<logger::ProjectContextFactory>(std::move(registry));
    aggregate_storage_ = LocalAggregateStorage::New(
        LocalAggregateStorage::StorageStrategy::Immediate, local_aggregation_store_path(), fs(),
        project_context_factory_.get(), *metadata_builder_, 0);
    project_context_ = GetProjectContext();
  }

  MetricAggregateRef GetMetricAggregate(uint32_t metric_id) {
    lib::statusor::StatusOr<MetricAggregateRef> metric_aggregate_or =
        aggregate_storage_->GetMetricAggregate(kProjectIdentifier.ForMetric(metric_id));
    EXPECT_TRUE(metric_aggregate_or.ok());

    return metric_aggregate_or.ConsumeValueOrDie();
  }

  std::shared_ptr<const logger::ProjectContext> GetProjectContext() {
    return project_context_factory_->NewProjectContext(
        lib::CustomerIdentifier(kCustomerId).ForProject(kProjectId));
  }

  void ConstructObservationGenerator(
      const logger::ObservationWriter& observation_writer,
      std::unique_ptr<FakePrivacyEncoder> privacy_encoder,
      util::CivilTimeConverterInterface& civil_time_converter,
      bool generate_observations_with_current_system_profile = false) {
    observation_generator_ = std::make_unique<ObservationGenerator>(
        *aggregate_storage_, project_context_factory_.get(), system_data_, observation_writer,
        std::move(privacy_encoder), civil_time_converter,
        generate_observations_with_current_system_profile);
  }

  void TearDown() override {
    if (observation_generator_) {
      observation_generator_->ShutDown();
    }
  }

  Status GenerateObservationsOnce(std::chrono::system_clock::time_point system_time) {
    return observation_generator_->GenerateObservationsOnce(system_time);
  }

  friend class BasicLogger;

 protected:
  system_data::FakeSystemData system_data_;
  std::unique_ptr<util::IncrementingSystemClock> system_clock_;
  std::unique_ptr<util::FakeValidatedClock> test_clock_;
  std::chrono::system_clock::time_point starting_time_;

  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<logger::ProjectContextFactory> project_context_factory_;
  // The `ProjectContext` for the test customer and project.
  std::shared_ptr<const logger::ProjectContext> project_context_;
  std::unique_ptr<LocalAggregateStorage> aggregate_storage_;
  std::unique_ptr<ObservationGenerator> observation_generator_;
};

class TestObservationStoreWriter : public observation_store::ObservationStoreWriterInterface {
 public:
  explicit TestObservationStoreWriter(
      std::function<void(std::unique_ptr<observation_store::StoredObservation>,
                         std::unique_ptr<ObservationMetadata>)>
          watcher)
      : watcher_(std::move(watcher)) {}

  Status StoreObservation(std::unique_ptr<observation_store::StoredObservation> observation,
                          std::unique_ptr<ObservationMetadata> metadata) override {
    watcher_(std::move(observation), std::move(metadata));
    return Status::OkStatus();
  }

 private:
  std::function<void(std::unique_ptr<observation_store::StoredObservation>,
                     std::unique_ptr<ObservationMetadata>)>
      watcher_;
};

struct ObservationGeneratorTestParams {
  uint32_t metric_id;
  uint32_t report_id;
  std::function<std::unique_ptr<util::CivilTimeConverterInterface>()> converter_fn;
};

class ObservationGeneratorTestWithParams
    : public ObservationGeneratorTest,
      public ::testing::WithParamInterface<ObservationGeneratorTestParams> {};

using HourlyObservationGeneratorTest = ObservationGeneratorTestWithParams;
using DailyObservationGeneratorTest = ObservationGeneratorTestWithParams;
using SystemProfileObservationGeneratorTest = ObservationGeneratorTestWithParams;

TEST_P(HourlyObservationGeneratorTest, GeneratesHourlyObservations) {
  // The delta between the hour IDs for consecutive hours, assuming no change in time zone
  // (including DST status).
  const int kHourIdsPerHour = 2;
  const uint32_t kMaxHourIdOffset = 101;

  ObservationGeneratorTestParams params = GetParam();
  std::unique_ptr<util::CivilTimeConverterInterface> converter = params.converter_fn();
  const MetricDefinition& metric = *project_context_->GetMetric(params.metric_id);
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_hour_id,
                          util::TimePointToHourId(starting_time_, *converter, metric));

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(params.metric_id);
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())[params.report_id];

    for (uint32_t i = 0; i <= kMaxHourIdOffset; i += kHourIdsPerHour) {
      uint32_t count = (i + 1) * 100;
      SystemProfileAggregate* agg =
          (*report_agg->mutable_hourly()->mutable_by_hour_id())[start_hour_id + i]
              .add_system_profile_aggregates();
      agg->set_system_profile_hash(system_profile_hash);
      agg->add_by_event_code()->mutable_data()->set_count(count);
    }

    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;
  uint32_t selected_id = params.report_id;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id, &selected_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == selected_id) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  for (uint32_t i = 0; i <= kMaxHourIdOffset; i += 2 * kHourIdsPerHour) {
    // Generate observations for the hour ending at `end_time`.
    std::chrono::system_clock::time_point end_time =
        starting_time_ + std::chrono::hours(i / kHourIdsPerHour);
    GenerateObservationsOnce(end_time + std::chrono::hours(1));

    CB_ASSERT_OK_AND_ASSIGN(uint32_t day_index,
                            util::TimePointToDayIndex(end_time, *converter, metric));
    EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
    EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
    EXPECT_EQ(last_metadata->day_index(), day_index)
        << "Incorrect day index for hour ID offset i: " << i;
    EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
    EXPECT_EQ(last_metadata->system_profile().board_name(), "");
    ASSERT_TRUE(last_observation);
    EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
    ASSERT_TRUE(last_observation->has_integer());
    ASSERT_GT(last_observation->integer().values_size(), 0);
    EXPECT_EQ(last_observation->integer().values(0).value(), (i + 1) * 100)
        << "Incorrect count for hour ID offset i: " << i;
  }
}

INSTANTIATE_TEST_SUITE_P(
    GenerateHourlyObservations, HourlyObservationGeneratorTest,
    ::testing::Values(
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceMetricMetricId,
            .report_id = kOccurrenceMetricFleetwideOccurrenceCountsReportReportId,
            .converter_fn = []() { return std::make_unique<util::UtcTimeConverter>(); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceOtherTzMetricMetricId,
            .report_id = kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId,
            .converter_fn = []() { return std::make_unique<util::UtcTimeConverter>(); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceMetricMetricId,
            .report_id = kOccurrenceMetricFleetwideOccurrenceCountsReportReportId,
            .converter_fn =
                []() { return std::make_unique<util::FakeCivilTimeConverter>(2, false); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceOtherTzMetricMetricId,
            .report_id = kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId,
            .converter_fn = []() {
              return std::make_unique<util::FakeCivilTimeConverter>(2, false);
            }}));

TEST_F(ObservationGeneratorTest, GeneratesHourlyObservationsWithDstStart) {
  // Use a civil time converter that simulates a transition from PST (UTC-8h) to PDT (UTC-7h), with
  // the transition occurring 1 hour after the start of the test.
  std::unique_ptr<util::FakeCivilTimeConverter> converter =
      std::make_unique<util::FakeCivilTimeConverter>(
          /*start_utc_offset=*/-8, /*start_isdst=*/false,
          /*end_utc_offset=*/-7, /*end_isdst=*/true,
          /*threshold=*/starting_time_ + std::chrono::hours(1));
  const MetricDefinition& metric = *project_context_->GetMetric(kOccurrenceOtherTzMetricMetricId);
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_hour_id,
                          util::TimePointToHourId(starting_time_, *converter, metric));

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;

  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() ==
            kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(metric.id());
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())
            [kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId];

    SystemProfileAggregate* agg =
        (*report_agg->mutable_hourly()->mutable_by_hour_id())[start_hour_id]
            .add_system_profile_aggregates();
    agg->set_system_profile_hash(system_profile_hash);
    agg->add_by_event_code()->mutable_data()->set_count(100);

    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  // Increment the clock by 1 hour, reaching the time zone transition threshold. The hour ID
  // increases by 3.
  system_clock_->increment_by(std::chrono::hours(1));
  CB_ASSERT_OK_AND_ASSIGN(uint32_t next_hour_id,
                          util::TimePointToHourId(system_clock_->now(), *converter, metric));
  ASSERT_EQ(next_hour_id, start_hour_id + 3);
  GenerateObservationsOnce(system_clock_->now());

  EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
  ASSERT_TRUE(last_metadata);
  EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
  EXPECT_EQ(last_metadata->day_index(), util::HourIdToDayIndex(start_hour_id));
  EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
  EXPECT_EQ(last_metadata->system_profile().board_name(), "");
  ASSERT_TRUE(last_observation);
  EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
  ASSERT_TRUE(last_observation->has_integer());
  ASSERT_GT(last_observation->integer().values_size(), 0);
  EXPECT_EQ(last_observation->integer().values(0).value(), 100);

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(metric.id());
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())
            [kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId];

    SystemProfileAggregate* agg =
        (*report_agg->mutable_hourly()->mutable_by_hour_id())[next_hour_id]
            .add_system_profile_aggregates();
    agg->set_system_profile_hash(system_profile_hash);
    agg->add_by_event_code()->mutable_data()->set_count(200);

    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  // Increment the clock by 1 hour. The hour ID increases by 2 since `next_hour_id`, for a total of
  // `start_hour_id + 5`.
  system_clock_->increment_by(std::chrono::hours(1));
  CB_ASSERT_OK_AND_ASSIGN(uint32_t final_hour_id,
                          util::TimePointToHourId(system_clock_->now(), *converter, metric));
  ASSERT_EQ(final_hour_id, start_hour_id + 5);
  GenerateObservationsOnce(system_clock_->now());

  EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
  ASSERT_TRUE(last_metadata);
  EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
  EXPECT_EQ(last_metadata->day_index(), util::HourIdToDayIndex(next_hour_id));
  EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
  EXPECT_EQ(last_metadata->system_profile().board_name(), "");
  ASSERT_TRUE(last_observation);
  EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
  ASSERT_TRUE(last_observation->has_integer());
  ASSERT_GT(last_observation->integer().values_size(), 0);
  EXPECT_EQ(last_observation->integer().values(0).value(), 200);
}

TEST_F(ObservationGeneratorTest, GeneratesHourlyObservationsWithDstEnd) {
  // Use a civil time converter that simulates a transition from PDT (UTC-7h) to PST (UTC-8h), with
  // the transition occurring 1 hour after the start of the test.
  std::unique_ptr<util::FakeCivilTimeConverter> converter =
      std::make_unique<util::FakeCivilTimeConverter>(
          /*start_utc_offset=*/-7, /*start_isdst=*/true,
          /*end_utc_offset=*/-8, /*end_isdst=*/false,
          /*threshold=*/starting_time_ + std::chrono::hours(1));
  const MetricDefinition& metric = *project_context_->GetMetric(kOccurrenceOtherTzMetricMetricId);
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_hour_id,
                          util::TimePointToHourId(starting_time_, *converter, metric));

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;

  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() ==
            kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(metric.id());
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())
            [kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId];

    SystemProfileAggregate* agg =
        (*report_agg->mutable_hourly()->mutable_by_hour_id())[start_hour_id]
            .add_system_profile_aggregates();
    agg->set_system_profile_hash(system_profile_hash);
    agg->add_by_event_code()->mutable_data()->set_count(100);

    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  // Increment the clock by 1 hour, reaching the time zone transition threshold. The hour ID
  // increases by 1.
  system_clock_->increment_by(std::chrono::hours(1));
  CB_ASSERT_OK_AND_ASSIGN(uint32_t next_hour_id,
                          util::TimePointToHourId(system_clock_->now(), *converter, metric));
  ASSERT_EQ(next_hour_id, start_hour_id + 1);
  GenerateObservationsOnce(system_clock_->now());

  EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
  ASSERT_TRUE(last_metadata);
  EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
  EXPECT_EQ(last_metadata->day_index(), util::HourIdToDayIndex(start_hour_id));
  EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
  EXPECT_EQ(last_metadata->system_profile().board_name(), "");
  ASSERT_TRUE(last_observation);
  EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
  ASSERT_TRUE(last_observation->has_integer());
  ASSERT_GT(last_observation->integer().values_size(), 0);
  EXPECT_EQ(last_observation->integer().values(0).value(), 100);

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(metric.id());
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())
            [kOccurrenceOtherTzMetricFleetwideOccurrenceCountsReportReportId];

    SystemProfileAggregate* agg =
        (*report_agg->mutable_hourly()->mutable_by_hour_id())[next_hour_id]
            .add_system_profile_aggregates();
    agg->set_system_profile_hash(system_profile_hash);
    agg->add_by_event_code()->mutable_data()->set_count(200);

    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  // Increment the clock by 1 hour. The hour ID increases by 2 since `next_hour_id`, for a total of
  // `start_hour_id + 3`.
  system_clock_->increment_by(std::chrono::hours(1));
  CB_ASSERT_OK_AND_ASSIGN(uint32_t final_hour_id,
                          util::TimePointToHourId(system_clock_->now(), *converter, metric));
  ASSERT_EQ(final_hour_id, start_hour_id + 3);
  GenerateObservationsOnce(system_clock_->now());

  EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
  ASSERT_TRUE(last_metadata);
  EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
  EXPECT_EQ(last_metadata->day_index(), util::HourIdToDayIndex(next_hour_id));
  EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
  EXPECT_EQ(last_metadata->system_profile().board_name(), "");
  ASSERT_TRUE(last_observation);
  EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
  ASSERT_TRUE(last_observation->has_integer());
  ASSERT_GT(last_observation->integer().values_size(), 0);
  EXPECT_EQ(last_observation->integer().values(0).value(), 200);
}

TEST_P(DailyObservationGeneratorTest, GeneratesDailyObservations) {
  const uint32_t kMaxDayIndexOffset = 5;

  ObservationGeneratorTestParams params = GetParam();
  std::unique_ptr<util::CivilTimeConverterInterface> converter = params.converter_fn();
  const MetricDefinition& metric = *project_context_->GetMetric(params.metric_id);
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_day_index,
                          util::TimePointToDayIndex(starting_time_, *converter, metric));

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(params.metric_id);
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())[params.report_id];

    for (uint32_t i = 0; i <= kMaxDayIndexOffset; i += 1) {
      SystemProfileAggregate* agg =
          (*report_agg->mutable_daily()->mutable_by_day_index())[start_day_index + i]
              .add_system_profile_aggregates();
      agg->set_system_profile_hash(system_profile_hash);
      agg->add_by_event_code()->mutable_data()->mutable_at_least_once()->set_at_least_once(true);
    }
    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;
  uint32_t selected_id = params.report_id;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id, &selected_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == selected_id) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  for (uint32_t i = 0; i <= kMaxDayIndexOffset; i += 1) {
    // Generate observations for the day ending at `end_time`.
    std::chrono::system_clock::time_point end_time =
        starting_time_ + std::chrono::hours(i * util::kNumHoursPerDay);
    GenerateObservationsOnce(end_time + std::chrono::hours(util::kNumHoursPerDay));

    CB_ASSERT_OK_AND_ASSIGN(uint32_t day_index,
                            util::TimePointToDayIndex(end_time, *converter, metric));
    EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
    ASSERT_TRUE(last_metadata);
    EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
    EXPECT_EQ(last_metadata->day_index(), day_index)
        << "Incorrect day index for day index offset i: " << i;
    EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
    EXPECT_EQ(last_metadata->system_profile().board_name(), "");
    ASSERT_TRUE(last_observation);
    EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
    ASSERT_TRUE(last_observation->has_integer());
    ASSERT_EQ(last_observation->integer().values_size(), 1);
    EXPECT_EQ(last_observation->integer().values(0).value(), 1)
        << "Incorrect count for day index offset i: " << i;
  }
}

INSTANTIATE_TEST_SUITE_P(
    GenerateDailyObservations, DailyObservationGeneratorTest,
    ::testing::Values(
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceMetricMetricId,
            .report_id = kOccurrenceMetricUniqueDeviceCountsReport1DayReportId,
            .converter_fn = []() { return std::make_unique<util::UtcTimeConverter>(); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceOtherTzMetricMetricId,
            .report_id = kOccurrenceOtherTzMetricUniqueDeviceCountsReport1DayReportId,
            .converter_fn = []() { return std::make_unique<util::UtcTimeConverter>(); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceMetricMetricId,
            .report_id = kOccurrenceOtherTzMetricUniqueDeviceCountsReport1DayReportId,
            .converter_fn =
                []() { return std::make_unique<util::FakeCivilTimeConverter>(2, false); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceOtherTzMetricMetricId,
            .report_id = kOccurrenceOtherTzMetricUniqueDeviceCountsReport1DayReportId,
            .converter_fn = []() {
              return std::make_unique<util::FakeCivilTimeConverter>(2, false);
            }}));

TEST_F(ObservationGeneratorTest, GeneratesNoObservationsForNoAggregateData) {
  const uint32_t kNumDays = 5;
  const MetricDefinition* metric = project_context_->GetMetric(kOccurrenceMetricMetricId);
  std::unique_ptr<util::UtcTimeConverter> converter = std::make_unique<util::UtcTimeConverter>();
  CB_ASSERT_OK_AND_ASSIGN(TimeInfo starting_time_info,
                          TimeInfo::FromTimePoint(starting_time_, *converter, *metric));

  {
    MetricAggregateRef aggregate = GetMetricAggregate(kOccurrenceMetricMetricId);
    ReportAggregate* report =
        &(*aggregate.aggregate()
               ->mutable_by_report_id())[kOccurrenceMetricUniqueDeviceCountsReport1DayReportId];
    report->mutable_daily()->set_last_day_index(starting_time_info.day_index);
    ASSERT_TRUE(aggregate.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == kOccurrenceMetricUniqueDeviceCountsReport1DayReportId) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  for (uint32_t i = 0; i <= kNumDays; ++i) {
    GenerateObservationsOnce(starting_time_ + std::chrono::hours(util::kNumHoursPerDay * kNumDays));

    EXPECT_FALSE(last_metadata);
    EXPECT_FALSE(last_observation);
  }
}

TEST_F(ObservationGeneratorTest, GeneratesDailyObservationsAsExpectedDespiteFailure) {
  const uint32_t kNumDays = 5;
  const MetricDefinition* metric = project_context_->GetMetric(kOccurrenceMetricMetricId);
  std::unique_ptr<util::UtcTimeConverter> converter = std::make_unique<util::UtcTimeConverter>();
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_day_index,
                          util::TimePointToDayIndex(starting_time_, *converter, *metric));

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef aggregate = GetMetricAggregate(kOccurrenceMetricMetricId);
    ReportAggregate* report =
        &(*aggregate.aggregate()
               ->mutable_by_report_id())[kOccurrenceMetricUniqueDeviceCountsReport1DayReportId];
    for (uint32_t i = start_day_index; i < start_day_index + kNumDays; i += 1) {
      SystemProfileAggregate* system_profile_agg =
          (*report->mutable_daily()->mutable_by_day_index())[i].add_system_profile_aggregates();
      system_profile_agg->set_system_profile_hash(system_profile_hash);
      system_profile_agg->add_by_event_code()
          ->mutable_data()
          ->mutable_at_least_once()
          ->set_at_least_once(true);
    }
    aggregate.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(aggregate.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == kOccurrenceMetricUniqueDeviceCountsReport1DayReportId) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  // Set the MetricType to an invalid type.
  SetRegistry(
      testing::MutateProject(GetRegistry(), kCustomerId, kProjectId, [](ProjectConfig* project) {
        project->mutable_metrics(kOccurrenceMetricMetricIndex)
            ->set_metric_type(MetricDefinition::INTEGER_HISTOGRAM);
      }));

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  // This generation should fail because the aggregation procedure
  // couldn't be created.
  EXPECT_NE(StatusCode::OK,
            GenerateObservationsOnce(
                util::FromUnixSeconds(util::DayIndexToUnixSeconds(start_day_index + 1)))
                .error_code());

  // Reset to default registry.
  SetRegistry();
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  // Data should still be collected as expected.
  for (uint32_t i = start_day_index; i < start_day_index + kNumDays; i += 1) {
    EXPECT_EQ(StatusCode::OK,
              GenerateObservationsOnce(util::FromUnixSeconds(util::DayIndexToUnixSeconds(i + 1)))
                  .error_code());

    EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
    ASSERT_TRUE(last_metadata);
    EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
    EXPECT_EQ(last_metadata->day_index(), i);
    EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
    EXPECT_EQ(last_metadata->system_profile().board_name(), "");
    ASSERT_TRUE(last_observation);
    EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
    ASSERT_TRUE(last_observation->has_integer());
    ASSERT_EQ(last_observation->integer().values_size(), 1);
    EXPECT_EQ(last_observation->integer().values(0).value(), 1);
  }
}

TEST_F(ObservationGeneratorTest, GeneratesDailyObservationsWithReportAllAsExpected) {
  SetRegistry(
      testing::MutateProject(GetRegistry(), kCustomerId, kProjectId, [](ProjectConfig* project) {
        project->mutable_metrics(kOccurrenceMetricMetricIndex)
            ->mutable_reports(kOccurrenceMetricUniqueDeviceCountsReport1DayReportIndex)
            ->set_system_profile_selection(SystemProfileSelectionPolicy::REPORT_ALL);
      }));

  const uint32_t kNumDays = 5;
  const MetricDefinition* metric = project_context_->GetMetric(kOccurrenceMetricMetricId);
  std::unique_ptr<util::UtcTimeConverter> converter = std::make_unique<util::UtcTimeConverter>();
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_day_index,
                          util::TimePointToDayIndex(starting_time_, *converter, *metric));

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef aggregate = GetMetricAggregate(kOccurrenceMetricMetricId);
    ReportAggregate* report =
        &(*aggregate.aggregate()
               ->mutable_by_report_id())[kOccurrenceMetricUniqueDeviceCountsReport1DayReportId];
    for (uint32_t i = start_day_index; i < start_day_index + kNumDays; i += 1) {
      SystemProfileAggregate* system_profile_agg =
          (*report->mutable_daily()->mutable_by_day_index())[i].add_system_profile_aggregates();
      system_profile_agg->set_system_profile_hash(system_profile_hash);
      system_profile_agg->add_by_event_code()
          ->mutable_data()
          ->mutable_at_least_once()
          ->set_at_least_once(true);
    }
    aggregate.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(aggregate.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == kOccurrenceMetricUniqueDeviceCountsReport1DayReportId) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  for (uint32_t i = start_day_index; i < start_day_index + kNumDays; i += 1) {
    GenerateObservationsOnce(util::FromUnixSeconds(util::DayIndexToUnixSeconds(i + 1)));

    EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
    ASSERT_TRUE(last_metadata);
    EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
    EXPECT_EQ(last_metadata->day_index(), i);
    ASSERT_TRUE(last_observation);
    EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
    ASSERT_TRUE(last_observation->has_integer());
    ASSERT_EQ(last_observation->integer().values_size(), 1);
    EXPECT_EQ(last_observation->integer().values(0).value(), 1);
  }
}

TEST_F(ObservationGeneratorTest, GeneratesPrivateObservations) {
  uint32_t kMaxHourOffset = 101;
  int kNumPrivateObs = 2;

  const MetricDefinition* metric = project_context_->GetMetric(kOccurrenceMetricMetricId);
  std::unique_ptr<util::UtcTimeConverter> converter = std::make_unique<util::UtcTimeConverter>();
  CB_ASSERT_OK_AND_ASSIGN(TimeInfo starting_time_info,
                          TimeInfo::FromTimePoint(starting_time_, *converter, *metric));

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());
  {
    MetricAggregateRef aggregate = GetMetricAggregate(kOccurrenceMetricMetricId);
    auto* report =
        &(*aggregate.aggregate()
               ->mutable_by_report_id())[kOccurrenceMetricFleetwideOccurrenceCountsReportReportId];
    report->mutable_hourly()->set_last_hour_id(starting_time_info.hour_id - 2);
    for (uint32_t i = starting_time_info.hour_id; i < starting_time_info.hour_id + kMaxHourOffset;
         i += 2) {
      SystemProfileAggregate* system_profile_agg =
          (*report->mutable_hourly()->mutable_by_hour_id())[i].add_system_profile_aggregates();
      system_profile_agg->set_system_profile_hash(system_profile_hash);
      system_profile_agg->add_by_event_code()->mutable_data()->set_count(
          (i - starting_time_info.hour_id + 1) * 100);
    }
    aggregate.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(aggregate.Save().ok());
  }

  std::vector<Observation> observations;
  observations.reserve(kNumPrivateObs);
  std::vector<ObservationMetadata> metadatas;
  metadatas.reserve(kNumPrivateObs);
  int contribution_count = 0;
  TestObservationStoreWriter test_writer(
      [&observations, &metadatas, &contribution_count](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == kOccurrenceMetricFleetwideOccurrenceCountsReportReportId) {
          metadatas.push_back(*metadata);
          if (observation->has_unencrypted()) {
            observations.push_back(observation->unencrypted());
          }
          if (!observation->contribution_id().empty()) {
            contribution_count++;
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(
      observation_writer, std::make_unique<FakePrivacyEncoder>(true, kNumPrivateObs), *converter);
  GenerateObservationsOnce(starting_time_ + util::kOneHour);

  EXPECT_EQ(observations.size(), kNumPrivateObs);
  EXPECT_EQ(contribution_count, 1);
  for (const Observation& obs : observations) {
    EXPECT_EQ(obs.random_id().size(), kRandomIdSize);
  }
  EXPECT_EQ(metadatas.size(), kNumPrivateObs);
  for (const ObservationMetadata& metadata : metadatas) {
    EXPECT_EQ(metadata.customer_id(), kCustomerId);
    EXPECT_EQ(metadata.day_index(), util::HourIdToDayIndex(starting_time_info.hour_id));
    // Stored data's system profile is used.
    EXPECT_EQ(metadata.system_profile().system_version(), system_profile.system_version());
    EXPECT_EQ(metadata.system_profile().board_name(), "");
  }
}

TEST_F(ObservationGeneratorTest, GeneratesPrivateObservationsForNoObservation) {
  int kNumPrivateObs = 2;
  const MetricDefinition* metric = project_context_->GetMetric(kOccurrenceMetricMetricId);
  std::unique_ptr<util::UtcTimeConverter> converter = std::make_unique<util::UtcTimeConverter>();
  CB_ASSERT_OK_AND_ASSIGN(TimeInfo starting_time_info,
                          TimeInfo::FromTimePoint(starting_time_, *converter, *metric));

  {
    MetricAggregateRef aggregate = GetMetricAggregate(kOccurrenceMetricMetricId);
    auto* report =
        &(*aggregate.aggregate()
               ->mutable_by_report_id())[kOccurrenceMetricFleetwideOccurrenceCountsReportReportId];
    report->mutable_hourly()->set_last_hour_id(starting_time_info.hour_id - 2);
    ASSERT_TRUE(aggregate.Save().ok());
  }

  std::vector<Observation> observations;
  observations.reserve(kNumPrivateObs);
  std::vector<ObservationMetadata> metadatas;
  metadatas.reserve(kNumPrivateObs);
  int contribution_count = 0;
  TestObservationStoreWriter test_writer(
      [&observations, &metadatas, &contribution_count](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == kOccurrenceMetricFleetwideOccurrenceCountsReportReportId) {
          metadatas.push_back(*metadata);
          if (observation->has_unencrypted()) {
            observations.push_back(observation->unencrypted());
          }
          if (!observation->contribution_id().empty()) {
            contribution_count++;
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(
      observation_writer, std::make_unique<FakePrivacyEncoder>(true, kNumPrivateObs), *converter);
  GenerateObservationsOnce(starting_time_ + util::kOneHour);

  EXPECT_EQ(observations.size(), kNumPrivateObs);
  EXPECT_EQ(contribution_count, 1);
  for (const Observation& obs : observations) {
    EXPECT_EQ(obs.random_id().size(), kRandomIdSize);
  }
  EXPECT_EQ(metadatas.size(), kNumPrivateObs);
  for (const ObservationMetadata& metadata : metadatas) {
    EXPECT_EQ(metadata.customer_id(), kCustomerId);
    EXPECT_EQ(metadata.day_index(), util::HourIdToDayIndex(starting_time_info.hour_id));
    // Current system profile is used.
    EXPECT_EQ(metadata.system_profile().system_version(),
              system_data_.system_profile().system_version());
    EXPECT_EQ(metadata.system_profile().board_name(), "");
  }
}

TEST_P(SystemProfileObservationGeneratorTest, GenerateObservationsFallbackToCurrentSystemProfile) {
  ObservationGeneratorTestParams params = GetParam();
  std::unique_ptr<util::CivilTimeConverterInterface> converter = params.converter_fn();
  const MetricDefinition& metric = *project_context_->GetMetric(params.metric_id);
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_day_index,
                          util::TimePointToDayIndex(starting_time_, *converter, metric));

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::ANDROID);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(params.metric_id);
    // Use the report that has experiment tokens in the system profile.
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())[params.report_id];
    SystemProfileAggregate* agg =
        (*report_agg->mutable_daily()->mutable_by_day_index())[start_day_index]
            .add_system_profile_aggregates();
    agg->set_system_profile_hash(system_profile_hash);
    agg->add_by_event_code()->mutable_data()->mutable_at_least_once()->set_at_least_once(true);
    // Don't store the system_profile.
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;
  uint32_t selected_id = params.report_id;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id, &selected_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == selected_id) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  GenerateObservationsOnce(starting_time_ + util::kOneDay);

  EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
  ASSERT_TRUE(last_metadata);
  EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
  EXPECT_EQ(last_metadata->day_index(), start_day_index);
  // System profile fields were set from the current system profile.
  EXPECT_NE(last_metadata->system_profile().os(), system_profile.os());
  EXPECT_NE(last_metadata->system_profile().system_version(), system_profile.system_version());
  EXPECT_EQ(last_metadata->system_profile().os(), system_data_.system_profile().os());
  EXPECT_EQ(last_metadata->system_profile().system_version(),
            system_data_.system_profile().system_version());
  EXPECT_EQ(last_metadata->system_profile().board_name(), "");
  ASSERT_TRUE(last_observation);
  EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
  ASSERT_TRUE(last_observation->has_integer());
  ASSERT_EQ(last_observation->integer().values_size(), 1);
  EXPECT_EQ(last_observation->integer().values(0).value(), 1);
}

// Use a report that has experiment tokens in the system profile.
TEST_P(SystemProfileObservationGeneratorTest, GenerateObservationsWithCurrentSystemProfile) {
  ObservationGeneratorTestParams params = GetParam();
  std::unique_ptr<util::CivilTimeConverterInterface> converter = params.converter_fn();
  const MetricDefinition& metric = *project_context_->GetMetric(params.metric_id);
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_day_index,
                          util::TimePointToDayIndex(starting_time_, *converter, metric));

  SystemProfile system_profile;
  // No system profile fields except OS.
  system_profile.set_os(SystemProfile::ANDROID);
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(params.metric_id);
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())[params.report_id];

    SystemProfileAggregate* agg =
        (*report_agg->mutable_daily()->mutable_by_day_index())[start_day_index]
            .add_system_profile_aggregates();
    agg->set_system_profile_hash(system_profile_hash);
    agg->add_by_event_code()->mutable_data()->mutable_at_least_once()->set_at_least_once(true);
    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;
  uint32_t selected_id = params.report_id;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id, &selected_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == selected_id) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter,
                                /*generate_observations_with_current_system_profile=*/true);
  // Generate observations for the day with day index `start_day_index`.
  GenerateObservationsOnce(starting_time_ + std::chrono::hours(util::kNumHoursPerDay));

  EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
  ASSERT_TRUE(last_metadata);
  EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
  EXPECT_EQ(last_metadata->day_index(), start_day_index);
  // Unset system profile fields were set from the current system
  // profile.
  EXPECT_EQ(last_metadata->system_profile().os(), system_profile.os());
  EXPECT_EQ(last_metadata->system_profile().system_version(),
            system_data_.system_profile().system_version());
  ASSERT_EQ(last_metadata->system_profile().experiment_tokens_size(), 1);
  EXPECT_EQ(last_metadata->system_profile().experiment_tokens(0).token(),
            system_data_.system_profile().experiment_tokens(0).token());
  EXPECT_EQ(last_metadata->system_profile().board_name(), "");
  ASSERT_TRUE(last_observation);
  EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
  ASSERT_TRUE(last_observation->has_integer());
  ASSERT_EQ(last_observation->integer().values_size(), 1);
  EXPECT_EQ(last_observation->integer().values(0).value(), 1);
}

// Use a report that has experiment tokens in the system profile.
TEST_P(SystemProfileObservationGeneratorTest,
       GenerateObservationsWithCurrentSystemProfileDoesNotOverwrite) {
  ObservationGeneratorTestParams params = GetParam();
  std::unique_ptr<util::CivilTimeConverterInterface> converter = params.converter_fn();
  const MetricDefinition& metric = *project_context_->GetMetric(params.metric_id);
  CB_ASSERT_OK_AND_ASSIGN(uint32_t start_day_index,
                          util::TimePointToDayIndex(starting_time_, *converter, metric));

  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::ANDROID);
  system_profile.set_system_version("100");
  ExperimentToken* token = system_profile.add_experiment_tokens();
  token->set_ns("ns2222");
  token->set_token("token2222");
  token = system_profile.add_experiment_tokens();
  token->set_ns("ns3333");
  token->set_token("token3333");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef metric_agg = GetMetricAggregate(params.metric_id);
    ReportAggregate* report_agg =
        &(*metric_agg.aggregate()->mutable_by_report_id())[params.report_id];

    SystemProfileAggregate* agg =
        (*report_agg->mutable_daily()->mutable_by_day_index())[start_day_index]
            .add_system_profile_aggregates();
    agg->set_system_profile_hash(system_profile_hash);
    agg->add_by_event_code()->mutable_data()->mutable_at_least_once()->set_at_least_once(true);
    metric_agg.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(metric_agg.Save().ok());
  }

  std::unique_ptr<ObservationMetadata> last_metadata;
  std::unique_ptr<Observation> last_observation;
  std::string last_contribution_id;
  uint32_t selected_id = params.report_id;
  TestObservationStoreWriter test_writer(
      [&last_metadata, &last_observation, &last_contribution_id, &selected_id](
          std::unique_ptr<observation_store::StoredObservation> observation,
          std::unique_ptr<ObservationMetadata> metadata) {
        if (metadata->report_id() == selected_id) {
          last_metadata = std::move(metadata);
          if (observation->has_unencrypted()) {
            last_observation = std::unique_ptr<Observation>(observation->release_unencrypted());
            last_contribution_id = observation->contribution_id();
          }
        }
      });

  logger::ObservationWriter observation_writer(test_writer, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter,
                                /*generate_observations_with_current_system_profile=*/true);
  // Generate observations for the day with day index `start_day_index`.
  GenerateObservationsOnce(starting_time_ + std::chrono::hours(util::kNumHoursPerDay));

  EXPECT_EQ(last_contribution_id.size(), kRandomIdSize);
  ASSERT_TRUE(last_metadata);
  EXPECT_EQ(last_metadata->customer_id(), kCustomerId);
  EXPECT_EQ(last_metadata->day_index(), start_day_index);
  // All system profile fields were set from the aggregate system
  // profile.
  EXPECT_EQ(last_metadata->system_profile().os(), system_profile.os());
  EXPECT_EQ(last_metadata->system_profile().system_version(), system_profile.system_version());
  ASSERT_EQ(last_metadata->system_profile().experiment_tokens_size(), 2);
  EXPECT_EQ(last_metadata->system_profile().experiment_tokens(0).token(),
            system_profile.experiment_tokens(0).token());
  EXPECT_EQ(last_metadata->system_profile().experiment_tokens(1).token(),
            system_profile.experiment_tokens(1).token());
  EXPECT_EQ(last_metadata->system_profile().board_name(), "");
  ASSERT_TRUE(last_observation);
  EXPECT_EQ(last_observation->random_id().size(), kRandomIdSize);
  ASSERT_TRUE(last_observation->has_integer());
  ASSERT_EQ(last_observation->integer().values_size(), 1);
  EXPECT_EQ(last_observation->integer().values(0).value(), 1);
}

INSTANTIATE_TEST_SUITE_P(
    GenerateObservationWithSystemProfile, SystemProfileObservationGeneratorTest,
    ::testing::Values(
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceMetricMetricId,
            .report_id = kOccurrenceMetricUniqueDeviceCountsSelectFirstReport1DayReportId,
            .converter_fn = []() { return std::make_unique<util::UtcTimeConverter>(); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceOtherTzMetricMetricId,
            .report_id = kOccurrenceOtherTzMetricUniqueDeviceCountsSelectFirstReport1DayReportId,
            .converter_fn = []() { return std::make_unique<util::UtcTimeConverter>(); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceMetricMetricId,
            .report_id = kOccurrenceMetricUniqueDeviceCountsSelectFirstReport1DayReportId,
            .converter_fn =
                []() { return std::make_unique<util::FakeCivilTimeConverter>(2, false); }},
        ObservationGeneratorTestParams{
            .metric_id = kOccurrenceOtherTzMetricMetricId,
            .report_id = kOccurrenceOtherTzMetricUniqueDeviceCountsSelectFirstReport1DayReportId,
            .converter_fn = []() {
              return std::make_unique<util::FakeCivilTimeConverter>(2, false);
            }}));

class BasicLogger : public logger::testing::FakeLogger {
 public:
  explicit BasicLogger(ObservationGeneratorTest* test) : test_(test) {}

  Status LogInteger(uint32_t metric_id, int64_t value,
                    const std::vector<uint32_t>& event_codes) override {
    // Lock the aggregate store to simulate actually performing log.
    test_->aggregate_storage_->GetMetricAggregate(
        lib::CustomerIdentifier(1).ForProject(1).ForMetric(1));
    return logger::testing::FakeLogger::LogInteger(metric_id, value, event_codes);
  }

 private:
  ObservationGeneratorTest* test_;
};

TEST_F(ObservationGeneratorTest, DoesNotDeadlock) {
  aggregate_storage_ = LocalAggregateStorage::New(
      LocalAggregateStorage::StorageStrategy::Delayed, local_aggregation_store_path(), fs(),
      project_context_factory_.get(), *metadata_builder_, 0);
  observation_store::FileObservationStore obs_store(10000, 10000, 10000, fs(), nullptr,
                                                    test_folder() + "/obs_store");
  BasicLogger logger(this);
  logger::InternalMetricsImpl internal_metrics(logger, nullptr);
  obs_store.ResetInternalMetrics(&internal_metrics);

  const MetricDefinition* metric = project_context_->GetMetric(kOccurrenceMetricMetricId);
  std::unique_ptr<util::UtcTimeConverter> converter = std::make_unique<util::UtcTimeConverter>();
  CB_ASSERT_OK_AND_ASSIGN(TimeInfo starting_time_info,
                          TimeInfo::FromTimePoint(starting_time_, *converter, *metric));

  const uint32_t kMaxHourOffset = 101;
  SystemProfile system_profile;
  system_profile.set_os(SystemProfile::FUCHSIA);
  system_profile.set_system_version("100");
  uint64_t system_profile_hash = util::Farmhash64(system_profile.SerializeAsString());

  {
    MetricAggregateRef aggregate = GetMetricAggregate(kOccurrenceMetricMetricId);
    ReportAggregate* report =
        &(*aggregate.aggregate()
               ->mutable_by_report_id())[kOccurrenceMetricFleetwideOccurrenceCountsReportReportId];
    for (uint32_t i = starting_time_info.hour_id; i < starting_time_info.hour_id + kMaxHourOffset;
         i += 2) {
      SystemProfileAggregate* system_profile_agg =
          (*report->mutable_hourly()->mutable_by_hour_id())[i].add_system_profile_aggregates();
      system_profile_agg->set_system_profile_hash(system_profile_hash);
      system_profile_agg->add_by_event_code()->mutable_data()->set_count(
          (i - starting_time_info.hour_id + 1) * 100);
    }
    aggregate.StoreFilteredSystemProfile(system_profile_hash, system_profile);
    ASSERT_TRUE(aggregate.Save().ok());
  }

  logger::ObservationWriter observation_writer(obs_store, nullptr);
  ConstructObservationGenerator(observation_writer, std::make_unique<FakePrivacyEncoder>(false),
                                *converter);

  for (uint32_t i = starting_time_info.hour_id; i < starting_time_info.hour_id + kMaxHourOffset;
       i += 4) {
    GenerateObservationsOnce(util::FromUnixSeconds(util::HourIdToUnixSeconds(i + 1)));
  }
}

}  // namespace cobalt::local_aggregation
