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

#include <ctype.h>
#include <stddef.h>
#include <stdint.h>
#include <string>
#include <utility>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/macros.h"
#include "components/metrics/client_info.h"
#include "components/metrics/metrics_pref_names.h"
#include "components/metrics/metrics_service.h"
#include "components/metrics/metrics_switches.h"
#include "components/metrics/test_enabled_state_provider.h"
#include "components/prefs/testing_pref_service.h"
#include "components/variations/caching_permuted_entropy_provider.h"
#include "components/variations/pref_names.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace metrics {

class MetricsStateManagerTest : public testing::Test {
 public:
  MetricsStateManagerTest()
      : test_begin_time_(base::Time::Now().ToTimeT()),
        enabled_state_provider_(new TestEnabledStateProvider(false, false)) {
    MetricsService::RegisterPrefs(prefs_.registry());
  }

  std::unique_ptr<MetricsStateManager> CreateStateManager() {
    return MetricsStateManager::Create(
        &prefs_, enabled_state_provider_.get(),
        base::Bind(&MetricsStateManagerTest::MockStoreClientInfoBackup,
                   base::Unretained(this)),
        base::Bind(&MetricsStateManagerTest::LoadFakeClientInfoBackup,
                   base::Unretained(this)));
  }

  // Sets metrics reporting as enabled for testing.
  void EnableMetricsReporting() {
    enabled_state_provider_->set_consent(true);
    enabled_state_provider_->set_enabled(true);
  }

  void SetClientInfoPrefs(const ClientInfo& client_info) {
    prefs_.SetString(prefs::kMetricsClientID, client_info.client_id);
    prefs_.SetInt64(prefs::kInstallDate, client_info.installation_date);
    prefs_.SetInt64(prefs::kMetricsReportingEnabledTimestamp,
                    client_info.reporting_enabled_date);
  }

  void SetFakeClientInfoBackup(const ClientInfo& client_info) {
    fake_client_info_backup_.reset(new ClientInfo);
    fake_client_info_backup_->client_id = client_info.client_id;
    fake_client_info_backup_->installation_date = client_info.installation_date;
    fake_client_info_backup_->reporting_enabled_date =
        client_info.reporting_enabled_date;
  }

 protected:
  TestingPrefServiceSimple prefs_;

  // Last ClientInfo stored by the MetricsStateManager via
  // MockStoreClientInfoBackup.
  std::unique_ptr<ClientInfo> stored_client_info_backup_;

  // If set, will be returned via LoadFakeClientInfoBackup if requested by the
  // MetricsStateManager.
  std::unique_ptr<ClientInfo> fake_client_info_backup_;

  const int64_t test_begin_time_;

 private:
  // Stores the |client_info| in |stored_client_info_backup_| for verification
  // by the tests later.
  void MockStoreClientInfoBackup(const ClientInfo& client_info) {
    stored_client_info_backup_.reset(new ClientInfo);
    stored_client_info_backup_->client_id = client_info.client_id;
    stored_client_info_backup_->installation_date =
        client_info.installation_date;
    stored_client_info_backup_->reporting_enabled_date =
        client_info.reporting_enabled_date;

    // Respect the contract that storing an empty client_id voids the existing
    // backup (required for the last section of the ForceClientIdCreation test
    // below).
    if (client_info.client_id.empty())
      fake_client_info_backup_.reset();
  }

  // Hands out a copy of |fake_client_info_backup_| if it is set.
  std::unique_ptr<ClientInfo> LoadFakeClientInfoBackup() {
    if (!fake_client_info_backup_)
      return std::unique_ptr<ClientInfo>();

    std::unique_ptr<ClientInfo> backup_copy(new ClientInfo);
    backup_copy->client_id = fake_client_info_backup_->client_id;
    backup_copy->installation_date =
        fake_client_info_backup_->installation_date;
    backup_copy->reporting_enabled_date =
        fake_client_info_backup_->reporting_enabled_date;
    return backup_copy;
  }

  std::unique_ptr<TestEnabledStateProvider> enabled_state_provider_;

  DISALLOW_COPY_AND_ASSIGN(MetricsStateManagerTest);
};

// Ensure the ClientId is formatted as expected.
TEST_F(MetricsStateManagerTest, ClientIdCorrectlyFormatted) {
  std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
  state_manager->ForceClientIdCreation();

  const std::string client_id = state_manager->client_id();
  EXPECT_EQ(36U, client_id.length());

  for (size_t i = 0; i < client_id.length(); ++i) {
    char current = client_id[i];
    if (i == 8 || i == 13 || i == 18 || i == 23)
      EXPECT_EQ('-', current);
    else
      EXPECT_TRUE(isxdigit(current));
  }
}

