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

#include <chrono>
#include <memory>
#include <string>

#include <google/protobuf/repeated_field.h>
#include <google/protobuf/text_format.h>
#include <google/protobuf/util/message_differencer.h>
#include <gtest/gtest.h>

#include "src/algorithms/rappor/rappor_encoder.h"
#include "src/lib/util/clock.h"
#include "src/lib/util/datetime_util.h"
#include "src/lib/util/encrypted_message_util.h"
#include "src/lib/util/testing/test_with_files.h"
#include "src/local_aggregation/event_aggregator_mgr.h"
#include "src/local_aggregation/local_aggregation.pb.h"
#include "src/local_aggregation/test_utils/test_event_aggregator_mgr.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.h"
#include "src/local_aggregation_1_1/local_aggregation.pb.h"
#include "src/logger/encoder.h"
#include "src/logger/logger_test_utils.h"
#include "src/logger/project_context.h"
#include "src/logger/test_registries/cobalt1.1_test_registry.cb.h"
#include "src/logger/testing_constants.h"
#include "src/pb/metadata_builder.h"
#include "src/pb/observation.pb.h"
#include "src/public/lib/status.h"
#include "src/registry/packed_event_codes.h"
#include "src/system_data/client_secret.h"
#include "src/system_data/fake_system_data.h"

using ::google::protobuf::RepeatedField;
#ifndef PROTO_LITE
using ::google::protobuf::util::MessageDifferencer;
#endif

namespace cobalt::logger {

using config::PackEventCodes;
using internal::EventLogger;
using local_aggregation::LocalAggregation;
using local_aggregation::TestEventAggregatorManager;
using system_data::ClientSecret;
using testing::CheckNumericEventObservations;
using testing::CheckUniqueActivesObservations;
using testing::ExpectedAggregationParams;
using testing::ExpectedPerDeviceNumericObservations;
using testing::ExpectedReportParticipationObservations;
using testing::ExpectedUniqueActivesObservations;
using testing::FakeObservationStore;
using testing::FetchObservations;
using testing::FetchSingleObservation;
using testing::GetTestProject;
using testing::GetTestProjectContextFactory;
using testing::MakeNullExpectedUniqueActivesObservations;
using testing::TestUpdateRecipient;
using util::EncryptedMessageMaker;
using util::IncrementingSystemClock;
using util::TimeToDayIndex;

namespace {
// Number of seconds in a day
constexpr int kDay = 60 * 60 * 24;
// Number of seconds in an ideal year
constexpr int kYear = kDay * 365;

}  // namespace

template <typename EventLoggerClass = internal::EventLogger>
class EventLoggersTest : public util::testing::TestWithFiles {
 protected:
  static_assert(std::is_base_of<internal::EventLogger, EventLoggerClass>::value,
                "The type argument must be a subclass of EventLogger");

  void SetUp() override {
    SetUpFromMetrics(testing::all_report_types::kCobaltRegistryBase64,
                     testing::all_report_types::kExpectedAggregationParams);
  }

  // Set up LoggerTest using a base64-encoded registry.
  void SetUpFromMetrics(const std::string& registry_base64,
                        const ExpectedAggregationParams& expected_aggregation_params) {
    MakeTestFolder();

    // Create a mock clock which does not increment by default when called.
    // Set the time to 1 year after the start of Unix time so that the start
    // date of any aggregation window falls after the start of time.
    mock_clock_ = std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    mock_clock_->set_time(std::chrono::system_clock::time_point(std::chrono::seconds(kYear)));
    validated_clock_ = std::make_unique<util::FakeValidatedClock>(mock_clock_.get());
    validated_clock_->SetAccurate(true);
    civil_time_converter_ = std::make_unique<util::UtcTimeConverter>();

    expected_aggregation_params_ = expected_aggregation_params;
    observation_store_ = std::make_unique<FakeObservationStore>();
    update_recipient_ = std::make_unique<TestUpdateRecipient>();
    observation_encrypter_ = EncryptedMessageMaker::MakeUnencrypted();
    observation_writer_ = std::make_unique<ObservationWriter>(
        observation_store_.get(), update_recipient_.get(), observation_encrypter_.get());
    metadata_builder_ = std::make_unique<MetadataBuilder>(&system_data_, validated_clock_.get(),
                                                          system_data_cache_path(), fs());
    metadata_builder_->SnapshotSystemData();
    encoder_ = std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), *metadata_builder_);
    CobaltConfig cfg = {.client_secret = system_data::ClientSecret::GenerateNewSecret()};

    cfg.local_aggregation_backfill_days = 0;
    cfg.local_aggregate_proto_store_path = aggregate_store_path();
    cfg.obs_history_proto_store_path = obs_history_path();

    project_context_factory_ = GetTestProjectContextFactory(registry_base64);

    event_aggregator_mgr_ = std::make_unique<TestEventAggregatorManager>(
        cfg, fs(), *encoder_, observation_writer_.get(), *metadata_builder_);
    local_aggregation_ = std::make_unique<LocalAggregation>(
        cfg, project_context_factory_.get(), &system_data_, *metadata_builder_, fs(),
        observation_writer_.get(), civil_time_converter_.get());
    project_context_ = GetTestProject(registry_base64);
    event_aggregator_mgr_->GetEventAggregator().UpdateAggregationConfigs(*project_context_);
    logger_ = std::make_unique<EventLoggerClass>(
        *encoder_, event_aggregator_mgr_->GetEventAggregator(), local_aggregation_.get(),
        observation_writer_.get(), &system_data_, civil_time_converter_.get());
  }

  void TearDown() override {
    event_aggregator_mgr_.reset();
    logger_.reset();
  }

  // Returns the day index of the current day according to |mock_clock_|, in
  // |time_zone|, without incrementing the clock.
  uint32_t CurrentDayIndex(MetricDefinition::TimeZonePolicy time_zone) {
    return TimeToDayIndex(std::chrono::system_clock::to_time_t(mock_clock_->peek_now()), time_zone);
  }

  // Advances |mock_clock_| by |num_days| days.
  void AdvanceDay(int num_days) {
    mock_clock_->increment_by(std::chrono::seconds(kDay) * num_days);
  }

  // Clears the FakeObservationStore and resets counts of Observations received
  // by the FakeObservationStore and the TestUpdateRecipient.
  void ResetObservationStore() {
    observation_store_->messages_received.clear();
    observation_store_->metadata_received.clear();
    observation_store_->ResetObservationCounter();
    update_recipient_->invocation_count = 0;
  }

  Status LogEvent(uint32_t metric_id, uint32_t event_code) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    event_record->event()->mutable_event_occurred_event()->set_event_code(event_code);
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::EVENT_OCCURRED,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogEventCount(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                       const std::string& component, int64_t period_duration_micros,
                       uint32_t count) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* event_count_event = event_record->event()->mutable_event_count_event();
    event_count_event->set_component(component);
    event_count_event->set_period_duration_micros(period_duration_micros);
    event_count_event->set_count(count);
    event_count_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::EVENT_COUNT,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogElapsedTime(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                        const std::string& component, int64_t elapsed_micros) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* elapsed_time_event = event_record->event()->mutable_elapsed_time_event();
    elapsed_time_event->set_component(component);
    elapsed_time_event->set_elapsed_micros(elapsed_micros);
    elapsed_time_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::ELAPSED_TIME,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogFrameRate(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                      const std::string& component, int64_t frames_per_1000_seconds) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* frame_rate_event = event_record->event()->mutable_frame_rate_event();
    frame_rate_event->set_component(component);
    frame_rate_event->set_frames_per_1000_seconds(frames_per_1000_seconds);
    frame_rate_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::FRAME_RATE,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogMemoryUsage(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                        const std::string& component, int64_t bytes) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* memory_usage_event = event_record->event()->mutable_memory_usage_event();
    memory_usage_event->set_component(component);
    memory_usage_event->set_bytes(bytes);
    memory_usage_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::MEMORY_USAGE,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogIntHistogram(uint32_t metric_id, const std::vector<uint32_t>& event_codes,
                         const std::string& component, const std::vector<uint32_t>& indices,
                         const std::vector<uint32_t>& counts) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* int_histogram_event = event_record->event()->mutable_int_histogram_event();
    int_histogram_event->set_component(component);
    int_histogram_event->mutable_buckets()->Swap(testing::NewHistogram(indices, counts).get());
    int_histogram_event->mutable_event_code()->CopyFrom(
        RepeatedField<uint32_t>(event_codes.begin(), event_codes.end()));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::INT_HISTOGRAM,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogCustomEvent(uint32_t metric_id, const std::vector<std::string>& dimension_names,
                        const std::vector<CustomDimensionValue>& values) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* custom_event = event_record->event()->mutable_custom_event();
    custom_event->mutable_values()->swap(*testing::NewCustomEvent(dimension_names, values));
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::CUSTOM,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  Status LogSerializedCustomEvent(uint32_t metric_id, const std::string& serialized_proto) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();
    auto* custom_event = event_record->event()->mutable_custom_event();
    custom_event->set_serialized_proto(serialized_proto);
    Status valid;
    if (!(valid = logger_->PrepareAndValidateEvent(metric_id, MetricDefinition::CUSTOM,
                                                   event_record.get()))
             .ok()) {
      return valid;
    }
    return logger_->Log(std::move(event_record), mock_clock_->now());
  }

  std::chrono::system_clock::time_point start_time_;
  std::unique_ptr<internal::EventLogger> logger_;
  std::unique_ptr<TestEventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<LocalAggregation> local_aggregation_;
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  ExpectedAggregationParams expected_aggregation_params_;

 private:
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  system_data::FakeSystemData system_data_;
  std::unique_ptr<IncrementingSystemClock> mock_clock_;
  std::unique_ptr<util::FakeValidatedClock> validated_clock_;
  std::unique_ptr<util::UtcTimeConverter> civil_time_converter_;
  std::unique_ptr<ProjectContextFactory> project_context_factory_;
  std::shared_ptr<ProjectContext> project_context_;
};

