// 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 "chrome/browser/prefs/pref_hash_calculator.h"

#include <string>

#include "base/bind.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "chrome/browser/prefs/tracked/pref_hash_calculator_helper.h"
#include "testing/gtest/include/gtest/gtest.h"

TEST(PrefHashCalculatorTest, TestCurrentAlgorithm) {
  base::StringValue string_value_1("string value 1");
  base::StringValue string_value_2("string value 2");
  base::DictionaryValue dictionary_value_1;
  dictionary_value_1.SetInteger("int value", 1);
  dictionary_value_1.Set("nested empty map", new base::DictionaryValue);
  base::DictionaryValue dictionary_value_1_equivalent;
  dictionary_value_1_equivalent.SetInteger("int value", 1);
  base::DictionaryValue dictionary_value_2;
  dictionary_value_2.SetInteger("int value", 2);

  PrefHashCalculator calc1("seed1", "deviceid");
  PrefHashCalculator calc1_dup("seed1", "deviceid");
  PrefHashCalculator calc2("seed2", "deviceid");
  PrefHashCalculator calc3("seed1", "deviceid2");

  // Two calculators with same seed produce same hash.
  ASSERT_EQ(calc1.Calculate("pref_path", &string_value_1),
            calc1_dup.Calculate("pref_path", &string_value_1));
  ASSERT_EQ(PrefHashCalculator::VALID,
            calc1_dup.Validate(
                "pref_path",
                &string_value_1,
                calc1.Calculate("pref_path", &string_value_1)));

  // Different seeds, different hashes.
  ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
            calc2.Calculate("pref_path", &string_value_1));
  ASSERT_EQ(PrefHashCalculator::INVALID,
            calc2.Validate(
                "pref_path",
                &string_value_1,
                calc1.Calculate("pref_path", &string_value_1)));

  // Different device IDs, different hashes.
  ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
            calc3.Calculate("pref_path", &string_value_1));

  // Different values, different hashes.
  ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
            calc1.Calculate("pref_path", &string_value_2));

  // Different paths, different hashes.
  ASSERT_NE(calc1.Calculate("pref_path", &string_value_1),
            calc1.Calculate("pref_path_2", &string_value_1));

  // Works for dictionaries.
  ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
            calc1.Calculate("pref_path", &dictionary_value_1));
  ASSERT_NE(calc1.Calculate("pref_path", &dictionary_value_1),
            calc1.Calculate("pref_path", &dictionary_value_2));

  // Empty dictionary children are pruned.
  ASSERT_EQ(calc1.Calculate("pref_path", &dictionary_value_1),
            calc1.Calculate("pref_path", &dictionary_value_1_equivalent));

  // NULL value is supported.
  ASSERT_FALSE(calc1.Calculate("pref_path", NULL).empty());
}

