// Copyright 2013 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/pref_hash_store_impl.h"

#include <string>

#include "base/macros.h"
#include "base/values.h"
#include "services/preferences/tracked/dictionary_hash_store_contents.h"
#include "services/preferences/tracked/hash_store_contents.h"
#include "services/preferences/tracked/pref_hash_store_transaction.h"
#include "testing/gtest/include/gtest/gtest.h"

using ValueState =
    prefs::mojom::TrackedPreferenceValidationDelegate::ValueState;

class PrefHashStoreImplTest : public testing::Test {
 public:
  PrefHashStoreImplTest() : contents_(&pref_store_contents_) {}

 protected:
  HashStoreContents* GetHashStoreContents() { return &contents_; }

 private:
  base::DictionaryValue pref_store_contents_;
  // Must be declared after |pref_store_contents_| as it needs to be outlived
  // by it.
  DictionaryHashStoreContents contents_;

  DISALLOW_COPY_AND_ASSIGN(PrefHashStoreImplTest);
};

TEST_F(PrefHashStoreImplTest, ComputeMac) {
  base::Value string_1("string1");
  base::Value string_2("string2");
  PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);

  std::string computed_mac_1 = pref_hash_store.ComputeMac("path1", &string_1);
  std::string computed_mac_2 = pref_hash_store.ComputeMac("path1", &string_2);
  std::string computed_mac_3 = pref_hash_store.ComputeMac("path2", &string_1);

  // Quick sanity checks here, see pref_hash_calculator_unittest.cc for more
  // complete tests.
  EXPECT_EQ(computed_mac_1, pref_hash_store.ComputeMac("path1", &string_1));
  EXPECT_NE(computed_mac_1, computed_mac_2);
  EXPECT_NE(computed_mac_1, computed_mac_3);
  EXPECT_EQ(64U, computed_mac_1.size());
}

TEST_F(PrefHashStoreImplTest, ComputeSplitMacs) {
  base::DictionaryValue dict;
  dict.SetKey("a", base::Value("string1"));
  dict.SetKey("b", base::Value("string2"));
  // Verify that dictionary keys can contain a '.' delimiter.
  dict.SetKey("http://www.example.com", base::Value("string3"));
  PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);

  std::unique_ptr<base::DictionaryValue> computed_macs =
      pref_hash_store.ComputeSplitMacs("foo.bar", &dict);

  const std::string mac_1 = computed_macs->FindKey("a")->GetString();
  const std::string mac_2 = computed_macs->FindKey("b")->GetString();
  const std::string mac_3 =
      computed_macs->FindKey("http://www.example.com")->GetString();

  EXPECT_EQ(3U, computed_macs->size());

  base::Value string_1("string1");
  base::Value string_2("string2");
  base::Value string_3("string3");
  EXPECT_EQ(pref_hash_store.ComputeMac("foo.bar.a", &string_1), mac_1);
  EXPECT_EQ(pref_hash_store.ComputeMac("foo.bar.b", &string_2), mac_2);
  EXPECT_EQ(
      pref_hash_store.ComputeMac("foo.bar.http://www.example.com", &string_3),
      mac_3);
}

TEST_F(PrefHashStoreImplTest, ComputeNullSplitMacs) {
  PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
  std::unique_ptr<base::DictionaryValue> computed_macs =
      pref_hash_store.ComputeSplitMacs("foo.bar", nullptr);

  ASSERT_TRUE(computed_macs);
  EXPECT_TRUE(computed_macs->empty());
}

