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

#include <memory>
#include <string>

#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_1_1/local_aggregation.h"
#include "src/logger/encoder.h"
#include "src/logger/fake_logger.h"
#include "src/logger/internal_metrics.h"
#include "src/logger/internal_metrics_config.cb.h"
#include "src/logger/logger_interface.h"
#include "src/logger/logger_test_utils.h"
#include "src/logger/project_context.h"
#include "src/logger/status.h"
#include "src/logger/testing_constants.h"
#include "src/pb/metadata_builder.h"
#include "src/pb/observation.pb.h"
#include "src/registry/packed_event_codes.h"
#include "src/system_data/client_secret.h"

namespace cobalt::logger {

using local_aggregation::EventAggregatorManager;
using local_aggregation::LocalAggregation;
using system_data::ClientSecret;
using system_data::SystemDataInterface;
using testing::FakeObservationStore;
using testing::GetTestProject;
using testing::GetTestProjectContextFactory;
using testing::TestUpdateRecipient;
using util::EncryptedMessageMaker;
using util::IncrementingSteadyClock;
using util::IncrementingSystemClock;

namespace {
std::tm kSystemTime = {
    .tm_sec = 30,
    .tm_min = 20,
    .tm_hour = 10,
    .tm_mday = 2,    // 2nd
    .tm_mon = 7,     // August
    .tm_year = 119,  // 2019
};
const auto kSystemTimePoint = std::chrono::system_clock::from_time_t(std::mktime(&kSystemTime));
constexpr int kDayIndex = 18110;  // 2019-08-02

// Use a smaller max saved size for testing.
constexpr size_t kMaxSavedEvents = 10;

}  // namespace

class UndatedEventManagerTest : public util::testing::TestWithFiles {
 protected:
  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_.get(), system_data_cache_path(), fs());
    encoder_ =
        std::make_unique<Encoder>(ClientSecret::GenerateNewSecret(), metadata_builder_.get());
    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(testing::all_report_types::kCobaltRegistryBase64);

    event_aggregator_mgr_ = std::make_unique<EventAggregatorManager>(cfg, fs(), encoder_.get(),
                                                                     observation_writer_.get());
    local_aggregation_ = std::make_unique<LocalAggregation>(cfg, project_context_factory_.get(),
                                                            metadata_builder_.get(), fs(),
                                                            observation_writer_.get());

    internal_logger_ = std::make_unique<testing::FakeLogger>();
    internal_metrics_ = logger::InternalMetrics::NewWithLogger(internal_logger_.get());

    mock_system_clock_ =
        std::make_unique<IncrementingSystemClock>(std::chrono::system_clock::duration(0));
    mock_system_clock_->set_time(kSystemTimePoint);
    mock_steady_clock_ = new IncrementingSteadyClock();

    undated_event_manager_ = std::make_unique<UndatedEventManager>(
        encoder_.get(), event_aggregator_mgr_->GetEventAggregator(), local_aggregation_.get(),
        observation_writer_.get(), system_data_.get(), kMaxSavedEvents);
    undated_event_manager_->SetSteadyClock(mock_steady_clock_);
  }

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

  std::unique_ptr<UndatedEventManager> undated_event_manager_;
  std::unique_ptr<testing::FakeLogger> internal_logger_;
  std::unique_ptr<logger::InternalMetrics> internal_metrics_;
  std::unique_ptr<ObservationWriter> observation_writer_;
  std::unique_ptr<FakeObservationStore> observation_store_;
  std::unique_ptr<TestUpdateRecipient> update_recipient_;
  std::unique_ptr<IncrementingSystemClock> mock_system_clock_;
  IncrementingSteadyClock* mock_steady_clock_;

 private:
  std::unique_ptr<MetadataBuilder> metadata_builder_;
  std::unique_ptr<Encoder> encoder_;
  std::unique_ptr<ProjectContextFactory> project_context_factory_;
  std::unique_ptr<EventAggregatorManager> event_aggregator_mgr_;
  std::unique_ptr<LocalAggregation> local_aggregation_;
  std::unique_ptr<EncryptedMessageMaker> observation_encrypter_;
  std::unique_ptr<SystemDataInterface> system_data_;
};