TEST_F(MetricsStateManagerTest, EntropySourceUsed_Low) {
  std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
  state_manager->CreateDefaultEntropyProvider();
  EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_LOW,
            state_manager->entropy_source_returned());
}

TEST_F(MetricsStateManagerTest, EntropySourceUsed_High) {
  EnableMetricsReporting();
  std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
  state_manager->CreateDefaultEntropyProvider();
  EXPECT_EQ(MetricsStateManager::ENTROPY_SOURCE_HIGH,
            state_manager->entropy_source_returned());
}

TEST_F(MetricsStateManagerTest, LowEntropySource0NotReset) {
  std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());

  // Get the low entropy source once, to initialize it.
  state_manager->GetLowEntropySource();

  // Now, set it to 0 and ensure it doesn't get reset.
  state_manager->low_entropy_source_ = 0;
  EXPECT_EQ(0, state_manager->GetLowEntropySource());
  // Call it another time, just to make sure.
  EXPECT_EQ(0, state_manager->GetLowEntropySource());
}

TEST_F(MetricsStateManagerTest,
       PermutedEntropyCacheClearedWhenLowEntropyReset) {
  const PrefService::Preference* low_entropy_pref =
      prefs_.FindPreference(prefs::kMetricsLowEntropySource);
  const char* kCachePrefName =
      variations::prefs::kVariationsPermutedEntropyCache;
  int low_entropy_value = -1;

  // First, generate an initial low entropy source value.
  {
    EXPECT_TRUE(low_entropy_pref->IsDefaultValue());

    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
    state_manager->GetLowEntropySource();

    EXPECT_FALSE(low_entropy_pref->IsDefaultValue());
    EXPECT_TRUE(low_entropy_pref->GetValue()->GetAsInteger(&low_entropy_value));
  }

  // Now, set a dummy value in the permuted entropy cache pref and verify that
  // another call to GetLowEntropySource() doesn't clobber it when
  // --reset-variation-state wasn't specified.
  {
    prefs_.SetString(kCachePrefName, "test");

    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
    state_manager->GetLowEntropySource();

    EXPECT_EQ("test", prefs_.GetString(kCachePrefName));
    EXPECT_EQ(low_entropy_value,
              prefs_.GetInteger(prefs::kMetricsLowEntropySource));
  }

  // Verify that the cache does get reset if --reset-variations-state is passed.
  {
    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kResetVariationState);

    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
    state_manager->GetLowEntropySource();

    EXPECT_TRUE(prefs_.GetString(kCachePrefName).empty());
  }
}

// Check that setting the kMetricsResetIds pref to true causes the client id to
// be reset. We do not check that the low entropy source is reset because we
// cannot ensure that metrics state manager won't generate the same id again.
TEST_F(MetricsStateManagerTest, ResetMetricsIDs) {
  // Set an initial client id in prefs. It should not be possible for the
  // metrics state manager to generate this id randomly.
  const std::string kInitialClientId = "initial client id";
  prefs_.SetString(prefs::kMetricsClientID, kInitialClientId);

  // Make sure the initial client id isn't reset by the metrics state manager.
  {
    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
    state_manager->ForceClientIdCreation();
    EXPECT_EQ(kInitialClientId, state_manager->client_id());
  }

  // Set the reset pref to cause the IDs to be reset.
  prefs_.SetBoolean(prefs::kMetricsResetIds, true);

  // Cause the actual reset to happen.
  {
    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
    state_manager->ForceClientIdCreation();
    EXPECT_NE(kInitialClientId, state_manager->client_id());

    state_manager->GetLowEntropySource();

    EXPECT_FALSE(prefs_.GetBoolean(prefs::kMetricsResetIds));
  }

  EXPECT_NE(kInitialClientId, prefs_.GetString(prefs::kMetricsClientID));
}

TEST_F(MetricsStateManagerTest, ForceClientIdCreation) {
  const int64_t kFakeInstallationDate = 12345;
  prefs_.SetInt64(prefs::kInstallDate, kFakeInstallationDate);

  {
    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());

    // client_id shouldn't be auto-generated if metrics reporting is not
    // enabled.
    EXPECT_EQ(std::string(), state_manager->client_id());
    EXPECT_EQ(0, prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp));

    // Confirm that the initial ForceClientIdCreation call creates the client id
    // and backs it up via MockStoreClientInfoBackup.
    EXPECT_FALSE(stored_client_info_backup_);
    state_manager->ForceClientIdCreation();
    EXPECT_NE(std::string(), state_manager->client_id());
    EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
              test_begin_time_);

    ASSERT_TRUE(stored_client_info_backup_);
    EXPECT_EQ(state_manager->client_id(),
              stored_client_info_backup_->client_id);
    EXPECT_EQ(kFakeInstallationDate,
              stored_client_info_backup_->installation_date);
    EXPECT_EQ(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
              stored_client_info_backup_->reporting_enabled_date);
  }
}

