// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/metrics/metrics_log_store.h"

#include "components/metrics/metrics_logs_event_manager.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/test/test_metrics_service_client.h"
#include "components/metrics/unsent_log_store_metrics_impl.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace metrics {
namespace {

const char kTestPrefName[] = "TestPref";

class TestUnsentLogStore : public UnsentLogStore {
 public:
  explicit TestUnsentLogStore(PrefService* service)
      : UnsentLogStore(std::make_unique<UnsentLogStoreMetricsImpl>(),
                       service,
                       kTestPrefName,
                       nullptr,
                       // Set to 3 so logs are not dropped in the test.
                       UnsentLogStore::UnsentLogStoreLimits{
                           .min_log_count = 3,
                       },
                       /*signing_key=*/std::string(),
                       /*logs_event_manager=*/nullptr) {}
  ~TestUnsentLogStore() override = default;

  TestUnsentLogStore(const TestUnsentLogStore&) = delete;
  TestUnsentLogStore& operator=(const TestUnsentLogStore&) = delete;

  static void RegisterPrefs(PrefRegistrySimple* registry) {
    registry->RegisterListPref(kTestPrefName);
  }
};

class MetricsLogStoreTest : public testing::Test {
 public:
  MetricsLogStoreTest() {
    MetricsLogStore::RegisterPrefs(pref_service_.registry());
    TestUnsentLogStore::RegisterPrefs(pref_service_.registry());
  }

  MetricsLogStoreTest(const MetricsLogStoreTest&) = delete;
  MetricsLogStoreTest& operator=(const MetricsLogStoreTest&) = delete;

  ~MetricsLogStoreTest() override = default;

  MetricsLog* CreateLog(MetricsLog::LogType log_type) {
    return new MetricsLog("0a94430b-18e5-43c8-a657-580f7e855ce1", 0, log_type,
                          &client_);
  }

  // Returns the stored number of logs of the given type.
  size_t TypeCount(MetricsLog::LogType log_type) {
    const char* pref = log_type == MetricsLog::INITIAL_STABILITY_LOG
                           ? prefs::kMetricsInitialLogs
                           : prefs::kMetricsOngoingLogs;
    return pref_service_.GetList(pref).size();
  }

  TestMetricsServiceClient client_;
  TestingPrefServiceSimple pref_service_;
};

}  // namespace

TEST_F(MetricsLogStoreTest, StandardFlow) {
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  log_store.LoadPersistedUnsentLogs();

  // Make sure a new manager has a clean slate.
  EXPECT_FALSE(log_store.has_staged_log());
  EXPECT_FALSE(log_store.has_unsent_logs());

  log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  EXPECT_TRUE(log_store.has_unsent_logs());
  EXPECT_FALSE(log_store.has_staged_log());

  log_store.StageNextLog();
  EXPECT_TRUE(log_store.has_staged_log());
  EXPECT_FALSE(log_store.staged_log().empty());

  log_store.DiscardStagedLog();
  EXPECT_FALSE(log_store.has_staged_log());
  EXPECT_FALSE(log_store.has_unsent_logs());
}

TEST_F(MetricsLogStoreTest, StoreAndLoad) {
  // Set up some in-progress logging in a scoped log manager simulating the
  // leadup to quitting, then persist as would be done on quit.
  {
    MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                              /*signing_key=*/std::string(),
                              /*logs_event_manager=*/nullptr);
    log_store.LoadPersistedUnsentLogs();
    EXPECT_FALSE(log_store.has_unsent_logs());
    log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                       MetricsLogsEventManager::CreateReason::kUnknown);
    log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
    EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
  }

  // Relaunch load and store more logs.
  {
    MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                              /*signing_key=*/std::string(),
                              /*logs_event_manager=*/nullptr);
    log_store.LoadPersistedUnsentLogs();
    EXPECT_TRUE(log_store.has_unsent_logs());
    EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
    log_store.StoreLog("x", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
                       MetricsLogsEventManager::CreateReason::kUnknown);
    log_store.StageNextLog();
    log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
                       MetricsLogsEventManager::CreateReason::kUnknown);

    EXPECT_TRUE(log_store.has_unsent_logs());
    EXPECT_TRUE(log_store.has_staged_log());
    EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));

    log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
    EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
  }

  // Relaunch and verify that once logs are handled they are not re-persisted.
  {
    MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                              /*signing_key=*/std::string(),
                              /*logs_event_manager=*/nullptr);
    log_store.LoadPersistedUnsentLogs();
    EXPECT_TRUE(log_store.has_unsent_logs());

    log_store.StageNextLog();
    log_store.DiscardStagedLog();
    // The initial log should be sent first; update the persisted storage to
    // verify.
    log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
    EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));

    // Handle the first ongoing log.
    log_store.StageNextLog();
    log_store.DiscardStagedLog();
    EXPECT_TRUE(log_store.has_unsent_logs());

    // Handle the last log.
    log_store.StageNextLog();
    log_store.DiscardStagedLog();
    EXPECT_FALSE(log_store.has_unsent_logs());

    // Nothing should have changed "on disk" since TrimAndPersistUnsentLogs
    // hasn't been called again.
    EXPECT_EQ(2U, TypeCount(MetricsLog::ONGOING_LOG));
    // Persist, and make sure nothing is left.
    log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
    EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
  }
}