// Test that the UndatedEventManager can outlive the source of the ProjectContext.
TEST_F(UndatedEventManagerTest, DeletedProjectContext) {
  std::shared_ptr<ProjectContext> project_context =
      GetTestProject(testing::all_report_types::kCobaltRegistryBase64);

  // Create an event and save it.
  auto event_record = std::make_unique<EventRecord>(
      project_context, testing::all_report_types::kErrorOccurredMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(42);
  ASSERT_NE(nullptr, event_record->metric());

  // Drop the ProjectContext. If no one else has retained a copy, it will be deleted.
  project_context.reset();

  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));

  // Check that no immediate Observations were generated.
  EXPECT_EQ(0, observation_store_->num_observations_added());
  EXPECT_EQ(1, undated_event_manager_->NumSavedEvents());

  // Flush the saved events, this will generate immediate observations.
  ASSERT_EQ(kOK, undated_event_manager_->Flush(mock_system_clock_.get(), internal_metrics_.get()));
  EXPECT_EQ(0, undated_event_manager_->NumSavedEvents());

  // Now there should be an observation.
  EXPECT_EQ(1, observation_store_->num_observations_added());
  // Monotonic clock was not advanced, so the day index is the current one.
  EXPECT_EQ(kDayIndex, observation_store_->metadata_received[0]->day_index());
  // One internal metric call for the number of cached events.
  internal_metrics_->Flush();
  EXPECT_EQ(1, internal_logger_->call_count());
  EXPECT_EQ(kInaccurateClockEventsCachedMetricId,
            internal_logger_->last_event_logged().metric_id());
}

TEST_F(UndatedEventManagerTest, OneImmediatelyFlushedEvent) {
  std::shared_ptr<ProjectContext> project_context =
      GetTestProject(testing::all_report_types::kCobaltRegistryBase64);

  // Create an event and save it.
  auto event_record = std::make_unique<EventRecord>(
      project_context, testing::all_report_types::kErrorOccurredMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(42);
  ASSERT_NE(nullptr, event_record->metric());
  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));

  // Check that no immediate Observations were generated.
  EXPECT_EQ(0, observation_store_->num_observations_added());
  EXPECT_EQ(1, undated_event_manager_->NumSavedEvents());

  // Flush the saved events, this will generate immediate observations.
  ASSERT_EQ(kOK, undated_event_manager_->Flush(mock_system_clock_.get(), internal_metrics_.get()));
  EXPECT_EQ(0, undated_event_manager_->NumSavedEvents());

  // Now there should be an observation.
  EXPECT_EQ(1, observation_store_->num_observations_added());
  // Monotonic clock was not advanced, so the day index is the current one.
  EXPECT_EQ(kDayIndex, observation_store_->metadata_received[0]->day_index());
  // One internal metric call for the number of cached events.
  internal_metrics_->Flush();
  EXPECT_EQ(1, internal_logger_->call_count());
  EXPECT_EQ(kInaccurateClockEventsCachedMetricId,
            internal_logger_->last_event_logged().metric_id());
}

TEST_F(UndatedEventManagerTest, OneDayDelayInSystemClockAccuracy) {
  std::shared_ptr<ProjectContext> project_context =
      GetTestProject(testing::all_report_types::kCobaltRegistryBase64);

  // Create an event and save it.
  auto event_record = std::make_unique<EventRecord>(
      project_context, testing::all_report_types::kErrorOccurredMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(42);
  ASSERT_NE(nullptr, event_record->metric());
  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));

  // Check that no immediate Observations were generated.
  EXPECT_EQ(0, observation_store_->num_observations_added());
  EXPECT_EQ(1, undated_event_manager_->NumSavedEvents());

  // One day later, the clock is finally accurate, flush the saved events, this will generate
  // observations.
  mock_steady_clock_->increment_by(std::chrono::hours(24));
  ASSERT_EQ(kOK, undated_event_manager_->Flush(mock_system_clock_.get(), internal_metrics_.get()));
  EXPECT_EQ(0, undated_event_manager_->NumSavedEvents());

  // Now there should be an observation.
  EXPECT_EQ(1, observation_store_->num_observations_added());
  // Day index is from the previous day, due to the monotonic time advancing one day.
  EXPECT_EQ(kDayIndex - 1, observation_store_->metadata_received[0]->day_index());
  // One internal metric call for the number of cached events.
  internal_metrics_->Flush();
  EXPECT_EQ(1, internal_logger_->call_count());
  EXPECT_EQ(kInaccurateClockEventsCachedMetricId,
            internal_logger_->last_event_logged().metric_id());
}