TEST_F(PrefHashStoreImplTest, AtomicHashStoreAndCheck) {
  base::Value string_1("string1");
  base::Value string_2("string2");

  {
    // 32 NULL bytes is the seed that was used to generate the legacy hash.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));

    // Only NULL should be trusted in the absence of a hash.
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("path1", &string_1));
    EXPECT_EQ(ValueState::TRUSTED_NULL_VALUE,
              transaction->CheckValue("path1", NULL));

    transaction->StoreHash("path1", &string_1);
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_1));
    EXPECT_EQ(ValueState::CLEARED, transaction->CheckValue("path1", NULL));
    transaction->StoreHash("path1", NULL);
    EXPECT_EQ(ValueState::UNCHANGED, transaction->CheckValue("path1", NULL));
    EXPECT_EQ(ValueState::CHANGED, transaction->CheckValue("path1", &string_2));

    base::DictionaryValue dict;
    dict.SetString("a", "foo");
    dict.SetString("d", "bad");
    dict.SetString("b", "bar");
    dict.SetString("c", "baz");

    transaction->StoreHash("path1", &dict);
    EXPECT_EQ(ValueState::UNCHANGED, transaction->CheckValue("path1", &dict));
  }

  ASSERT_FALSE(GetHashStoreContents()->GetSuperMac().empty());

  {
    // |pref_hash_store| should trust its initial hashes dictionary and thus
    // trust new unknown values.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    EXPECT_EQ(ValueState::TRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("new_path", &string_1));
    EXPECT_EQ(ValueState::TRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("new_path", &string_2));
    EXPECT_EQ(ValueState::TRUSTED_NULL_VALUE,
              transaction->CheckValue("new_path", NULL));
  }

  // Manually corrupt the super MAC.
  GetHashStoreContents()->SetSuperMac(std::string(64, 'A'));

  {
    // |pref_hash_store| should no longer trust its initial hashes dictionary
    // and thus shouldn't trust non-NULL unknown values.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("new_path", &string_1));
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("new_path", &string_2));
    EXPECT_EQ(ValueState::TRUSTED_NULL_VALUE,
              transaction->CheckValue("new_path", NULL));
  }
}

TEST_F(PrefHashStoreImplTest, ImportExportOperations) {
  base::Value string_1("string1");
  base::Value string_2("string2");

  // Initial state: no super MAC.
  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_FALSE(transaction->IsSuperMACValid());

    ASSERT_FALSE(transaction->HasHash("path1"));

    // Storing a hash will stamp the super MAC.
    transaction->StoreHash("path1", &string_1);

    ASSERT_TRUE(transaction->HasHash("path1"));
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_1));
    EXPECT_EQ(ValueState::CHANGED, transaction->CheckValue("path1", &string_2));
  }

  // Make a copy of the stored hash for future use.
  const base::Value* hash = NULL;
  ASSERT_TRUE(GetHashStoreContents()->GetContents()->Get("path1", &hash));
  std::unique_ptr<base::Value> path_1_string_1_hash_copy(hash->DeepCopy());
  hash = NULL;

  // Verify that the super MAC was stamped.
  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_TRUE(transaction->IsSuperMACValid());
    ASSERT_TRUE(transaction->HasHash("path1"));

    // Clearing the hash should preserve validity.
    transaction->ClearHash("path1");

    // The effects of the clear should be immediately visible.
    ASSERT_FALSE(transaction->HasHash("path1"));
    EXPECT_EQ(ValueState::TRUSTED_NULL_VALUE,
              transaction->CheckValue("path1", NULL));
    EXPECT_EQ(ValueState::TRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("path1", &string_1));
  }

  // Verify that validity was preserved and that the clear took effect.
  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_TRUE(transaction->IsSuperMACValid());
    ASSERT_FALSE(transaction->HasHash("path1"));
  }

  // Invalidate the super MAC.
  GetHashStoreContents()->SetSuperMac(std::string());

  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_FALSE(transaction->IsSuperMACValid());
    ASSERT_FALSE(transaction->HasHash("path1"));

    // An import should preserve invalidity.
    transaction->ImportHash("path1", path_1_string_1_hash_copy.get());

    ASSERT_TRUE(transaction->HasHash("path1"));

    // The imported hash should be usable for validating the original value.
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_1));
  }

  // Verify that invalidity was preserved and that the import took effect.
  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_FALSE(transaction->IsSuperMACValid());
    ASSERT_TRUE(transaction->HasHash("path1"));
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_1));

    // After clearing the hash, non-null values are UNTRUSTED_UNKNOWN.
    transaction->ClearHash("path1");

    EXPECT_EQ(ValueState::TRUSTED_NULL_VALUE,
              transaction->CheckValue("path1", NULL));
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("path1", &string_1));
  }

  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_FALSE(transaction->IsSuperMACValid());

    // Test StampSuperMac.
    transaction->StampSuperMac();
  }

  // Verify that the store is now valid.
  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_TRUE(transaction->IsSuperMACValid());

    // Store the hash of a different value to test an "over-import".
    transaction->StoreHash("path1", &string_2);
    EXPECT_EQ(ValueState::CHANGED, transaction->CheckValue("path1", &string_1));
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_2));
  }

  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_TRUE(transaction->IsSuperMACValid());

    // "Over-import". An import should preserve validity.
    transaction->ImportHash("path1", path_1_string_1_hash_copy.get());
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_1));
    EXPECT_EQ(ValueState::CHANGED, transaction->CheckValue("path1", &string_2));
  }

  // Verify that validity was preserved and the "over-import" took effect.
  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    ASSERT_TRUE(transaction->IsSuperMACValid());
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_1));
    EXPECT_EQ(ValueState::CHANGED, transaction->CheckValue("path1", &string_2));
  }
}