class EventOccurredEventLoggerTest : public EventLoggersTest<internal::EventOccurredEventLogger> {};

class EventCountEventLoggerTest : public EventLoggersTest<internal::EventCountEventLogger> {};

class ElapsedTimeEventLoggerTest : public EventLoggersTest<internal::ElapsedTimeEventLogger> {};

class FrameRateEventLoggerTest : public EventLoggersTest<internal::FrameRateEventLogger> {};

class MemoryUsageEventLoggerTest : public EventLoggersTest<internal::MemoryUsageEventLogger> {};

class IntHistogramEventLoggerTest : public EventLoggersTest<internal::IntHistogramEventLogger> {};

class CustomEventLoggerTest : public EventLoggersTest<internal::CustomEventLogger> {};

// Creates a Logger whose ProjectContext contains only EVENT_OCCURRED metrics,
// each of which has a report of type UNIQUE_N_DAY_ACTIVES with
// local_privacy_noise_level set to NONE. Used to test the values of
// UniqueActivesObservations generated by the EventAggregator.
class UniqueActivesLoggerTest : public EventOccurredEventLoggerTest {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::unique_actives_noise_free::kCobaltRegistryBase64,
                     testing::unique_actives_noise_free::kExpectedAggregationParams);
  }
};

// Creates a Logger for a ProjectContext where each of the metrics
// has a report of type PER_DEVICE_NUMERIC_STATS.
class PerDeviceNumericEventCountEventLoggerTest
    : public EventLoggersTest<internal::EventCountEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

class PerDeviceNumericElapsedTimeEventLoggerTest
    : public EventLoggersTest<internal::ElapsedTimeEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

class PerDeviceNumericFrameRateEventLoggerTest
    : public EventLoggersTest<internal::FrameRateEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

class PerDeviceNumericMemoryUsageEventLoggerTest
    : public EventLoggersTest<internal::MemoryUsageEventLogger> {
 protected:
  void SetUp() override {
    SetUpFromMetrics(testing::per_device_numeric_stats::kCobaltRegistryBase64,
                     testing::per_device_numeric_stats::kExpectedAggregationParams);
  }
};

// Tests the EventOccurredEventLogger.
TEST_F(EventOccurredEventLoggerTest, Log) {
  // Attempt to use an event code larger than max_event_code.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEvent(testing::all_report_types::kErrorOccurredMetricId, 101).error_code());

  // Now use good arguments.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kErrorOccurredMetricId, 42).error_code());
  Observation observation;
  uint32_t expected_report_id = testing::all_report_types::kErrorOccurredErrorCountsByCodeReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, observation_store_.get(),
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_basic_rappor());
  EXPECT_FALSE(observation.basic_rappor().data().empty());
}

// Tests the EventCountEventLogger.
TEST_F(EventCountEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kReadCacheHitsReadCacheHitCountsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitHistogramsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitStatsReportId};

  // Attempt to use an event code larger than max_event_code.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {112}, "component2", 1, 303)
          .error_code());

  // All good
  ASSERT_EQ(StatusCode::OK, LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {43},
                                          "component2", 1, 303)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 43u, "component2", 303,
                                            observation_store_.get(), update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // No problem using event code 0.
  ASSERT_EQ(StatusCode::OK,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {0}, "", 1, 303)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0u, "", 303,
                                            observation_store_.get(), update_recipient_.get()));
}

// Tests the EventCountEventLogger with multiple event codes.
TEST_F(EventCountEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kReadCacheHitsReadCacheHitCountsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitHistogramsReportId,
      testing::all_report_types::kReadCacheHitsReadCacheHitStatsReportId};

  // Use a metric ID for the wrong type of metric. Expect StatusCode::INVALID_ARGUMENT.
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEventCount(testing::all_report_types::kErrorOccurredMetricId, {43}, "", 0, 303)
                .error_code());

  // Use no event codes when the metric has one dimension. Expect kOK.
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {}, "", 0, 303)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0, "", 303,
                                            observation_store_.get(), update_recipient_.get()));
  ResetObservationStore();

  // Use two event codes when the metric has one dimension. Expect
  // StatusCode::INVALID_ARGUMENT.
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {43, 44}, "", 0, 303)
                .error_code());

  // Use an event code that exceeds the specified max_event_code. Expect
  // StatusCode::INVALID_ARGUMENT.
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {200}, "", 0, 303)
                .error_code());

  // All good, expect OK.
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::all_report_types::kReadCacheHitsMetricId, {43}, "", 0, 303)
                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 43u, "", 303,
                                            observation_store_.get(), update_recipient_.get()));
}

// Tests the ElapsedTimeEventLogger.
TEST_F(ElapsedTimeEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeAggregatedReportId,
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeHistogramReportId};

  // Use a non-zero event code even though the metric does not have any
  // metric dimensions defined. Expect kInvalidArgument.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {44}, "component4", 4004)
          .error_code());

  // Use a zero event code when the metric does not have any metric dimensions
  // set. This is OK by convention. The zero will be ignored.
  ASSERT_EQ(StatusCode::OK, LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {0},
                                           "component4", 4004)
                                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0u, "component4", 4004,
                                            observation_store_.get(), update_recipient_.get()));
}

// Tests the ElapsedTimeEventLogger with multiple event codes.
TEST_F(ElapsedTimeEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeAggregatedReportId,
      testing::all_report_types::kModuleLoadTimeModuleLoadTimeHistogramReportId};

  // Use a non-zero event code even though the metric does not have any
  // metric dimensions defined. Expect kInvalidArgument.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {44}, "component4", 4004)
          .error_code());

  // Use two event codes even though the metric does not have any
  // metric dimensions defined. Expect kInvalidArgument.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {0, 0}, "component4", 4004)
          .error_code());

  // Use no event codes when the metric does not have any metric
  // dimensions set. This is good.
  ASSERT_EQ(StatusCode::OK, LogElapsedTime(testing::all_report_types::kModuleLoadTimeMetricId, {},
                                           "component4", 4004)
                                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0u, "component4", 4004,
                                            observation_store_.get(), update_recipient_.get()));
}

// Tests the FrameRateEventLogger.
TEST_F(FrameRateEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateAggregatedReportId,
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateHistogramReportId};

  // There is no max_event_code set so only the specified code of 45 is allowed.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {0},
                         "component5", 5123)
                .error_code());

  // All good.
  ASSERT_EQ(StatusCode::OK, LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId,
                                         {45}, "component5", 5123)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 45u, "component5", 5123,
                                            observation_store_.get(), update_recipient_.get()));
}

// Tests the FrameRateEventLogger with multiple event codes.
TEST_F(FrameRateEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateAggregatedReportId,
      testing::all_report_types::kLoginModuleFrameRateLoginModuleFrameRateHistogramReportId};

  // Use a metric ID for the wrong type of metric. Expect StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogFrameRate(testing::all_report_types::kModuleLoadTimeMetricId, {45}, "", 5123)
                .error_code());

  // Use no event codes when the metric has one dimension. Expect kOK.
  ASSERT_EQ(StatusCode::OK,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {}, "", 5123)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0, "", 5123,
                                            observation_store_.get(), update_recipient_.get()));
  // Clear the FakeObservationStore.
  ResetObservationStore();

  // Use two event codes when the metric has one dimension. Expect
  // StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(
      StatusCode::INVALID_ARGUMENT,
      LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {45, 46}, "", 5123)
          .error_code());

  // There is no max_event_code set so only the specified code of 45 is allowed.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {44}, "", 5123)
                .error_code());

  // All good
  ASSERT_EQ(StatusCode::OK,
            LogFrameRate(testing::all_report_types::kLoginModuleFrameRateMetricId, {45}, "", 5123)
                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 45u, "", 5123,
                                            observation_store_.get(), update_recipient_.get()));
}

// Tests the MemoryUsageEventLogger.
TEST_F(MemoryUsageEventLoggerTest, Log) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageAggregatedReportId,
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageHistogramReportId};

  // The simple version of LogMemoryUsage() can be used, even though the metric has two dimensions.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {46}, "component6", 606)
                                .error_code());

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 46, "component6", 606,
                                            observation_store_.get(), update_recipient_.get()));
}