TEST_F(UndatedEventManagerTest, TooManyEventsToStore) {
  std::shared_ptr<ProjectContext> project_context =
      GetTestProject(testing::all_report_types::kCobaltRegistryBase64);

  // Create some events and save them. These will be dropped
  auto event_record = std::make_unique<EventRecord>(
      project_context, testing::all_report_types::kDeviceBootsMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(1);
  ASSERT_NE(nullptr, event_record->metric());
  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));
  event_record = std::make_unique<EventRecord>(project_context,
                                               testing::all_report_types::kErrorOccurredMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(99);
  ASSERT_NE(nullptr, event_record->metric());
  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));
  event_record = std::make_unique<EventRecord>(project_context,
                                               testing::all_report_types::kFeaturesActiveMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(98);
  ASSERT_NE(nullptr, event_record->metric());
  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));
  event_record = std::make_unique<EventRecord>(project_context,
                                               testing::all_report_types::kErrorOccurredMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(97);
  ASSERT_NE(nullptr, event_record->metric());
  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));

  // Save events beyond the max size of the cache. Only 10 events should fit in memory.
  // Each event is on a different day.
  for (int i = kMaxSavedEvents; i > 0; i--) {
    mock_steady_clock_->increment_by(std::chrono::hours(24));
    event_record = std::make_unique<EventRecord>(project_context,
                                                 testing::all_report_types::kErrorOccurredMetricId);
    event_record->event()->mutable_event_occurred_event()->set_event_code(i);
    ASSERT_NE(nullptr, event_record->metric());
    ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));
  }

  // Check that no immediate Observations were generated and only the max were saved.
  ASSERT_EQ(0, observation_store_->num_observations_added());
  EXPECT_EQ(kMaxSavedEvents, undated_event_manager_->NumSavedEvents());

  // Flush the saved events, this will generate immediate observations.
  ASSERT_EQ(kOK, undated_event_manager_->Flush(mock_system_clock_.get(), internal_metrics_.get()));
  EXPECT_EQ(0, undated_event_manager_->NumSavedEvents());

  // Now there should be the maximum cache size of observation.
  EXPECT_EQ(kMaxSavedEvents, observation_store_->num_observations_added());

  for (int i = 0; i < kMaxSavedEvents; i++) {
    EXPECT_EQ(testing::all_report_types::kErrorOccurredMetricId,
              observation_store_->metadata_received[i]->metric_id());
    // Day index starts from 9 days ago and ends at today.
    EXPECT_EQ(kDayIndex - (kMaxSavedEvents - 1) + i,
              observation_store_->metadata_received[i]->day_index());
  }
  internal_metrics_->Flush();
  // Two internal metric calls for the number of cached and dropped events.
  EXPECT_EQ(2, internal_logger_->call_count());
  EXPECT_EQ(kInaccurateClockEventsDroppedMetricId,
            internal_logger_->last_event_logged().metric_id());
}

TEST_F(UndatedEventManagerTest, SaveAfterFlush) {
  std::shared_ptr<ProjectContext> project_context =
      GetTestProject(testing::all_report_types::kCobaltRegistryBase64);

  // Flush the empty manager, this will not generate any observations.
  ASSERT_EQ(kOK, undated_event_manager_->Flush(mock_system_clock_.get(), internal_metrics_.get()));
  EXPECT_EQ(0, observation_store_->num_observations_added());
  EXPECT_EQ(0, undated_event_manager_->NumSavedEvents());

  // Create an event and try to save it.
  auto event_record = std::make_unique<EventRecord>(
      project_context, testing::all_report_types::kErrorOccurredMetricId);
  event_record->event()->mutable_event_occurred_event()->set_event_code(42);
  ASSERT_NE(nullptr, event_record->metric());

  // One day later, the clock is finally accurate, try to save an event, this will generate
  // observations. (This scenario is not very likely, as the clock should report accurate around the
  // same time as the flush, but this allows us to verify the steady clock time being after the
  // flush time results in a correct date setting.)
  mock_steady_clock_->increment_by(std::chrono::hours(24));
  ASSERT_EQ(kOK, undated_event_manager_->Save(std::move(event_record)));
  EXPECT_EQ(0, undated_event_manager_->NumSavedEvents());
  // Now there should be an observation.
  EXPECT_EQ(1, observation_store_->num_observations_added());
  // Day index is from the previous day, due to the monotonic time advancing one day.
  EXPECT_EQ(kDayIndex + 1, observation_store_->metadata_received[0]->day_index());
  internal_metrics_->Flush();
  // No internal metric calls for the number of cached events.
  EXPECT_EQ(0, internal_logger_->call_count());
}

}  // namespace cobalt::logger