// Tests the output against a known value to catch unexpected algorithm changes.
// The test hashes below must NEVER be updated, the serialization algorithm used
// must always be able to generate data that will produce these exact hashes.
TEST(PrefHashCalculatorTest, CatchHashChanges) {
  static const char kSeed[] = "0123456789ABCDEF0123456789ABCDEF";
  static const char kDeviceId[] = "test_device_id1";

  scoped_ptr<base::Value> null_value(base::Value::CreateNullValue());
  scoped_ptr<base::Value> bool_value(base::Value::CreateBooleanValue(false));
  scoped_ptr<base::Value> int_value(
      base::Value::CreateIntegerValue(1234567890));
  scoped_ptr<base::Value> double_value(
      base::Value::CreateDoubleValue(123.0987654321));
  scoped_ptr<base::Value> string_value(base::Value::CreateStringValue(
      "testing with special chars:\n<>{}:^^@#$\\/"));

  // For legacy reasons, we have to support pruning of empty lists/dictionaries
  // and nested empty ists/dicts in the hash generation algorithm.
  scoped_ptr<base::DictionaryValue> nested_empty_dict(
      new base::DictionaryValue);
  nested_empty_dict->Set("a", new base::DictionaryValue);
  nested_empty_dict->Set("b", new base::ListValue);
  scoped_ptr<base::ListValue> nested_empty_list(
      new base::ListValue);
  nested_empty_list->Append(new base::DictionaryValue);
  nested_empty_list->Append(new base::ListValue);
  nested_empty_list->Append(nested_empty_dict->DeepCopy());

  // A dictionary with an empty dictionary, an empty list, and nested empty
  // dictionaries/lists in it.
  scoped_ptr<base::DictionaryValue> dict_value(new base::DictionaryValue);
  dict_value->Set("a", new base::StringValue("foo"));
  dict_value->Set("d", new base::ListValue);
  dict_value->Set("b", new base::DictionaryValue);
  dict_value->Set("c", new base::StringValue("baz"));
  dict_value->Set("e", nested_empty_dict.release());
  dict_value->Set("f", nested_empty_list.release());

  scoped_ptr<base::ListValue> list_value(new base::ListValue);
  list_value->AppendBoolean(true);
  list_value->AppendInteger(100);
  list_value->AppendDouble(1.0);

  ASSERT_EQ(base::Value::TYPE_NULL, null_value->GetType());
  ASSERT_EQ(base::Value::TYPE_BOOLEAN, bool_value->GetType());
  ASSERT_EQ(base::Value::TYPE_INTEGER, int_value->GetType());
  ASSERT_EQ(base::Value::TYPE_DOUBLE, double_value->GetType());
  ASSERT_EQ(base::Value::TYPE_STRING, string_value->GetType());
  ASSERT_EQ(base::Value::TYPE_DICTIONARY, dict_value->GetType());
  ASSERT_EQ(base::Value::TYPE_LIST, list_value->GetType());

  // Test every value type independently. Intentionally omits TYPE_BINARY which
  // isn't even allowed in JSONWriter's input.
  static const char kExpectedNullValue[] =
      "C2871D0AC76176E39948C50A9A562B863E610FDA90C675A6A8AD16B4DC4F53DC";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", null_value.get(), kExpectedNullValue));

  static const char kExpectedBooleanValue[] =
      "A326E2F405CFE05D08289CDADD9DB4F529592F0945A8CE204289E4C930D8AA43";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", bool_value.get(), kExpectedBooleanValue));

  static const char kExpectedIntegerValue[] =
      "4B69938F802A2A26D69467F3E1E4A474F6323C64EFC54DBDB4A5708A7D005042";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", int_value.get(), kExpectedIntegerValue));

  static const char kExpectedDoubleValue[] =
      "1734C9C745B9C92D896B9A710994BF1B56D55BFB0F00C207EC995152AF02F08F";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", double_value.get(), kExpectedDoubleValue));

  static const char kExpectedStringValue[] =
      "154D15522C856AA944BFA5A9E3FFB46925BF2B95A10199564651CA1C13E98433";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", string_value.get(), kExpectedStringValue));

  static const char kExpectedDictValue[] =
      "597CECCBF930AF1FFABAC6AF3851C062867C134B4D5A06BDB3B03B988A182CBB";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", dict_value.get(), kExpectedDictValue));

  static const char kExpectedListValue[] =
      "4E2CC0A9B8DF8C5049C53E8B139007792EC6295239545BC99BBF9CDE8A2F5E30";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", list_value.get(), kExpectedListValue));

  // Also test every value type together in the same dictionary.
  base::DictionaryValue everything;
  everything.Set("null", null_value.release());
  everything.Set("bool", bool_value.release());
  everything.Set("int", int_value.release());
  everything.Set("double", double_value.release());
  everything.Set("string", string_value.release());
  everything.Set("list", list_value.release());
  everything.Set("dict", dict_value.release());
  static const char kExpectedEverythingValue[] =
      "5A9D15E4D2FA909007EDE6A18605735E3EB712E2EDE83D6735CE5DD96A5AFBAA";
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kDeviceId).Validate(
                "pref.path", &everything, kExpectedEverythingValue));
}