// Tests the MemoryUsageEventLogger with multiple event codes.
TEST_F(MemoryUsageEventLoggerTest, LogMultiDimension) {
  std::vector<uint32_t> expected_report_ids = {
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageAggregatedReportId,
      testing::all_report_types::kLedgerMemoryUsageLedgerMemoryUsageHistogramReportId};

  // Use a metric ID for the wrong type of metric. Expect StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogMemoryUsage(testing::all_report_types::kLoginModuleFrameRateMetricId, {45, 46},
                           "component6", 606)
                .error_code());

  // Use no event codes when the metric has two dimension. Expect kOK.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {}, "component6", 606)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 0, "component6", 606,
                                            observation_store_.get(), update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // Use one event code when the metric has two dimension. Expect kOK.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {45}, "component6", 606)
                                .error_code());
  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, 45u, "component6", 606,
                                            observation_store_.get(), update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // Use three event codes when the metric has two dimension. Expect
  // StatusCode::INVALID_ARGUMENT.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId, {45, 46, 47},
                           "component6", 606)
                .error_code());

  // There is no max_event_code set for the second dimension so only the
  // specified codes of 1 or 46 are allowed.
  ASSERT_EQ(StatusCode::INVALID_ARGUMENT,
            LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId, {1, 45},
                           "component6", 606)
                .error_code());

  // All good
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {1, 46}, "component6", 606)
                                .error_code());
  uint64_t expected_packed_event_code = (1) | (46 << 10);

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, expected_packed_event_code,
                                            "component6", 606, observation_store_.get(),
                                            update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();

  // No problem with the first event code being zero.
  ASSERT_EQ(StatusCode::OK, LogMemoryUsage(testing::all_report_types::kLedgerMemoryUsageMetricId,
                                           {0, 46}, "component6", 606)
                                .error_code());
  expected_packed_event_code = (0) | (46 << 10);

  EXPECT_TRUE(CheckNumericEventObservations(expected_report_ids, expected_packed_event_code,
                                            "component6", 606, observation_store_.get(),
                                            update_recipient_.get()));
}

// Tests the IntHistogramEventLogger.
TEST_F(IntHistogramEventLoggerTest, Log) {
  std::vector<uint32_t> indices = {0, 1, 2, 3};
  std::vector<uint32_t> counts = {100, 101, 102, 103};

  ASSERT_EQ(StatusCode::OK,
            LogIntHistogram(testing::all_report_types::kFileSystemWriteTimesMetricId, {47},
                            "component7", indices, counts)
                .error_code());
  Observation observation;
  uint32_t expected_report_id =
      testing::all_report_types::kFileSystemWriteTimesFileSystemWriteTimesHistogramReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, observation_store_.get(),
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_histogram());
  auto histogram_observation = observation.histogram();
  EXPECT_EQ(47u, histogram_observation.event_code());
  EXPECT_EQ(histogram_observation.component_name_hash().size(), 32u);
  EXPECT_EQ(static_cast<size_t>(histogram_observation.buckets_size()), indices.size());
  for (int i = 0; i < indices.size(); i++) {
    const auto& bucket = histogram_observation.buckets(i);
    EXPECT_EQ(bucket.index(), indices[i]);
    EXPECT_EQ(bucket.count(), counts[i]);
  }
}

// Tests the CustomEventLogger.
TEST_F(CustomEventLoggerTest, LogCustomEvent) {
  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};
  ASSERT_EQ(StatusCode::OK, LogCustomEvent(testing::all_report_types::kModuleInstallsMetricId,
                                           dimension_names, values)
                                .error_code());
  Observation observation;
  uint32_t expected_report_id =
      testing::all_report_types::kModuleInstallsModuleInstallsDetailedDataReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, observation_store_.get(),
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_custom());
  const CustomObservation& custom_observation = observation.custom();
  for (auto i = 0u; i < values.size(); i++) {
    auto obs_dimension = custom_observation.values().at(dimension_names[i]);
#ifdef PROTO_LITE
#else
    EXPECT_TRUE(MessageDifferencer::Equals(obs_dimension, values[i]));
#endif
  }
}

TEST_F(CustomEventLoggerTest, LogSerializedCustomEvent) {
  std::string serialized_proto = "serialized proto";
  ASSERT_EQ(
      StatusCode::OK,
      LogSerializedCustomEvent(testing::all_report_types::kModuleInstallsMetricId, serialized_proto)
          .error_code());
  Observation observation;
  uint32_t expected_report_id =
      testing::all_report_types::kModuleInstallsModuleInstallsDetailedDataReportId;
  ASSERT_TRUE(FetchSingleObservation(&observation, expected_report_id, observation_store_.get(),
                                     update_recipient_.get()));
  ASSERT_TRUE(observation.has_custom());
  EXPECT_EQ(observation.custom().serialized_proto(), serialized_proto);
}

// Tests that UniqueActivesObservations with the expected values are generated
// when no events have been logged.
TEST_F(UniqueActivesLoggerTest, CheckUniqueActivesObsValuesNoEvents) {
  const auto current_day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Generate locally aggregated Observations without logging any events.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((current_day_index)).error_code());
  // Check that all generated Observations are of non-activity.
  auto expected_obs =
      MakeNullExpectedUniqueActivesObservations(expected_aggregation_params_, current_day_index);
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                             update_recipient_.get()));
}

// Tests that UniqueActivesObservations with the expected values are generated
// when events have been logged for UNIQUE_N_DAY_ACTIVES reports on a single
// day.
TEST_F(UniqueActivesLoggerTest, CheckUniqueActivesObsValuesSingleDay) {
  const auto current_day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Log 2 occurrences of event code 0 for the DeviceBoots metric, which has 1
  // locally aggregated report and no immediate reports.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kDeviceBootsMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kDeviceBootsMetricId, 0).error_code());
  // Log 2 occurrences of different event codes for the SomeFeaturesActive
  // metric, which has 1 locally aggregated report and no immediate reports.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kFeaturesActiveMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::unique_actives_noise_free::kFeaturesActiveMetricId, 1).error_code());
  // Generate locally aggregated observations for the current day index.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((current_day_index)).error_code());
  // Form the expected observations for the current day index.
  auto expected_obs =
      MakeNullExpectedUniqueActivesObservations(expected_aggregation_params_, current_day_index);
  expected_obs[{testing::unique_actives_noise_free::kDeviceBootsMetricReportId,
                current_day_index}] = {{1, {true, false}}};
  expected_obs[{testing::unique_actives_noise_free::kFeaturesActiveMetricReportId,
                current_day_index}] = {{1, {true, true, false, false, false}},
                                       {7, {true, true, false, false, false}},
                                       {28, {true, true, false, false, false}},
                                       {30, {true, true, false, false, false}}};
  // Check that the expected aggregated observations were generated.
  EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs, observation_store_.get(),
                                             update_recipient_.get()));
}

