// Copyright (c) 2016 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 "services/preferences/tracked/registry_hash_store_contents_win.h"

#include "base/bind.h"
#include "base/files/scoped_temp_dir.h"
#include "base/strings/string16.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/test_reg_util_win.h"
#include "base/threading/thread.h"
#include "base/values.h"
#include "base/win/registry.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

constexpr base::char16 kRegistryPath[] = L"Foo\\TestStore";
constexpr base::char16 kStoreKey[] = L"test_store_key";

// Hex-encoded MACs are 64 characters long.
constexpr char kTestStringA[] =
    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
constexpr char kTestStringB[] =
    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb";

constexpr char kAtomicPrefPath[] = "path1";
constexpr char kSplitPrefPath[] = "extension";

class RegistryHashStoreContentsWinTest : public testing::Test {
 protected:
  RegistryHashStoreContentsWinTest() {}

  void SetUp() override {
    ASSERT_NO_FATAL_FAILURE(
        registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));

    contents.reset(
        new RegistryHashStoreContentsWin(kRegistryPath, kStoreKey, nullptr));
  }

  std::unique_ptr<HashStoreContents> contents;

 private:
  registry_util::RegistryOverrideManager registry_override_manager_;

  DISALLOW_COPY_AND_ASSIGN(RegistryHashStoreContentsWinTest);
};

}  // namespace

