// Copyright 2014 The Chromium 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 "components/metrics/metrics_log_manager.h"

#include <string>
#include <utility>
#include <vector>

#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/testing_pref_service.h"
#include "components/metrics/metrics_log.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/test_metrics_service_client.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace metrics {

namespace {

// Dummy serializer that just stores logs in memory.
class TestLogPrefService : public TestingPrefServiceSimple {
 public:
  TestLogPrefService() {
    registry()->RegisterListPref(prefs::kMetricsInitialLogs);
    registry()->RegisterListPref(prefs::kMetricsInitialLogsOld);
    registry()->RegisterListPref(prefs::kMetricsOngoingLogs);
    registry()->RegisterListPref(prefs::kMetricsOngoingLogsOld);
  }

  // Returns the number of logs of the given type.
  size_t TypeCount(MetricsLog::LogType log_type) {
    int list_length = 0;
    if (log_type == MetricsLog::INITIAL_STABILITY_LOG)
      list_length = GetList(prefs::kMetricsInitialLogs)->GetSize();
    else
      list_length = GetList(prefs::kMetricsOngoingLogs)->GetSize();
    return list_length / 2;
  }
};

}  // namespace

TEST(MetricsLogManagerTest, StandardFlow) {
  TestMetricsServiceClient client;
  TestLogPrefService pref_service;
  MetricsLogManager log_manager(&pref_service, 0);

  // Make sure a new manager has a clean slate.
  EXPECT_EQ(NULL, log_manager.current_log());
  EXPECT_FALSE(log_manager.has_staged_log());
  EXPECT_FALSE(log_manager.has_unsent_logs());

  // Check that the normal flow works.
  MetricsLog* initial_log = new MetricsLog(
      "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service);
  log_manager.BeginLoggingWithLog(make_scoped_ptr(initial_log));
  EXPECT_EQ(initial_log, log_manager.current_log());
  EXPECT_FALSE(log_manager.has_staged_log());

  log_manager.FinishCurrentLog();
  EXPECT_EQ(NULL, log_manager.current_log());
  EXPECT_TRUE(log_manager.has_unsent_logs());
  EXPECT_FALSE(log_manager.has_staged_log());

  MetricsLog* second_log =
      new MetricsLog("id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service);
  log_manager.BeginLoggingWithLog(make_scoped_ptr(second_log));
  EXPECT_EQ(second_log, log_manager.current_log());

  log_manager.StageNextLogForUpload();
  EXPECT_TRUE(log_manager.has_staged_log());
  EXPECT_FALSE(log_manager.staged_log().empty());

  log_manager.DiscardStagedLog();
  EXPECT_EQ(second_log, log_manager.current_log());
  EXPECT_FALSE(log_manager.has_staged_log());
  EXPECT_FALSE(log_manager.has_unsent_logs());

  EXPECT_FALSE(log_manager.has_unsent_logs());
}

TEST(MetricsLogManagerTest, AbandonedLog) {
  TestMetricsServiceClient client;
  TestLogPrefService pref_service;
  MetricsLogManager log_manager(&pref_service, 0);

  MetricsLog* dummy_log = new MetricsLog(
      "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service);
  log_manager.BeginLoggingWithLog(make_scoped_ptr(dummy_log));
  EXPECT_EQ(dummy_log, log_manager.current_log());

  log_manager.DiscardCurrentLog();
  EXPECT_EQ(NULL, log_manager.current_log());
  EXPECT_FALSE(log_manager.has_staged_log());
}

TEST(MetricsLogManagerTest, InterjectedLog) {
  TestMetricsServiceClient client;
  TestLogPrefService pref_service;
  MetricsLogManager log_manager(&pref_service, 0);

  MetricsLog* ongoing_log =
      new MetricsLog("id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service);
  MetricsLog* temp_log = new MetricsLog(
      "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service);

  log_manager.BeginLoggingWithLog(make_scoped_ptr(ongoing_log));
  EXPECT_EQ(ongoing_log, log_manager.current_log());

  log_manager.PauseCurrentLog();
  EXPECT_EQ(NULL, log_manager.current_log());

  log_manager.BeginLoggingWithLog(make_scoped_ptr(temp_log));
  EXPECT_EQ(temp_log, log_manager.current_log());
  log_manager.FinishCurrentLog();
  EXPECT_EQ(NULL, log_manager.current_log());

  log_manager.ResumePausedLog();
  EXPECT_EQ(ongoing_log, log_manager.current_log());

  EXPECT_FALSE(log_manager.has_staged_log());
  log_manager.StageNextLogForUpload();
  log_manager.DiscardStagedLog();
  EXPECT_FALSE(log_manager.has_unsent_logs());
}

TEST(MetricsLogManagerTest, InterjectedLogPreservesType) {
  TestMetricsServiceClient client;
  TestLogPrefService pref_service;
  MetricsLogManager log_manager(&pref_service, 0);
  log_manager.LoadPersistedUnsentLogs();

  log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
      "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
  log_manager.PauseCurrentLog();
  log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
      "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)));
  log_manager.FinishCurrentLog();
  log_manager.ResumePausedLog();
  log_manager.StageNextLogForUpload();
  log_manager.DiscardStagedLog();

  // Verify that the remaining log (which is the original ongoing log) still
  // has the right type.
  log_manager.FinishCurrentLog();
  log_manager.PersistUnsentLogs();
  EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
  EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
}

TEST(MetricsLogManagerTest, StoreAndLoad) {
  TestMetricsServiceClient client;
  TestLogPrefService pref_service;
  // Set up some in-progress logging in a scoped log manager simulating the
  // leadup to quitting, then persist as would be done on quit.
  {
    MetricsLogManager log_manager(&pref_service, 0);
    log_manager.LoadPersistedUnsentLogs();

    // Simulate a log having already been unsent from a previous session.
    {
      std::string log("proto");
      PersistedLogs ongoing_logs(&pref_service, prefs::kMetricsOngoingLogs,
                                 prefs::kMetricsOngoingLogsOld, 1, 1, 0);
      ongoing_logs.StoreLog(log);
      ongoing_logs.SerializeLogs();
    }
    EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
    EXPECT_FALSE(log_manager.has_unsent_logs());
    log_manager.LoadPersistedUnsentLogs();
    EXPECT_TRUE(log_manager.has_unsent_logs());

    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE);
    log_manager.FinishCurrentLog();

    // Nothing should be written out until PersistUnsentLogs is called.
    EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
    log_manager.PersistUnsentLogs();
    EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(2U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
  }

  // Now simulate the relaunch, ensure that the log manager restores
  // everything correctly, and verify that once the are handled they are not
  // re-persisted.
  {
    MetricsLogManager log_manager(&pref_service, 0);
    log_manager.LoadPersistedUnsentLogs();
    EXPECT_TRUE(log_manager.has_unsent_logs());

    log_manager.StageNextLogForUpload();
    log_manager.DiscardStagedLog();
    // The initial log should be sent first; update the persisted storage to
    // verify.
    log_manager.PersistUnsentLogs();
    EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(2U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));

    // Handle the first ongoing log.
    log_manager.StageNextLogForUpload();
    log_manager.DiscardStagedLog();
    EXPECT_TRUE(log_manager.has_unsent_logs());

    // Handle the last log.
    log_manager.StageNextLogForUpload();
    log_manager.DiscardStagedLog();
    EXPECT_FALSE(log_manager.has_unsent_logs());

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

TEST(MetricsLogManagerTest, StoreStagedLogTypes) {
  TestMetricsServiceClient client;

  // Ensure that types are preserved when storing staged logs.
  {
    TestLogPrefService pref_service;
    MetricsLogManager log_manager(&pref_service, 0);
    log_manager.LoadPersistedUnsentLogs();

    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE);
    log_manager.PersistUnsentLogs();

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

  {
    TestLogPrefService pref_service;
    MetricsLogManager log_manager(&pref_service, 0);
    log_manager.LoadPersistedUnsentLogs();

    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE);
    log_manager.PersistUnsentLogs();

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

TEST(MetricsLogManagerTest, LargeLogDiscarding) {
  TestMetricsServiceClient client;
  TestLogPrefService pref_service;
  // Set the size threshold very low, to verify that it's honored.
  MetricsLogManager log_manager(&pref_service, 1);
  log_manager.LoadPersistedUnsentLogs();

  log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
      "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)));
  log_manager.FinishCurrentLog();
  log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
      "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
  log_manager.FinishCurrentLog();

  // Only the ongoing log should be written out, due to the threshold.
  log_manager.PersistUnsentLogs();
  EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
  EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
}

TEST(MetricsLogManagerTest, ProvisionalStoreStandardFlow) {
  TestMetricsServiceClient client;

  // Ensure that provisional store works, and discards the correct log.
  {
    TestLogPrefService pref_service;
    MetricsLogManager log_manager(&pref_service, 0);
    log_manager.LoadPersistedUnsentLogs();

    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::INITIAL_STABILITY_LOG, &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE);
    log_manager.FinishCurrentLog();
    log_manager.DiscardLastProvisionalStore();

    log_manager.PersistUnsentLogs();
    EXPECT_EQ(0U, pref_service.TypeCount(MetricsLog::INITIAL_STABILITY_LOG));
    EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
  }
}

TEST(MetricsLogManagerTest, ProvisionalStoreNoop) {
  TestMetricsServiceClient client;

  // Ensure that trying to drop a sent log is a no-op, even if another log has
  // since been staged.
  {
    TestLogPrefService pref_service;
    MetricsLogManager log_manager(&pref_service, 0);
    log_manager.LoadPersistedUnsentLogs();

    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE);
    log_manager.StageNextLogForUpload();
    log_manager.DiscardStagedLog();
    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE);
    log_manager.DiscardLastProvisionalStore();

    log_manager.PersistUnsentLogs();
    EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
  }

  // Ensure that trying to drop more than once is a no-op
  {
    TestLogPrefService pref_service;
    MetricsLogManager log_manager(&pref_service, 0);
    log_manager.LoadPersistedUnsentLogs();

    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::ONGOING_LOG, &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::NORMAL_STORE);
    log_manager.BeginLoggingWithLog(make_scoped_ptr(new MetricsLog(
        "id", 0, MetricsLog::ONGOING_LOG,  &client, &pref_service)));
    log_manager.FinishCurrentLog();
    log_manager.StageNextLogForUpload();
    log_manager.StoreStagedLogAsUnsent(PersistedLogs::PROVISIONAL_STORE);
    log_manager.DiscardLastProvisionalStore();
    log_manager.DiscardLastProvisionalStore();

    log_manager.PersistUnsentLogs();
    EXPECT_EQ(1U, pref_service.TypeCount(MetricsLog::ONGOING_LOG));
  }
}

}  // namespace metrics