// Tests that UniqueActivesObservations with the expected values are generated
// when events have been logged for a UniqueActives report over multiple days.
//
// Logs events for the EventsOccurred_UniqueDevices report (whose parent metric
// has max_event_code = 5, and whose report ID is 401) for 10 days, according to
// the following pattern:
//
// * Never log event code 0.
// * On the i-th day (0-indexed) of logging, log an event for event code k,
//   1 <= k < 5, if 3*k divides i.
//
// Each day following the first day, generates Observations for the previous
// day index and checks them against the expected set of Observations, then
// garbage-collects the LocalAggregateStore for the current day index.
//
// The EventsOccurred_UniqueDevices report has window sizes 1 and 7, and
// the expected pattern of those Observations' values on the i-th day is:
//
// (i, window size)            active for event codes
// ------------------------------------------------------
// (0, 1)                           1, 2, 3, 4
// (0, 7)                           1, 2, 3, 4
// (1, 1)                          ---
// (1, 7)                           1, 2, 3, 4
// (2, 1)                          ---
// (2, 7)                           1, 2, 3, 4
// (3, 1)                           1
// (3, 7)                           1, 2, 3, 4
// (4, 1)                          ---
// (4, 7)                           1, 2, 3, 4
// (5, 1)                          ---
// (5, 7)                           1, 2, 3, 4
// (6, 1)                           1, 2
// (6, 7)                           1, 2, 3, 4
// (7, 1)                          ---
// (7, 7)                           1, 2
// (8, 1)                          ---
// (8, 7)                           1, 2
// (9, 1)                           1, 3
// (9, 7)                           1, 2, 3
//
// All Observations for all other locally aggregated reports should be
// observations of non-occurrence.
TEST_F(UniqueActivesLoggerTest, CheckUniqueActivesObsValuesMultiDay) {
  const auto& expected_id = testing::unique_actives_noise_free::kEventsOccurredMetricReportId;
  const auto start_day_index = CurrentDayIndex(MetricDefinition::UTC);

  // Form expected Observations for the 10 days of logging.
  std::vector<ExpectedUniqueActivesObservations> expected_obs(10);
  for (uint32_t i = 0; i < expected_obs.size(); i++) {
    expected_obs[i] = MakeNullExpectedUniqueActivesObservations(expected_aggregation_params_,
                                                                start_day_index + i);
  }
  expected_obs[0][{expected_id, start_day_index}] = {{1, {false, true, true, true, true}},
                                                     {7, {false, true, true, true, true}}};
  expected_obs[1][{expected_id, start_day_index + 1}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[2][{expected_id, start_day_index + 2}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[3][{expected_id, start_day_index + 3}] = {{1, {false, true, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[4][{expected_id, start_day_index + 4}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[5][{expected_id, start_day_index + 5}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[6][{expected_id, start_day_index + 6}] = {{1, {false, true, true, false, false}},
                                                         {7, {false, true, true, true, true}}};
  expected_obs[7][{expected_id, start_day_index + 7}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, false, false}}};
  expected_obs[8][{expected_id, start_day_index + 8}] = {{1, {false, false, false, false, false}},
                                                         {7, {false, true, true, false, false}}};
  expected_obs[9][{expected_id, start_day_index + 9}] = {{1, {false, true, false, true, false}},
                                                         {7, {false, true, true, true, false}}};

  for (uint32_t i = 0; i < 10; i++) {
    if (i < 10) {
      for (uint32_t event_code = 1; event_code < 5; event_code++) {
        if (i % (3 * event_code) == 0) {
          ASSERT_EQ(
              StatusCode::OK,
              LogEvent(testing::unique_actives_noise_free::kEventsOccurredMetricId, event_code)
                  .error_code());
        }
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Advance the Logger's clock by 1 day.
    AdvanceDay(1);
    // Generate locally aggregated Observations for the previous day
    // index.
    ASSERT_EQ(
        StatusCode::OK,
        event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC) - 1))
            .error_code());
    // Check the generated Observations against the expectation.
    EXPECT_TRUE(CheckUniqueActivesObservations(expected_obs[i], observation_store_.get(),
                                               update_recipient_.get()));
    // Garbage-collect the LocalAggregateStore for the current day index.
    ASSERT_EQ(
        StatusCode::OK,
        event_aggregator_mgr_->GarbageCollect(CurrentDayIndex(MetricDefinition::UTC)).error_code());
  }
}

// Generate Observations without logging any events, and check that the
// resulting Observations are as expected: 1 ReportParticipationObservation for
// each PER_DEVICE_NUMERIC_STATS report in the config, and no
// PerDeviceNumericObservations.
TEST_F(PerDeviceNumericEventCountEventLoggerTest, CheckPerDeviceNumericObsValuesNoEvents) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  const auto& expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  EXPECT_TRUE(CheckPerDeviceNumericObservations({}, expected_report_participation_obs,
                                                observation_store_.get(), update_recipient_.get()));
}

// Tests that Observations with the expected values are generated when events
// have been logged for EVENT_COUNT metrics with a PER_DEVICE_NUMERIC_STATS
// report, on a single day.
TEST_F(PerDeviceNumericEventCountEventLoggerTest, CheckPerDeviceNumericObsValuesSingleDay) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);

  // Log several events on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {0},
                          "component_A", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {0},
                          "component_B", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {0},
                          "component_A", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kConnectionFailuresMetricId, {1},
                          "component_A", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId, {0},
                          "component_C", 0, 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId, {0},
                          "component_C", 0, 5)
                .error_code());
  // The ConnectionFailures metric has an immediate report of type
  // EVENT_COMPONENT_OCCURRENCE_COUNT. Check that 4 immediate Observations were
  // generated for that report.
  std::vector<Observation> immediate_observations(4);
  std::vector<uint32_t> expected_immediate_report_ids(
      4,
      testing::per_device_numeric_stats::kConnectionFailuresConnectionFailuresGlobalCountReportId);
  EXPECT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                observation_store_.get(), update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  // Form the expected locally aggregated Observations.
  auto expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kConnectionFailuresMetricReportId, day_index}][1] = {
      {"component_A", 0u, 10}, {"component_A", 1u, 5}, {"component_B", 0u, 5}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId, day_index}][7] =
      {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId, day_index}][30] =
      {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId,
      day_index}][7] = {{"component_C", 0u, 10}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId,
      day_index}][30] = {{"component_C", 0u, 10}};
  EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs,
                                                expected_report_participation_obs,
                                                observation_store_.get(), update_recipient_.get()));
}

// Tests that Observations with the expected values are generated when events
// have been logged for a FRAME_RATE metric with a PER_DEVICE_NUMERIC_STATS
// report, on a single day.
TEST_F(PerDeviceNumericFrameRateEventLoggerTest, CheckPerDeviceNumericObsValuesFrameRateSingleDay) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Log several events on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_A", 5000)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_B", 4200)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_A", 3750)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {1},
                         "component_A", 2000)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_C", 7900)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogFrameRate(testing::per_device_numeric_stats::kLoginModuleFrameRateMetricId, {0},
                         "component_C", 4000)
                .error_code());
  // The LoginModuleFrameRate metric has an immediate report of type
  // NUMERIC_AGGREGATION. Check that 6 immediate Observations were
  // generated for that report.
  std::vector<Observation> immediate_observations(6);
  std::vector<uint32_t> expected_immediate_report_ids(
      6, testing::per_device_numeric_stats::
             kLoginModuleFrameRateLoginModuleFrameRateAggregatedReportId);
  EXPECT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                observation_store_.get(), update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  // Form the expected locally aggregated Observations.
  auto expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLoginModuleFrameRateMinMetricReportId, day_index}][1] = {
      {"component_A", 0u, 3750},
      {"component_A", 1u, 2000},
      {"component_B", 0u, 4200},
      {"component_C", 0u, 4000}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLoginModuleFrameRateMinMetricReportId, day_index}][7] = {
      {"component_A", 0u, 3750},
      {"component_A", 1u, 2000},
      {"component_B", 0u, 4200},
      {"component_C", 0u, 4000}};
  EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs,
                                                expected_report_participation_obs,
                                                observation_store_.get(), update_recipient_.get()));
}

// Tests that Observations with the expected values are generated when events
// have been logged for a MEMORY_USAGE metric with a PER_DEVICE_NUMERIC_STATS
// report, on a single day.
TEST_F(PerDeviceNumericMemoryUsageEventLoggerTest,
       CheckPerDeviceNumericObsValuesMemoryUsageSingleDay) {
  const auto day_index = CurrentDayIndex(MetricDefinition::UTC);
  // Log several events on |day_index|.
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_A", 5)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_B", 4)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_A", 3)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{1u, 0u}, "component_A", 2)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_C", 7)
                .error_code());
  EXPECT_EQ(StatusCode::OK,
            LogMemoryUsage(testing::per_device_numeric_stats::kLedgerMemoryUsageMetricId,
                           std::vector<uint32_t>{0u, 0u}, "component_C", 4)
                .error_code());
  // The LedgerMemoryUsage metric has an immediate report of type
  // NUMERIC_AGGREGATION. Check that 6 immediate Observations were
  // generated for that report.
  std::vector<Observation> immediate_observations(6);
  std::vector<uint32_t> expected_immediate_report_ids(
      6, testing::per_device_numeric_stats::kLedgerMemoryUsageLedgerMemoryUsageAggregatedReportId);
  EXPECT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                observation_store_.get(), update_recipient_.get()));

  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated Observations for |day_index|.
  EXPECT_EQ(StatusCode::OK, event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
  // Form the expected locally aggregated Observations.
  auto expected_report_participation_obs = MakeExpectedReportParticipationObservations(
      testing::per_device_numeric_stats::kExpectedAggregationParams, day_index);
  ExpectedPerDeviceNumericObservations expected_per_device_numeric_obs;
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLedgerMemoryUsageMaxMetricReportId, day_index}][1] = {
      {"component_A", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 5},
      {"component_A", PackEventCodes(std::vector<uint32_t>{1u, 0u}), 2},
      {"component_B", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 4},
      {"component_C", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 7}};
  expected_per_device_numeric_obs[{
      testing::per_device_numeric_stats::kLedgerMemoryUsageMaxMetricReportId, day_index}][7] = {
      {"component_A", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 5},
      {"component_A", PackEventCodes(std::vector<uint32_t>{1u, 0u}), 2},
      {"component_B", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 4},
      {"component_C", PackEventCodes(std::vector<uint32_t>{0u, 0u}), 7}};

  EXPECT_TRUE(CheckPerDeviceNumericObservations(expected_per_device_numeric_obs,
                                                expected_report_participation_obs,
                                                observation_store_.get(), update_recipient_.get()));
}