TEST_F(MetricsLogStoreTest, StoreStagedOngoingLog) {
  // Ensure that types are preserved when storing staged logs.
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  log_store.LoadPersistedUnsentLogs();
  log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StageNextLog();
  log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);

  EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
  EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
}

TEST_F(MetricsLogStoreTest, StoreStagedInitialLog) {
  // Ensure that types are preserved when storing staged logs.
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  log_store.LoadPersistedUnsentLogs();
  log_store.StoreLog("b", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StageNextLog();
  log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);

  EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
  EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
}

TEST_F(MetricsLogStoreTest, LargeLogDiscarding) {
  // Set the size threshold very low, to verify that it's honored.
  client_.set_max_ongoing_log_size_bytes(1);
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  log_store.LoadPersistedUnsentLogs();

  log_store.StoreLog("persisted", MetricsLog::INITIAL_STABILITY_LOG,
                     LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StoreLog("not_persisted", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);

  // Only the stability log should be written out, due to the threshold.
  log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
  EXPECT_EQ(1U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
  EXPECT_EQ(0U, TypeCount(MetricsLog::ONGOING_LOG));
}

TEST_F(MetricsLogStoreTest, DiscardOrder) {
  // Ensure that the correct log is discarded if new logs are pushed while
  // a log is staged.
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  log_store.LoadPersistedUnsentLogs();

  log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StageNextLog();
  log_store.StoreLog("c", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  EXPECT_EQ(2U, log_store.ongoing_log_count());
  EXPECT_EQ(1U, log_store.initial_log_count());
  // Should discard the ongoing log staged earlier.
  log_store.DiscardStagedLog();
  EXPECT_EQ(1U, log_store.ongoing_log_count());
  EXPECT_EQ(1U, log_store.initial_log_count());
  // Initial log should be staged next.
  log_store.StageNextLog();
  log_store.DiscardStagedLog();
  EXPECT_EQ(1U, log_store.ongoing_log_count());
  EXPECT_EQ(0U, log_store.initial_log_count());
}

TEST_F(MetricsLogStoreTest, WritesToAlternateOngoingLogStore) {
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
      std::make_unique<TestUnsentLogStore>(&pref_service_);
  TestUnsentLogStore* alternate_ongoing_log_store_ptr =
      alternate_ongoing_log_store.get();

  // Needs to be called before writing logs to alternate ongoing store since
  // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
  // the native initial and ongoing unsent logs have already been loaded.
  log_store.LoadPersistedUnsentLogs();

  log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
  log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StoreLog("c", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);

  EXPECT_EQ(1U, log_store.ongoing_log_count());
  EXPECT_EQ(2U, alternate_ongoing_log_store_ptr->size());
}

TEST_F(MetricsLogStoreTest, AlternateOngoingLogStoreGetsEventsLogsManager) {
  // Create a MetricsLogStore with a MetricsLogsEventManager.
  MetricsLogsEventManager logs_event_manager;
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(), &logs_event_manager);

  // Create an UnsentLogStore that will be used as an alternate ongoing log
  // store.
  std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
      std::make_unique<TestUnsentLogStore>(&pref_service_);
  TestUnsentLogStore* alternate_ongoing_log_store_ptr =
      alternate_ongoing_log_store.get();

  // Verify that |alternate_ongoing_log_store| has no logs event manager.
  EXPECT_FALSE(
      alternate_ongoing_log_store_ptr->GetLogsEventManagerForTesting());

  // Needs to be called before we can set |log_store|'s alternate ongoing log
  // store.
  log_store.LoadPersistedUnsentLogs();

  // Verify that after setting |log_store|'s alternate ongoing log store to
  // |alternate_ongoing_log_store|, the latter should have the former's logs
  // event manager.
  log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
  EXPECT_EQ(alternate_ongoing_log_store_ptr->GetLogsEventManagerForTesting(),
            &logs_event_manager);
}

TEST_F(MetricsLogStoreTest, StagesInitialOverBothOngoing) {
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
      std::make_unique<TestUnsentLogStore>(&pref_service_);
  TestUnsentLogStore* alternate_ongoing_log_store_ptr =
      alternate_ongoing_log_store.get();

  // Needs to be called before writing logs to alternate ongoing store since
  // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
  // the native initial and ongoing unsent logs have already been loaded.
  log_store.LoadPersistedUnsentLogs();

  log_store.StoreLog("a", MetricsLog::INITIAL_STABILITY_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
  log_store.StoreLog("c", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StageNextLog();
  log_store.DiscardStagedLog();

  // Discarded log should be from initial_log_store.
  EXPECT_EQ(0U, log_store.initial_log_count());
  EXPECT_EQ(1U, log_store.ongoing_log_count());
  EXPECT_EQ(1U, alternate_ongoing_log_store_ptr->size());
}

TEST_F(MetricsLogStoreTest, StagesAlternateOverOngoing) {
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
      std::make_unique<TestUnsentLogStore>(&pref_service_);
  TestUnsentLogStore* alternate_ongoing_log_store_ptr =
      alternate_ongoing_log_store.get();

  // Needs to be called before writing logs to alternate ongoing store since
  // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
  // the native initial and ongoing unsent logs have already been loaded.
  log_store.LoadPersistedUnsentLogs();

  log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
  log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StageNextLog();
  log_store.DiscardStagedLog();

  // Discarded log should be from alternate_ongoing_log_store.
  EXPECT_EQ(1U, log_store.ongoing_log_count());
  EXPECT_EQ(0U, alternate_ongoing_log_store_ptr->size());
}

TEST_F(MetricsLogStoreTest,
       UnboundAlternateOngoingLogStoreWritesToNativeOngoing) {
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
      std::make_unique<TestUnsentLogStore>(&pref_service_);

  // Needs to be called before writing logs to alternate ongoing store since
  // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
  // the native initial and ongoing unsent logs have already been loaded.
  log_store.LoadPersistedUnsentLogs();

  log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));
  // Should be written to alternate ongoing log store.
  log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);

  log_store.UnsetAlternateOngoingLogStore();

  // Should be in native ongoing log store.
  log_store.StoreLog("b", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StoreLog("c", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);

  EXPECT_EQ(2U, log_store.ongoing_log_count());
}

TEST_F(MetricsLogStoreTest,
       StageOngoingLogWhenAlternateOngoingLogStoreIsEmpty) {
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  std::unique_ptr<TestUnsentLogStore> alternate_ongoing_log_store =
      std::make_unique<TestUnsentLogStore>(&pref_service_);

  // Needs to be called before writing logs to alternate ongoing store since
  // SetAlternateOngoingLogStore loads persisted unsent logs and assumes that
  // the native initial and ongoing unsent logs have already been loaded.
  log_store.LoadPersistedUnsentLogs();

  // Should be written to ongoing log store.
  log_store.StoreLog("a", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);

  // Ensure that the log was stored in ongoing log.
  EXPECT_EQ(1U, log_store.ongoing_log_count());

  log_store.SetAlternateOngoingLogStore(std::move(alternate_ongoing_log_store));

  log_store.StageNextLog();
  log_store.DiscardStagedLog();

  // Discarded log should be from ongoing.
  EXPECT_EQ(0U, log_store.ongoing_log_count());
}

TEST_F(MetricsLogStoreTest, TrimLargeInitialStabilityLog) {
  // Set the max log size to be 1 byte so that pretty much all logs will be
  // trimmed. We don't set it to 0 bytes because that is a special value that
  // represents no max size.
  client_.set_max_initial_log_size_bytes(1);
  MetricsLogStore log_store(&pref_service_, client_.GetStorageLimits(),
                            /*signing_key=*/std::string(),
                            /*logs_event_manager=*/nullptr);
  log_store.LoadPersistedUnsentLogs();

  log_store.StoreLog("not_persisted", MetricsLog::INITIAL_STABILITY_LOG,
                     LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);
  log_store.StoreLog("persisted", MetricsLog::ONGOING_LOG, LogMetadata(),
                     MetricsLogsEventManager::CreateReason::kUnknown);

  // Only the ongoing log should be written out, due to the threshold.
  log_store.TrimAndPersistUnsentLogs(/*overwrite_in_memory_store=*/true);
  EXPECT_EQ(0U, TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
  EXPECT_EQ(1U, TypeCount(MetricsLog::ONGOING_LOG));
}
}  // namespace metrics