TEST_F(MetricsStateManagerTest, LoadPrefs) {
  ClientInfo client_info;
  client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
  client_info.installation_date = 1112;
  client_info.reporting_enabled_date = 2223;
  SetClientInfoPrefs(client_info);

  EnableMetricsReporting();
  {
    EXPECT_FALSE(fake_client_info_backup_);
    EXPECT_FALSE(stored_client_info_backup_);

    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());

    // client_id should be auto-obtained from the constructor when metrics
    // reporting is enabled.
    EXPECT_EQ(client_info.client_id, state_manager->client_id());

    // The backup should not be modified.
    ASSERT_FALSE(stored_client_info_backup_);

    // Re-forcing client id creation shouldn't cause another backup and
    // shouldn't affect the existing client id.
    state_manager->ForceClientIdCreation();
    EXPECT_FALSE(stored_client_info_backup_);
    EXPECT_EQ(client_info.client_id, state_manager->client_id());
  }
}

TEST_F(MetricsStateManagerTest, PreferPrefs) {
  ClientInfo client_info;
  client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
  client_info.installation_date = 1112;
  client_info.reporting_enabled_date = 2223;
  SetClientInfoPrefs(client_info);

  ClientInfo client_info2;
  client_info2.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
  client_info2.installation_date = 1111;
  client_info2.reporting_enabled_date = 2222;
  SetFakeClientInfoBackup(client_info2);

  EnableMetricsReporting();
  {
    // The backup should be ignored if we already have a client id.

    EXPECT_FALSE(stored_client_info_backup_);

    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
    EXPECT_EQ(client_info.client_id, state_manager->client_id());

    // The backup should not be modified.
    ASSERT_FALSE(stored_client_info_backup_);
  }
}

TEST_F(MetricsStateManagerTest, RestoreBackup) {
  ClientInfo client_info;
  client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEF";
  client_info.installation_date = 1112;
  client_info.reporting_enabled_date = 2223;
  SetClientInfoPrefs(client_info);

  ClientInfo client_info2;
  client_info2.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
  client_info2.installation_date = 1111;
  client_info2.reporting_enabled_date = 2222;
  SetFakeClientInfoBackup(client_info2);

  prefs_.ClearPref(prefs::kMetricsClientID);
  prefs_.ClearPref(prefs::kMetricsReportingEnabledTimestamp);

  EnableMetricsReporting();
  {
    // The backup should kick in if the client id has gone missing. It should
    // replace remaining and missing dates as well.

    EXPECT_FALSE(stored_client_info_backup_);

    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());
    EXPECT_EQ(client_info2.client_id, state_manager->client_id());
    EXPECT_EQ(client_info2.installation_date,
              prefs_.GetInt64(prefs::kInstallDate));
    EXPECT_EQ(client_info2.reporting_enabled_date,
              prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp));

    EXPECT_TRUE(stored_client_info_backup_);
  }
}

TEST_F(MetricsStateManagerTest, ResetBackup) {
  ClientInfo client_info;
  client_info.client_id = "AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE";
  client_info.installation_date = 1111;
  client_info.reporting_enabled_date = 2222;

  SetFakeClientInfoBackup(client_info);
  SetClientInfoPrefs(client_info);

  prefs_.SetBoolean(prefs::kMetricsResetIds, true);

  EnableMetricsReporting();
  {
    // Upon request to reset metrics ids, the existing backup should not be
    // restored.

    std::unique_ptr<MetricsStateManager> state_manager(CreateStateManager());

    // A brand new client id should have been generated.
    EXPECT_NE(std::string(), state_manager->client_id());
    EXPECT_NE(client_info.client_id, state_manager->client_id());
    EXPECT_TRUE(stored_client_info_backup_);

    // The installation date should not have been affected.
    EXPECT_EQ(client_info.installation_date,
              prefs_.GetInt64(prefs::kInstallDate));

    // The metrics-reporting-enabled date will be reset to Now().
    EXPECT_GE(prefs_.GetInt64(prefs::kMetricsReportingEnabledTimestamp),
              test_begin_time_);
  }
}

}  // namespace metrics