// Checks that PerDeviceNumericObservations with the expected values are
// generated when some events have been logged for an EVENT_COUNT metric with a
// PER_DEVICE_NUMERIC_STATS report over multiple days and
// GenerateAggregatedObservations(() is called each day).
//
// Logged events for the SettingsChanged_PerDeviceCount metric on the i-th day:
//
//  i            (component, event code, count)
// -----------------------------------------------------------------------
//  0
//  1          ("A", 1, 3)
//  2          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  3          ("A", 1, 3)
//  4          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//  5          ("A", 1, 3)
//  6          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  7          ("A", 1, 3)
//  8          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//  9          ("A", 1, 3)
//
// Expected PerDeviceNumericObservations for the SettingsChanged_PerDeviceCount
// report on the i-th day:
//
// (i, window size)          (component, event code, count)
// -----------------------------------------------------------------------
// (0, 7)
// (0, 30)
// (1, 7)     ("A", 1,  3)
// (1, 30)    ("A", 1,  3)
// (2, 7)     ("A", 1,  6),  ("A", 2,  3), ("B", 1, 2)
// (2, 30)    ("A", 1,  6),  ("A", 2,  3), ("B", 1, 2)
// (3, 7)     ("A", 1,  9),  ("A", 2,  3), ("B", 1, 2)
// (3, 30)    ("A", 1,  9),  ("A", 2,  3), ("B", 1, 2)
// (4, 7)     ("A", 1, 12),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (4, 30)    ("A", 1, 12),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (5, 7)     ("A", 1, 15),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (5, 30)    ("A", 1, 15),  ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (6, 7)     ("A", 1, 18),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (6, 30)    ("A", 1, 18),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (7, 7)     ("A", 1, 21),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (7, 30)    ("A", 1, 21),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (8, 7)     ("A", 1, 21),  ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
// (8, 30)    ("A", 1, 24),  ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
// (9, 7)     ("A", 1, 21),  ("A", 2,  9), ("B", 1, 6), ("B", 2, 4)
// (9, 30)    ("A", 1, 27),  ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
//
// In addition, expect 1 ReportParticipationObservations for each day, for each
// report in the registry.
TEST_F(PerDeviceNumericEventCountEventLoggerTest, CheckPerDeviceNumericObsValuesMultiDay) {
  const auto start_day_index = CurrentDayIndex(MetricDefinition::UTC);
  std::vector<MetricReportId> expected_ids = {
      testing::per_device_numeric_stats::kSettingsChangedWindowSizeMetricReportId,
      testing::per_device_numeric_stats::kSettingsChangedAggregationWindowMetricReportId};
  // Form expected Observations for the 10 days of logging.
  uint32_t num_days = 10;
  std::vector<ExpectedPerDeviceNumericObservations> expected_per_device_numeric_obs(num_days);
  std::vector<ExpectedReportParticipationObservations> expected_report_participation_obs(num_days);
  for (uint32_t offset = 0; offset < num_days; offset++) {
    expected_report_participation_obs[offset] = MakeExpectedReportParticipationObservations(
        expected_aggregation_params_, start_day_index + offset);
  }
  expected_per_device_numeric_obs[0] = {};
  for (auto expected_id : expected_ids) {
    expected_per_device_numeric_obs[1][{expected_id, start_day_index + 1}] = {{7, {{"A", 1u, 3}}},
                                                                              {30, {{"A", 1u, 3}}}};
    expected_per_device_numeric_obs[2][{expected_id, start_day_index + 2}] = {
        {7, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}},
        {30, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}}};
    expected_per_device_numeric_obs[3][{expected_id, start_day_index + 3}] = {
        {7, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}},
        {30, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}}};
    expected_per_device_numeric_obs[4][{expected_id, start_day_index + 4}] = {
        {7, {{"A", 1u, 12}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 12}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[5][{expected_id, start_day_index + 5}] = {
        {7, {{"A", 1u, 15}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 15}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[6][{expected_id, start_day_index + 6}] = {
        {7, {{"A", 1u, 18}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 18}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[7][{expected_id, start_day_index + 7}] = {
        {7, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}},
        {30, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
    expected_per_device_numeric_obs[8][{expected_id, start_day_index + 8}] = {
        {7, {{"A", 1u, 21}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}},
        {30, {{"A", 1u, 24}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}}};
    expected_per_device_numeric_obs[9][{expected_id, start_day_index + 9}] = {
        {7, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 4}}},
        {30, {{"A", 1u, 27}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}}};
  }
  for (uint32_t offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex(MetricDefinition::UTC);
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && offset % event_code == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId,
                                {event_code}, "A", 0, 3)
                      .error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogEventCount(testing::per_device_numeric_stats::kSettingsChangedMetricId,
                                {event_code}, "B", 0, 2)
                      .error_code());
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations.
    EXPECT_EQ(StatusCode::OK,
              event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
    EXPECT_TRUE(CheckPerDeviceNumericObservations(
        expected_per_device_numeric_obs[offset], expected_report_participation_obs[offset],
        observation_store_.get(), update_recipient_.get()))
        << "offset = " << offset;
    AdvanceDay(1);
  }
}

// Tests that the expected Observations are generated when events are logged for
// over multiple days for an ELAPSED_TIME metric with PER_DEVICE_NUMERIC_STATS
// reports with multiple aggregation types, when Observations are backfilled for
// some days during that period, and when the LocalAggregatedStore is
// garbage-collected after each call to GenerateObservations().
//
// Logged events for the StreamingTime metric on the i-th day:
//
//  i            (component, event code, count)
// -----------------------------------------------------------------------
//  0
//  1          ("A", 1, 3)
//  2          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  3          ("A", 1, 3)
//  4          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//  5          ("A", 1, 3)
//  6          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
//  7          ("A", 1, 3)
//  8          ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//
// Expected PerDeviceNumericObservations for the
// StreamingTime_PerDeviceTotal report on the i-th day:
//
// (day, window size)            (event code, component, total)
// ---------------------------------------------------------------------------
// (0, 1)
// (0, 7)
// (1, 1)     ("A", 1,  3)
// (1, 7)     ("A", 1,  3)
// (2, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2)
// (2, 7)     ("A", 1,  6), ("A", 2,  3), ("B", 1, 2)
// (3, 1)     ("A", 1,  3)
// (3, 7)     ("A", 1,  9), ("A", 2,  3), ("B", 1, 2)
// (4, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2), ("B", 2, 2)
// (4, 7)     ("A", 1, 12), ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (5, 1)     ("A", 1,  3)
// (5, 7)     ("A", 1, 15), ("A", 2,  6), ("B", 1, 4), ("B", 2, 2)
// (6, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2)
// (6, 7)     ("A", 1, 18), ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (7, 1)     ("A", 1,  3)
// (7, 7)     ("A", 1, 21), ("A", 2,  9), ("B", 1, 6), ("B", 2, 2)
// (8, 1)     ("A", 1,  3), ("A", 2,  3), ("B", 1, 2), ("B", 2, 2)
// (8, 7)     ("A", 1, 21), ("A", 2, 12), ("B", 1, 8), ("B", 2, 4)
//
//
// Expected PerDeviceNumericObservations for the
// StreamingTime_PerDeviceMin report on the i-th day:
//
// (day, window size)            (event code, component, total)
// ---------------------------------------------------------------------------
// (0, 1)
// (0. 7)
// (1, 1)     ("A", 1, 3)
// (1, 7)     ("A", 1, 3)
// (2, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (2, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (3, 1)     ("A", 1, 3)
// (3, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (4, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (4, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (5, 1)     ("A", 1, 3)
// (5, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (6, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (6, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (7, 1)     ("A", 1, 3)
// (7, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//
// Expected PerDeviceNumericObservations for the
// StreamingTime_PerDeviceMax report on the i-th day:
//
// (day, window size)            (event code, component, total)
// ---------------------------------------------------------------------------
// (0, 1)
// (0. 7)
// (1, 1)     ("A", 1, 3)
// (1, 7)     ("A", 1, 3)
// (2, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (2, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (3, 1)     ("A", 1, 3)
// (3, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (4, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (4, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (5, 1)     ("A", 1, 3)
// (5, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (6, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2)
// (6, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (7, 1)     ("A", 1, 3)
// (7, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 1)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
// (8, 7)     ("A", 1, 3), ("A", 2, 3), ("B", 1, 2), ("B", 2, 2)
//
// In addition, expect 1 ReportParticipationObservation each day for each
// report in the registry.
TEST_F(PerDeviceNumericElapsedTimeEventLoggerTest, ElapsedTimeCheckObservationValues) {
  const auto start_day_index = CurrentDayIndex(MetricDefinition::UTC);
  const auto& total_report_id =
      testing::per_device_numeric_stats::kStreamingTimeTotalMetricReportId;
  const auto& min_report_id = testing::per_device_numeric_stats::kStreamingTimeMinMetricReportId;
  const auto& max_report_id = testing::per_device_numeric_stats::kStreamingTimeMaxMetricReportId;
  // Form expected Observations for the 9 days of logging.
  uint32_t num_days = 9;
  std::vector<ExpectedPerDeviceNumericObservations> expected_per_device_numeric_obs(num_days);
  std::vector<ExpectedReportParticipationObservations> expected_report_participation_obs(num_days);

  for (uint32_t offset = 0; offset < num_days; offset++) {
    expected_report_participation_obs[offset] = MakeExpectedReportParticipationObservations(
        expected_aggregation_params_, start_day_index + offset);
  }
  expected_per_device_numeric_obs[0] = {};
  expected_per_device_numeric_obs[1][{total_report_id, start_day_index + 1}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}}}};
  expected_per_device_numeric_obs[2][{total_report_id, start_day_index + 2}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 6}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[3][{total_report_id, start_day_index + 3}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 9}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[4][{total_report_id, start_day_index + 4}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 12}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[5][{total_report_id, start_day_index + 5}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 15}, {"A", 2u, 6}, {"B", 1u, 4}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[6][{total_report_id, start_day_index + 6}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 18}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[7][{total_report_id, start_day_index + 7}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 21}, {"A", 2u, 9}, {"B", 1u, 6}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[8][{total_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 21}, {"A", 2u, 12}, {"B", 1u, 8}, {"B", 2u, 4}}}};

  expected_per_device_numeric_obs[1][{min_report_id, start_day_index + 1}] = {{1, {{"A", 1u, 3}}},
                                                                              {7, {{"A", 1u, 3}}}};
  expected_per_device_numeric_obs[2][{min_report_id, start_day_index + 2}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[3][{min_report_id, start_day_index + 3}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[4][{min_report_id, start_day_index + 4}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[5][{min_report_id, start_day_index + 5}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[6][{min_report_id, start_day_index + 6}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[7][{min_report_id, start_day_index + 7}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[8][{min_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};

  expected_per_device_numeric_obs[8][{max_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[1][{max_report_id, start_day_index + 1}] = {{1, {{"A", 1u, 3}}},
                                                                              {7, {{"A", 1u, 3}}}};
  expected_per_device_numeric_obs[2][{max_report_id, start_day_index + 2}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[3][{max_report_id, start_day_index + 3}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}}};
  expected_per_device_numeric_obs[4][{max_report_id, start_day_index + 4}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[5][{max_report_id, start_day_index + 5}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[6][{max_report_id, start_day_index + 6}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[7][{max_report_id, start_day_index + 7}] = {
      {1, {{"A", 1u, 3}}}, {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};
  expected_per_device_numeric_obs[8][{max_report_id, start_day_index + 8}] = {
      {1, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}},
      {7, {{"A", 1u, 3}, {"A", 2u, 3}, {"B", 1u, 2}, {"B", 2u, 2}}}};

  for (uint32_t offset = 0; offset < num_days; offset++) {
    auto day_index = CurrentDayIndex(MetricDefinition::UTC);
    for (uint32_t event_code = 1; event_code < 3; event_code++) {
      if (offset > 0 && offset % event_code == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogElapsedTime(testing::per_device_numeric_stats::kStreamingTimeMetricId,
                                 {event_code}, "A", 3)
                      .error_code());
      }
      if (offset > 0 && offset % (2 * event_code) == 0) {
        EXPECT_EQ(StatusCode::OK,
                  LogElapsedTime(testing::per_device_numeric_stats::kStreamingTimeMetricId,
                                 {event_code}, "B", 2)
                      .error_code());
      }
    }
    // Clear the FakeObservationStore.
    ResetObservationStore();
    // Generate locally aggregated Observations.
    EXPECT_EQ(StatusCode::OK,
              event_aggregator_mgr_->GenerateObservations((day_index)).error_code());
    EXPECT_TRUE(CheckPerDeviceNumericObservations(
        expected_per_device_numeric_obs[offset], expected_report_participation_obs[offset],
        observation_store_.get(), update_recipient_.get()))
        << "offset = " << offset;
    AdvanceDay(1);
  }
}

// Tests that the expected number of locally aggregated Observations are
// generated when no events have been logged.
TEST_F(EventOccurredEventLoggerTest, CheckNumAggregatedObsNoEvents) {
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC)))
                .error_code());
  std::vector<Observation> observations(0);
  EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_aggregation_params_,
                                          observation_store_.get(), update_recipient_.get()));
}

// Tests that the expected number of locally aggregated Observations are
// generated when one Event has been logged for a locally aggregated report.
TEST_F(EventOccurredEventLoggerTest, CheckNumAggregatedObsOneEvent) {
  // Log 1 occurrence of event code 0 for the DeviceBoots metric, which has no
  // immediate reports.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kDeviceBootsMetricId, 0).error_code());
  // Check that no immediate Observation was generated.
  std::vector<Observation> immediate_observations(0);
  std::vector<uint32_t> expected_immediate_report_ids = {};
  ASSERT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                observation_store_.get(), update_recipient_.get()));
  // Generate locally aggregated observations for the current day index.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC)))
                .error_code());
  // Check that the expected numbers of aggregated observations were generated.
  std::vector<Observation> aggregated_observations;
  EXPECT_TRUE(FetchAggregatedObservations(&aggregated_observations, expected_aggregation_params_,
                                          observation_store_.get(), update_recipient_.get()));
}