TEST(PrefHashCalculatorTest, TestCompatibilityWithPrefMetricsService) {
  static const char kSeed[] = {
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
    0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
  };
  static const char kDeviceId[] =
      "D730D9CBD98C734A4FB097A1922275FE9F7E026A4EA1BE0E84";
  static const char kExpectedValue[] =
      "845EF34663FF8D32BE6707F40258FBA531C2BFC532E3B014AFB3476115C2A9DE";

  base::ListValue startup_urls;
  startup_urls.Set(0, new base::StringValue("http://www.chromium.org/"));

  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(std::string(kSeed, arraysize(kSeed)), kDeviceId).
            Validate("session.startup_urls", &startup_urls, kExpectedValue));
}

TEST(PrefHashCalculatorTest, TestLegacyNoDeviceIdNoPathAlgorithm) {
  static const char kTestedLegacyHash[] =
      "C503FB7C65EEFD5C07185F616A0AA67923C069909933F362022B1F187E73E9A2";
  static const char kDeviceId[] = "not_used";

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

  // 32 NULL bytes is the seed that was used to generate the legacy hash.
  EXPECT_EQ(PrefHashCalculator::VALID_WEAK_LEGACY,
            PrefHashCalculator(std::string(32u, 0), kDeviceId).Validate(
                "unused_path", &dict, kTestedLegacyHash));
}

std::string MockGetLegacyDeviceId(const std::string& modern_device_id) {
  if (modern_device_id.empty())
    return std::string();
  return modern_device_id + "_LEGACY";
}

TEST(PrefHashCalculatorTest, TestLegacyDeviceIdAlgorithm) {
  // The full algorithm should kick in when the device id is non-empty and we
  // should thus get VALID_SECURE_LEGACY on verification.
  static const char kDeviceId[] = "DEVICE_ID";
  static const char kSeed[] = "01234567890123456789012345678901";
  static const char kPrefPath[] = "test.pref";
  static const char kPrefValue[] = "http://example.com/";
  // Test hash based on the mock legacy id (based on kDeviceId) + kPrefPath +
  // kPrefValue under kSeed.
  static const char kTestedHash[] =
      "09ABD84B13E4366B24DFF898C8C4614E033514B4E2EF3C6810F50B63273C83AD";

  const base::StringValue string_value(kPrefValue);
  EXPECT_EQ(PrefHashCalculator::VALID_SECURE_LEGACY,
            PrefHashCalculator(kSeed, kDeviceId,
                               base::Bind(&MockGetLegacyDeviceId)).Validate(
                kPrefPath, &string_value, kTestedHash));
}

TEST(PrefHashCalculatorTest, TestLegacyDeviceIdAlgorithmOnEmptyDeviceId) {
  // MockGetLegacyDeviceId will return a legacy device ID that is the same
  // (empty) as the modern device ID here. So this MAC will be valid using
  // either ID. The PrefHashCalculator should return VALID, not
  // VALID_SECURE_LEGACY, in this case.
  static const char kEmptyDeviceId[] = "";
  static const char kSeed[] = "01234567890123456789012345678901";
  static const char kPrefPath[] = "test.pref";
  static const char kPrefValue[] = "http://example.com/";
  // Test hash based on an empty legacy device id + kPrefPath + kPrefValue under
  // kSeed.
  static const char kTestedHash[] =
      "842C71283B9C3D86AA934CD639FDB0428BF0E2B6EC8537A21575CC4C4FA0A615";

  const base::StringValue string_value(kPrefValue);
  EXPECT_EQ(PrefHashCalculator::VALID,
            PrefHashCalculator(kSeed, kEmptyDeviceId,
                               base::Bind(&MockGetLegacyDeviceId)).Validate(
                kPrefPath, &string_value, kTestedHash));
}