TEST_F(PrefHashStoreImplTest, SuperMACDisabled) {
  base::Value string_1("string1");
  base::Value string_2("string2");

  {
    // Pass |use_super_mac| => false.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", false);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));

    transaction->StoreHash("path1", &string_2);
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckValue("path1", &string_2));
  }

  ASSERT_TRUE(GetHashStoreContents()->GetSuperMac().empty());

  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", false);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckValue("new_path", &string_1));
  }
}

TEST_F(PrefHashStoreImplTest, SplitHashStoreAndCheck) {
  base::DictionaryValue dict;
  dict.SetKey("a", base::Value("to be replaced"));
  dict.SetKey("unchanged.path.with.dots", base::Value("same"));
  dict.SetKey("o", base::Value("old"));

  base::DictionaryValue modified_dict;
  modified_dict.SetKey("a", base::Value("replaced"));
  modified_dict.SetKey("unchanged.path.with.dots", base::Value("same"));
  modified_dict.SetKey("c", base::Value("new"));

  base::DictionaryValue empty_dict;

  std::vector<std::string> invalid_keys;

  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));

    // No hashes stored yet and hashes dictionary is empty (and thus not
    // trusted).
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckSplitValue("path1", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());

    transaction->StoreSplitHash("path1", &dict);

    // Verify match post storage.
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckSplitValue("path1", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());

    // Verify new path is still unknown.
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckSplitValue("path2", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());

    // Verify NULL or empty dicts are declared as having been cleared.
    EXPECT_EQ(ValueState::CLEARED,
              transaction->CheckSplitValue("path1", NULL, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
    EXPECT_EQ(ValueState::CLEARED, transaction->CheckSplitValue(
                                       "path1", &empty_dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());

    // Verify changes are properly detected.
    EXPECT_EQ(ValueState::CHANGED, transaction->CheckSplitValue(
                                       "path1", &modified_dict, &invalid_keys));
    std::vector<std::string> expected_invalid_keys1;
    expected_invalid_keys1.push_back("a");
    expected_invalid_keys1.push_back("c");
    expected_invalid_keys1.push_back("o");
    EXPECT_EQ(expected_invalid_keys1, invalid_keys);
    invalid_keys.clear();

    // Verify |dict| still matches post check.
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckSplitValue("path1", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());

    // Store hash for |modified_dict|.
    transaction->StoreSplitHash("path1", &modified_dict);

    // Verify |modified_dict| is now the one that verifies correctly.
    EXPECT_EQ(
        ValueState::UNCHANGED,
        transaction->CheckSplitValue("path1", &modified_dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());

    // Verify old dict no longer matches.
    EXPECT_EQ(ValueState::CHANGED,
              transaction->CheckSplitValue("path1", &dict, &invalid_keys));
    std::vector<std::string> expected_invalid_keys2;
    expected_invalid_keys2.push_back("a");
    expected_invalid_keys2.push_back("o");
    expected_invalid_keys2.push_back("c");
    EXPECT_EQ(expected_invalid_keys2, invalid_keys);
    invalid_keys.clear();
  }

  {
    // |pref_hash_store| should trust its initial hashes dictionary and thus
    // trust new unknown values.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    EXPECT_EQ(ValueState::TRUSTED_UNKNOWN_VALUE,
              transaction->CheckSplitValue("new_path", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
  }
  {
    // Check the same as above for a path with dots.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    EXPECT_EQ(
        ValueState::TRUSTED_UNKNOWN_VALUE,
        transaction->CheckSplitValue("path.with.dots", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
  }

  // Manually corrupt the super MAC.
  GetHashStoreContents()->SetSuperMac(std::string(64, 'A'));

  {
    // |pref_hash_store| should no longer trust its initial hashes dictionary
    // and thus shouldn't trust unknown values.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    EXPECT_EQ(ValueState::UNTRUSTED_UNKNOWN_VALUE,
              transaction->CheckSplitValue("new_path", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
  }
  {
    // Check the same as above for a path with dots.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    EXPECT_EQ(
        ValueState::UNTRUSTED_UNKNOWN_VALUE,
        transaction->CheckSplitValue("path.with.dots", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
  }
}

TEST_F(PrefHashStoreImplTest, EmptyAndNULLSplitDict) {
  base::DictionaryValue empty_dict;

  std::vector<std::string> invalid_keys;

  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));

    // Store hashes for a random dict to be overwritten below.
    base::DictionaryValue initial_dict;
    initial_dict.SetString("a", "foo");
    transaction->StoreSplitHash("path1", &initial_dict);

    // Verify stored empty dictionary matches NULL and empty dictionary back.
    transaction->StoreSplitHash("path1", &empty_dict);
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckSplitValue("path1", NULL, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
    EXPECT_EQ(ValueState::UNCHANGED, transaction->CheckSplitValue(
                                         "path1", &empty_dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());

    // Same when storing NULL directly.
    transaction->StoreSplitHash("path1", NULL);
    EXPECT_EQ(ValueState::UNCHANGED,
              transaction->CheckSplitValue("path1", NULL, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
    EXPECT_EQ(ValueState::UNCHANGED, transaction->CheckSplitValue(
                                         "path1", &empty_dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
  }

  {
    // |pref_hash_store| should trust its initial hashes dictionary (and thus
    // trust new unknown values) even though the last action done was to clear
    // the hashes for path1 by setting its value to NULL (this is a regression
    // test ensuring that the internal action of clearing some hashes does
    // update the stored hash of hashes).
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));

    base::DictionaryValue tested_dict;
    tested_dict.SetString("a", "foo");
    tested_dict.SetString("b", "bar");
    EXPECT_EQ(
        ValueState::TRUSTED_UNKNOWN_VALUE,
        transaction->CheckSplitValue("new_path", &tested_dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
  }
}

// Test that the PrefHashStore returns TRUSTED_UNKNOWN_VALUE when checking for
// a split preference even if there is an existing atomic preference's hash
// stored. There is no point providing a migration path for preferences
// switching strategies after their initial release as split preferences are
// turned into split preferences specifically because the atomic hash isn't
// considered useful.
TEST_F(PrefHashStoreImplTest, TrustedUnknownSplitValueFromExistingAtomic) {
  base::Value string("string1");

  base::DictionaryValue dict;
  dict.SetString("a", "foo");
  dict.SetString("d", "bad");
  dict.SetString("b", "bar");
  dict.SetString("c", "baz");

  {
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));

    transaction->StoreHash("path1", &string);
    EXPECT_EQ(ValueState::UNCHANGED, transaction->CheckValue("path1", &string));
  }

  {
    // Load a new |pref_hash_store| in which the hashes dictionary is trusted.
    PrefHashStoreImpl pref_hash_store(std::string(32, 0), "device_id", true);
    std::unique_ptr<PrefHashStoreTransaction> transaction(
        pref_hash_store.BeginTransaction(GetHashStoreContents()));
    std::vector<std::string> invalid_keys;
    EXPECT_EQ(ValueState::TRUSTED_UNKNOWN_VALUE,
              transaction->CheckSplitValue("path1", &dict, &invalid_keys));
    EXPECT_TRUE(invalid_keys.empty());
  }
}