// Tests that the expected number of locally aggregated Observations are
// generated when multiple Events have been logged for locally aggregated
// and immediate reports.
TEST_F(EventOccurredEventLoggerTest, CheckNumAggregatedObsImmediateAndAggregatedEvents) {
  // Log 3 occurrences of event codes for the EventsOccurred metric, which
  // has 1 locally aggregated report and 1 immediate report.
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kEventsOccurredMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kEventsOccurredMetricId, 0).error_code());
  ASSERT_EQ(StatusCode::OK,
            LogEvent(testing::all_report_types::kEventsOccurredMetricId, 2).error_code());
  // Check that each of the 3 logged events resulted in an immediate
  // Observation.
  std::vector<Observation> immediate_observations(3);
  std::vector<uint32_t> expected_immediate_report_ids(
      3, testing::all_report_types::kEventsOccurredEventsOccurredGlobalCountReportId);
  ASSERT_TRUE(FetchObservations(&immediate_observations, expected_immediate_report_ids,
                                observation_store_.get(), update_recipient_.get()));
  // Clear the FakeObservationStore.
  ResetObservationStore();
  // Generate locally aggregated observations for the current day index.
  ASSERT_EQ(StatusCode::OK,
            event_aggregator_mgr_->GenerateObservations((CurrentDayIndex(MetricDefinition::UTC)))
                .error_code());
  // Check that the expected aggregated observations were generated.
  std::vector<Observation> observations;
  EXPECT_TRUE(FetchAggregatedObservations(&observations, expected_aggregation_params_,
                                          observation_store_.get(), update_recipient_.get()));
}

// needed for Friend class status
namespace internal {

class EventLoggersAddEventTest : public util::testing::TestWithFiles {
 public:
  void SetUp() override {
    MakeTestFolder();
    observation_store_ = std::make_unique<FakeObservationStore>();
    update_recipient_ = std::make_unique<TestUpdateRecipient>();
    observation_encrypter_ = EncryptedMessageMaker::MakeUnencrypted();
    observation_writer_ = std::make_unique<ObservationWriter>(
        observation_store_.get(), update_recipient_.get(), observation_encrypter_.get());
    metadata_builder_ =
        std::make_unique<MetadataBuilder>(&system_data_, system_data_cache_path(), fs());
    encoder_ = std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), *metadata_builder_);
    project_context_factory_ =
        GetTestProjectContextFactory(testing::per_device_histogram::kCobaltRegistryBase64);
    project_context_ = GetTestProject(testing::per_device_histogram::kCobaltRegistryBase64);
    // Create a mock clock which does not increment by default when called.
    // Set the time to 1 year after the start of Unix time so that the start
    // date of any aggregation window falls after the start of time.
    mock_clock_ = std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    mock_clock_->set_time(std::chrono::system_clock::time_point(std::chrono::seconds(kYear)));
    civil_time_converter_ = std::make_unique<util::UtcTimeConverter>();
    CobaltConfig cfg = {.client_secret = system_data::ClientSecret::GenerateNewSecret()};

    cfg.local_aggregation_backfill_days = 0;
    cfg.local_aggregate_proto_store_path = aggregate_store_path();
    cfg.obs_history_proto_store_path = obs_history_path();

    event_aggregator_mgr_ = std::make_unique<TestEventAggregatorManager>(
        cfg, fs(), *encoder_, observation_writer_.get(), *metadata_builder_);
    event_aggregator_mgr_->GetEventAggregator().UpdateAggregationConfigs(*project_context_);
    local_aggregation_ = std::make_unique<LocalAggregation>(
        cfg, project_context_factory_.get(), &system_data_, *metadata_builder_, fs(),
        observation_writer_.get(), civil_time_converter_.get());
  }

  std::unique_ptr<EventLogger> GetEventLoggerForMetricType(
      MetricDefinition::MetricType metric_type) {
    auto logger = EventLogger::Create(
        metric_type, *encoder_, event_aggregator_mgr_->GetEventAggregator(),
        local_aggregation_.get(), nullptr, nullptr, civil_time_converter_.get());
    return logger;
  }

  std::unique_ptr<EventRecord> GetEventRecordWithMetricType(
      uint32_t metric_id, MetricDefinition::MetricType metric_type) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();

    switch (metric_type) {
      case (MetricDefinition::EVENT_COUNT): {
        EventCountEvent* event = event_record->event()->mutable_event_count_event();
        event->set_component("test");
        event->set_period_duration_micros(10);
        event->set_count(1);
        break;
      }
      case (MetricDefinition::ELAPSED_TIME): {
        ElapsedTimeEvent* event = event_record->event()->mutable_elapsed_time_event();
        event->set_component("test");
        event->set_elapsed_micros(10);
        break;
      }
      case (MetricDefinition::MEMORY_USAGE): {
        MemoryUsageEvent* event = event_record->event()->mutable_memory_usage_event();
        event->set_component("test");
        event->set_bytes(10);
        break;
      }
      case (MetricDefinition::FRAME_RATE): {
        FrameRateEvent* event = event_record->event()->mutable_frame_rate_event();
        event->set_component("test");
        event->set_frames_per_1000_seconds(10);
        break;
      }
      default: {
      }
    }

    return event_record;
  }

  static ReportDefinition ReportDefinitionWithReportType(uint32_t report_id,
                                                         ReportDefinition::ReportType report_type) {
    ReportDefinition report_definition;
    report_definition.set_report_type(report_type);
    report_definition.set_id(report_id);
    return report_definition;
  }

  static Encoder::Result MaybeEncodeImmediateObservation(EventLogger* event_logger,
                                                         const ReportDefinition& report,
                                                         EventRecord* event_record) {
    return event_logger->MaybeEncodeImmediateObservation(report, /*may_invalidate=*/false,
                                                         event_record);
  }

  static Status MaybeUpdateLocalAggregation(EventLogger* event_logger,
                                            const ReportDefinition& report,
                                            const EventRecord& event_record) {
    return event_logger->MaybeUpdateLocalAggregation(report, event_record);
  }

 protected:
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  system_data::FakeSystemData system_data_;
  std::unique_ptr<IncrementingSystemClock> mock_clock_;
  std::unique_ptr<util::UtcTimeConverter> civil_time_converter_;
  std::unique_ptr<ProjectContextFactory> project_context_factory_;
  std::shared_ptr<ProjectContext> project_context_;
  std::unique_ptr<TestEventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<LocalAggregation> local_aggregation_;
};