TEST_F(RegistryHashStoreContentsWinTest, TestSetAndGetMac) {
  std::string stored_mac;
  EXPECT_FALSE(contents->GetMac(kAtomicPrefPath, &stored_mac));

  contents->SetMac(kAtomicPrefPath, kTestStringA);

  EXPECT_TRUE(contents->GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_EQ(kTestStringA, stored_mac);
}

TEST_F(RegistryHashStoreContentsWinTest, TestSetAndGetSplitMacs) {
  std::map<std::string, std::string> split_macs;
  EXPECT_FALSE(contents->GetSplitMacs(kSplitPrefPath, &split_macs));

  contents->SetSplitMac(kSplitPrefPath, "a", kTestStringA);
  contents->SetSplitMac(kSplitPrefPath, "b", kTestStringB);

  EXPECT_TRUE(contents->GetSplitMacs(kSplitPrefPath, &split_macs));
  EXPECT_EQ(2U, split_macs.size());
  EXPECT_EQ(kTestStringA, split_macs.at("a"));
  EXPECT_EQ(kTestStringB, split_macs.at("b"));
}

TEST_F(RegistryHashStoreContentsWinTest, TestRemoveAtomicMac) {
  contents->SetMac(kAtomicPrefPath, kTestStringA);

  std::string stored_mac;
  EXPECT_TRUE(contents->GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_EQ(kTestStringA, stored_mac);

  contents->RemoveEntry(kAtomicPrefPath);

  EXPECT_FALSE(contents->GetMac(kAtomicPrefPath, &stored_mac));
}

TEST_F(RegistryHashStoreContentsWinTest, TestRemoveSplitMacs) {
  contents->SetSplitMac(kSplitPrefPath, "a", kTestStringA);
  contents->SetSplitMac(kSplitPrefPath, "b", kTestStringB);

  std::map<std::string, std::string> split_macs;
  EXPECT_TRUE(contents->GetSplitMacs(kSplitPrefPath, &split_macs));
  EXPECT_EQ(2U, split_macs.size());

  contents->RemoveEntry(kSplitPrefPath);

  split_macs.clear();
  EXPECT_FALSE(contents->GetSplitMacs(kSplitPrefPath, &split_macs));
  EXPECT_EQ(0U, split_macs.size());
}

TEST_F(RegistryHashStoreContentsWinTest, TestReset) {
  contents->SetMac(kAtomicPrefPath, kTestStringA);
  contents->SetSplitMac(kSplitPrefPath, "a", kTestStringA);

  std::string stored_mac;
  EXPECT_TRUE(contents->GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_EQ(kTestStringA, stored_mac);

  std::map<std::string, std::string> split_macs;
  EXPECT_TRUE(contents->GetSplitMacs(kSplitPrefPath, &split_macs));
  EXPECT_EQ(1U, split_macs.size());

  contents->Reset();

  stored_mac.clear();
  EXPECT_FALSE(contents->GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_TRUE(stored_mac.empty());

  split_macs.clear();
  EXPECT_FALSE(contents->GetSplitMacs(kSplitPrefPath, &split_macs));
  EXPECT_EQ(0U, split_macs.size());
}

TEST(RegistryHashStoreContentsWinScopedTest, TestScopedDirsCleared) {
  std::string stored_mac;

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  const base::string16 registry_path =
      temp_dir.GetPath().DirName().BaseName().LossyDisplayName();

  RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey,
                                                  nullptr);

  scoped_refptr<TempScopedDirRegistryCleaner> temp_scoped_dir_cleaner =
      base::MakeRefCounted<TempScopedDirRegistryCleaner>();
  std::unique_ptr<RegistryHashStoreContentsWin> contentsA =
      std::make_unique<RegistryHashStoreContentsWin>(registry_path, kStoreKey,
                                                     temp_scoped_dir_cleaner);
  std::unique_ptr<RegistryHashStoreContentsWin> contentsB =
      std::make_unique<RegistryHashStoreContentsWin>(registry_path, kStoreKey,
                                                     temp_scoped_dir_cleaner);

  contentsA->SetMac(kAtomicPrefPath, kTestStringA);
  contentsB->SetMac(kAtomicPrefPath, kTestStringB);

  temp_scoped_dir_cleaner = nullptr;
  EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_EQ(kTestStringB, stored_mac);

  contentsB.reset();
  EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_EQ(kTestStringB, stored_mac);

  contentsA.reset();
  EXPECT_FALSE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
}

void OffThreadTempScopedDirDestructor(
    base::string16 registry_path,
    std::unique_ptr<HashStoreContents> contents) {
  std::string stored_mac;

  RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey,
                                                  nullptr);

  contents->SetMac(kAtomicPrefPath, kTestStringB);
  EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_EQ(kTestStringB, stored_mac);

  contents.reset();
  EXPECT_FALSE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
}

TEST(RegistryHashStoreContentsWinScopedTest, TestScopedDirsClearedMultiThread) {
  std::string stored_mac;

  base::ScopedTempDir temp_dir;
  ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
  const base::string16 registry_path =
      temp_dir.GetPath().DirName().BaseName().LossyDisplayName();

  RegistryHashStoreContentsWin verifying_contents(registry_path, kStoreKey,
                                                  nullptr);

  base::Thread test_thread("scoped_dir_cleaner_test_thread");
  test_thread.StartAndWaitForTesting();

  scoped_refptr<TempScopedDirRegistryCleaner> temp_scoped_dir_cleaner =
      base::MakeRefCounted<TempScopedDirRegistryCleaner>();
  std::unique_ptr<RegistryHashStoreContentsWin> contents =
      std::make_unique<RegistryHashStoreContentsWin>(
          registry_path, kStoreKey, std::move(temp_scoped_dir_cleaner));
  base::OnceClosure other_thread_closure =
      base::BindOnce(&OffThreadTempScopedDirDestructor, registry_path,
                     base::Passed(contents->MakeCopy()));

  contents->SetMac(kAtomicPrefPath, kTestStringA);
  contents.reset();

  EXPECT_TRUE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
  EXPECT_EQ(kTestStringA, stored_mac);

  test_thread.task_runner()->PostTask(FROM_HERE,
                                      std::move(other_thread_closure));
  test_thread.FlushForTesting();

  EXPECT_FALSE(verifying_contents.GetMac(kAtomicPrefPath, &stored_mac));
}