TEST_F(EventLoggersAddEventTest, EventCountPerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kSettingsChangedSettingsChangedPerDeviceHistogramReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kSettingsChangedMetricId, MetricDefinition::EVENT_COUNT);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::EVENT_COUNT);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, EventCountPerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kSettingsChangedSettingsChangedPerDeviceHistogramReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kSettingsChangedMetricId, MetricDefinition::EVENT_COUNT);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::EVENT_COUNT);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, ElapsedTimePerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kStreamingTimeStreamingTimePerDeviceTotalReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kStreamingTimeMetricId, MetricDefinition::ELAPSED_TIME);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::ELAPSED_TIME);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, ElapsedTimePerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kStreamingTimeStreamingTimePerDeviceTotalReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kStreamingTimeMetricId, MetricDefinition::ELAPSED_TIME);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::ELAPSED_TIME);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, FrameRatePerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLoginModuleFrameRateLoginModuleFrameRatePerDeviceMinReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLoginModuleFrameRateMetricId, MetricDefinition::FRAME_RATE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::FRAME_RATE);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, FrameRatePerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLoginModuleFrameRateLoginModuleFrameRatePerDeviceMinReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLoginModuleFrameRateMetricId, MetricDefinition::FRAME_RATE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::FRAME_RATE);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, MemoryUsagePerDeviceHistogramNoImmediateObservation) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLedgerMemoryUsageLedgerMemoryUsagePerDeviceMaxReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLedgerMemoryUsageMetricId, MetricDefinition::MEMORY_USAGE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::MEMORY_USAGE);
  auto result = MaybeEncodeImmediateObservation(event_logger.get(), report, event_record.get());

  EXPECT_EQ(StatusCode::OK, result.status.error_code());
  EXPECT_EQ(nullptr, result.observation);
  EXPECT_EQ(nullptr, result.metadata);
  EXPECT_EQ(0, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

TEST_F(EventLoggersAddEventTest, MemoryUsagePerDeviceHistogramAddToEventAggregator) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::per_device_histogram::kLedgerMemoryUsageLedgerMemoryUsagePerDeviceMaxReportId,
      ReportDefinition::PER_DEVICE_HISTOGRAM);
  auto event_record = GetEventRecordWithMetricType(
      testing::per_device_histogram::kLedgerMemoryUsageMetricId, MetricDefinition::MEMORY_USAGE);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::MEMORY_USAGE);
  auto status = MaybeUpdateLocalAggregation(event_logger.get(), report, *event_record);

  EXPECT_EQ(StatusCode::OK, status.error_code());
  EXPECT_EQ(1, event_aggregator_mgr_->NumPerDeviceNumericAggregatesInStore());
}

class EventLoggersLocalAggregationTest : public util::testing::TestWithFiles {
 public:
  void SetUp() override {
    MakeTestFolder();
    observation_store_ = std::make_unique<FakeObservationStore>();
    update_recipient_ = std::make_unique<TestUpdateRecipient>();
    observation_encrypter_ = EncryptedMessageMaker::MakeUnencrypted();
    observation_writer_ = std::make_unique<ObservationWriter>(
        observation_store_.get(), update_recipient_.get(), observation_encrypter_.get());
    metadata_builder_ =
        std::make_unique<MetadataBuilder>(&system_data_, system_data_cache_path(), fs());
    encoder_ = std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), *metadata_builder_);
    project_context_factory_ =
        GetTestProjectContextFactory(testing::cobalt_new::kCobaltRegistryBase64);
    project_context_ = GetTestProject(testing::cobalt_new::kCobaltRegistryBase64);
    // Create a mock clock which does not increment by default when called.
    // Set the time to 1 year after the start of Unix time so that the start
    // date of any aggregation window falls after the start of time.
    mock_clock_ = std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    start_time_ = std::chrono::system_clock::time_point(std::chrono::seconds(kYear));
    mock_clock_->set_time(start_time_);
    // Set the test local time converter to switch time zones 1 hour after `start_time_`.
    // This should only affect metrics with the OTHER_TIME_ZONE TimeZonePolicy.
    civil_time_converter_ = std::make_unique<util::FakeCivilTimeConverter>(
        /*start_utc_offset=*/0, /*start_isdst=*/false, /*end_utc_offset=*/1, /*end_isdst=*/true,
        /*threshold=*/start_time_ + util::kOneHour);

    CobaltConfig cfg = {.client_secret = system_data::ClientSecret::GenerateNewSecret()};

    cfg.local_aggregation_backfill_days = 0;
    cfg.local_aggregate_proto_store_path = aggregate_store_path();
    cfg.obs_history_proto_store_path = obs_history_path();
    cfg.local_aggregate_store_dir = local_aggregation_store_path();

    event_aggregator_mgr_ = std::make_unique<TestEventAggregatorManager>(
        cfg, fs(), *encoder_, observation_writer_.get(), *metadata_builder_);
    event_aggregator_mgr_->GetEventAggregator().UpdateAggregationConfigs(*project_context_);
    local_aggregation_ = std::make_unique<LocalAggregation>(
        cfg, project_context_factory_.get(), &system_data_, *metadata_builder_, fs(),
        observation_writer_.get(), civil_time_converter_.get());
  }

  local_aggregation::ImmediateLocalAggregateStorage GetLocalAggregateStorage() {
    return local_aggregation::ImmediateLocalAggregateStorage(local_aggregation_store_path(), fs(),
                                                             project_context_factory_.get(),
                                                             *metadata_builder_, 0);
  }

  local_aggregation::ReportAggregate GetReportAggregate(
      uint32_t metric_id, MetricDefinition::MetricType metric_type, uint32_t report_id,
      local_aggregation::LocalAggregateStorage* store) {
    std::unique_ptr<EventRecord> event_record =
        GetEventRecordWithMetricType(metric_id, metric_type);
    local_aggregation::LocalAggregateStorage::MetricAggregateRef aggregate =
        store->GetMetricAggregate(event_record->MetricIdentifier()).ConsumeValueOrDie();
    return aggregate.aggregate()->by_report_id().at(report_id);
  }

  std::unique_ptr<EventLogger> GetEventLoggerForMetricType(
      MetricDefinition::MetricType metric_type) {
    auto logger = EventLogger::Create(
        metric_type, *encoder_, event_aggregator_mgr_->GetEventAggregator(),
        local_aggregation_.get(), nullptr, nullptr, civil_time_converter_.get());
    return logger;
  }

  std::unique_ptr<EventRecord> GetEventRecordWithMetricType(
      uint32_t metric_id, MetricDefinition::MetricType metric_type) {
    auto event_record = EventRecord::MakeEventRecord(project_context_, metric_id).ValueOrDie();

    switch (metric_type) {
      case (MetricDefinition::OCCURRENCE): {
        OccurrenceEvent* event = event_record->event()->mutable_occurrence_event();
        event->set_count(1);
        break;
      }
      case (MetricDefinition::INTEGER): {
        IntegerEvent* event = event_record->event()->mutable_integer_event();
        event->set_value(10);
        break;
      }
      case (MetricDefinition::INTEGER_HISTOGRAM): {
        IntegerHistogramEvent* event = event_record->event()->mutable_integer_histogram_event();
        event->mutable_buckets()->Swap(
            testing::NewHistogram({0, 1, 2, 3}, {100, 101, 102, 103}).get());
        break;
      }
      case (MetricDefinition::STRING): {
        StringEvent* event = event_record->event()->mutable_string_event();
        event->set_string_value("component4");
        break;
      }
      default: {
      }
    }

    return event_record;
  }

  static ReportDefinition ReportDefinitionWithReportType(uint32_t report_id,
                                                         ReportDefinition::ReportType report_type) {
    ReportDefinition report_definition;
    report_definition.set_report_type(report_type);
    report_definition.set_id(report_id);
    return report_definition;
  }

  static Status MaybeUpdateLocalAggregation(EventLogger* event_logger,
                                            const ReportDefinition& report,
                                            const EventRecord& event_record) {
    return event_logger->MaybeUpdateLocalAggregation(report, event_record);
  }

 protected:
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  system_data::FakeSystemData system_data_;
  std::unique_ptr<IncrementingSystemClock> mock_clock_;
  std::chrono::system_clock::time_point start_time_;
  std::unique_ptr<util::FakeCivilTimeConverter> civil_time_converter_;
  std::unique_ptr<ProjectContextFactory> project_context_factory_;
  std::shared_ptr<ProjectContext> project_context_;
  std::unique_ptr<TestEventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<LocalAggregation> local_aggregation_;
};

TEST_F(EventLoggersLocalAggregationTest, OccurrenceUniqueDeviceHistogramsValidation) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                                   MetricDefinition::OCCURRENCE);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kSettingsChangedMetricId,
                                          MetricDefinition::OCCURRENCE, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, OccurrenceUniqueDeviceHistogramsValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                                   MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kSettingsChangedMetricId,
                                          MetricDefinition::OCCURRENCE, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, OccurrenceUniqueDeviceHistograms) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kSettingsChangedSettingsChangedUniqueDeviceHistogramsReportId,
      ReportDefinition::UNIQUE_DEVICE_HISTOGRAMS);
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                                   MetricDefinition::OCCURRENCE);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kSettingsChangedMetricId,
                                              MetricDefinition::OCCURRENCE);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kSettingsChangedMetricId, MetricDefinition::OCCURRENCE,
      testing::cobalt_new::kSettingsChangedSettingsChangedUniqueDeviceHistogramsReportId, &store);
  ASSERT_TRUE(report_aggregate.has_daily());
  local_aggregation::AggregationPeriodBucket daily_bucket =
      report_aggregate.daily().by_day_index().begin()->second;
  local_aggregation::AggregateData data =
      daily_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  EXPECT_EQ(data.count(), 1);
}

TEST_F(EventLoggersLocalAggregationTest, IntegerFleetwideMeansValidation) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                                   MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kStreamingTimeMetricId,
                                          MetricDefinition::INTEGER, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerFleetwideMeansValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                                   MetricDefinition::OCCURRENCE);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kStreamingTimeMetricId,
                                          MetricDefinition::INTEGER, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerFleetwideMeans) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kStreamingTimeStreamingTimeAggregationReportId,
      ReportDefinition::FLEETWIDE_MEANS);
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                                   MetricDefinition::INTEGER);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kStreamingTimeMetricId,
                                              MetricDefinition::INTEGER);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kStreamingTimeMetricId, MetricDefinition::INTEGER,
      testing::cobalt_new::kStreamingTimeStreamingTimeAggregationReportId, &store);
  ASSERT_TRUE(report_aggregate.has_hourly());
  local_aggregation::AggregationPeriodBucket hourly_bucket =
      report_aggregate.hourly().by_hour_id().begin()->second;
  local_aggregation::AggregateData data =
      hourly_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  ASSERT_TRUE(data.has_sum_and_count());
  EXPECT_EQ(data.sum_and_count().sum(), 10);
}

TEST_F(EventLoggersLocalAggregationTest, IntegerHistogramFleetwideHistogramsValidation) {
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                          MetricDefinition::INTEGER_HISTOGRAM, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerHistogramFleetwideHistogramsValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                          MetricDefinition::INTEGER_HISTOGRAM, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest,
       IntegerHistogramFleetwideHistogramsValidationWrongBuckets) {
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM);
  // Replace with a histogram containing an invalid bucket index. The metric FileSystemWriteTimes
  // has a num_buckets = 10, with 0 being the underflow bucket and 10+1=11 being the overflow
  // bucket. So the first invalid bucket index is 12.
  event_record->event()->mutable_integer_histogram_event()->mutable_buckets()->Swap(
      testing::NewHistogram({0, 1, 2, 12}, {100, 101, 102, 103}).get());
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                          MetricDefinition::INTEGER_HISTOGRAM, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, IntegerHistogramFleetwideHistograms) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kFileSystemWriteTimesFileSystemWriteTimesHistogramReportId,
      ReportDefinition::FLEETWIDE_HISTOGRAMS);
  auto event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::INTEGER_HISTOGRAM);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kFileSystemWriteTimesMetricId,
                                              MetricDefinition::INTEGER_HISTOGRAM);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kFileSystemWriteTimesMetricId, MetricDefinition::INTEGER_HISTOGRAM,
      testing::cobalt_new::kFileSystemWriteTimesFileSystemWriteTimesHistogramReportId, &store);
  ASSERT_TRUE(report_aggregate.has_hourly());
  local_aggregation::AggregationPeriodBucket hourly_bucket =
      report_aggregate.hourly().by_hour_id().begin()->second;
  local_aggregation::AggregateData data =
      hourly_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  ASSERT_TRUE(data.has_integer_histogram());
  const auto& histogram = data.integer_histogram();
  EXPECT_EQ(histogram.histogram().at(0), 100);
  EXPECT_EQ(histogram.histogram().at(1), 101);
  EXPECT_EQ(histogram.histogram().at(2), 102);
  EXPECT_EQ(histogram.histogram().at(3), 103);
}

TEST_F(EventLoggersLocalAggregationTest, StringStringHistogramsValidation) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                                   MetricDefinition::STRING);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::STRING);
  EXPECT_EQ(StatusCode::OK,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kComponentMetricId,
                                          MetricDefinition::STRING, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, StringStringHistogramsValidationWrongType) {
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                                   MetricDefinition::INTEGER);
  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::STRING);
  EXPECT_EQ(StatusCode::INVALID_ARGUMENT,
            event_logger
                ->PrepareAndValidateEvent(testing::cobalt_new::kComponentMetricId,
                                          MetricDefinition::STRING, event_record.get())
                .error_code());
}

TEST_F(EventLoggersLocalAggregationTest, StringStringHistograms) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kComponentComponentHistogramReportId, ReportDefinition::STRING_COUNTS);
  auto event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                                   MetricDefinition::STRING);

  auto event_logger = GetEventLoggerForMetricType(MetricDefinition::STRING);
  EXPECT_EQ(
      StatusCode::OK,
      event_logger->Log(std::move(event_record), std::chrono::system_clock::now()).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kComponentMetricId,
                                              MetricDefinition::STRING);
  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate =
      GetReportAggregate(testing::cobalt_new::kComponentMetricId, MetricDefinition::STRING,
                         testing::cobalt_new::kComponentComponentHistogramReportId, &store);
  ASSERT_TRUE(report_aggregate.has_hourly());
  local_aggregation::AggregationPeriodBucket hourly_bucket =
      report_aggregate.hourly().by_hour_id().begin()->second;
  local_aggregation::AggregateData data =
      hourly_bucket.system_profile_aggregates(0).by_event_code().at(0).data();
  ASSERT_TRUE(data.has_string_histogram());
  const auto& histogram = data.string_histogram();
  EXPECT_EQ(histogram.histogram().at(0), 1);
}

TEST_F(EventLoggersLocalAggregationTest, OccurrenceOtherTimeZone) {
  ReportDefinition report = ReportDefinitionWithReportType(
      testing::cobalt_new::kOccurrenceOtherTzFleetwideOccurrenceCountsReportId,
      ReportDefinition::FLEETWIDE_OCCURRENCE_COUNTS);
  std::unique_ptr<EventRecord> event_record = GetEventRecordWithMetricType(
      testing::cobalt_new::kOccurrenceOtherTzMetricId, MetricDefinition::OCCURRENCE);
  std::unique_ptr<EventLogger> event_logger =
      GetEventLoggerForMetricType(MetricDefinition::OCCURRENCE);

  // Log a count of 1 for start_time_, which has hour ID 17521 in the initial time zone of
  // `civil_time_converter_`.
  EXPECT_EQ(StatusCode::OK, event_logger->Log(std::move(event_record), start_time_).error_code());

  event_record = GetEventRecordWithMetricType(testing::cobalt_new::kOccurrenceOtherTzMetricId,
                                              MetricDefinition::OCCURRENCE);
  event_record->event()->mutable_occurrence_event()->set_count(2);

  // Log a count of 2 for `start_time_ + 1` hour, which has hour ID 17524 in the final time zone of
  // `civil_time_converter_`.
  EXPECT_EQ(StatusCode::OK,
            event_logger->Log(std::move(event_record), start_time_ + util::kOneHour).error_code());

  local_aggregation::ImmediateLocalAggregateStorage store = GetLocalAggregateStorage();
  local_aggregation::ReportAggregate report_aggregate = GetReportAggregate(
      testing::cobalt_new::kOccurrenceOtherTzMetricId, MetricDefinition::OCCURRENCE,
      testing::cobalt_new::kOccurrenceOtherTzFleetwideOccurrenceCountsReportId, &store);

  // Check that the EventLogger recorded the correct hour IDs and event counts.
  ASSERT_TRUE(report_aggregate.has_hourly());
  ASSERT_EQ(report_aggregate.hourly().by_hour_id_size(), 2);

  ASSERT_EQ(report_aggregate.hourly().by_hour_id().count(17521), 1);
  EXPECT_EQ(report_aggregate.hourly()
                .by_hour_id()
                .at(17521)
                .system_profile_aggregates(0)
                .by_event_code()
                .at(0)
                .data()
                .count(),
            1);

  ASSERT_EQ(report_aggregate.hourly().by_hour_id().count(17524), 1);
  EXPECT_EQ(report_aggregate.hourly()
                .by_hour_id()
                .at(17524)
                .system_profile_aggregates(0)
                .by_event_code()
                .at(0)
                .data()
                .count(),
            2);
}

}  // namespace internal
}  // namespace cobalt::logger
