// Copyright (c) 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/policy/preg_parser_win.h"

#include "base/base_paths.h"
#include "base/files/file_path.h"
#include "base/json/json_writer.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "base/values.h"
#include "chrome/browser/policy/policy_load_status.h"
#include "chrome/browser/policy/registry_dict_win.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace policy {
namespace preg_parser {
namespace {

// Check whether two RegistryDicts equal each other.
testing::AssertionResult RegistryDictEquals(const RegistryDict& a,
                                            const RegistryDict& b) {
  RegistryDict::KeyMap::const_iterator iter_key_a(a.keys().begin());
  RegistryDict::KeyMap::const_iterator iter_key_b(b.keys().begin());
  for (; iter_key_a != a.keys().end() && iter_key_b != b.keys().end();
       ++iter_key_a, ++iter_key_b) {
    if (iter_key_a->first != iter_key_b->first) {
      return testing::AssertionFailure()
          << "Key mismatch " << iter_key_a->first
          << " vs. " << iter_key_b->first;
    }
    testing::AssertionResult result = RegistryDictEquals(*iter_key_a->second,
                                                         *iter_key_b->second);
    if (!result)
      return result;
  }

  RegistryDict::ValueMap::const_iterator iter_value_a(a.values().begin());
  RegistryDict::ValueMap::const_iterator iter_value_b(b.values().begin());
  for (; iter_value_a != a.values().end() && iter_value_b != b.values().end();
       ++iter_value_a, ++iter_value_b) {
    if (iter_value_a->first != iter_value_b->first ||
        !base::Value::Equals(iter_value_a->second, iter_value_b->second)) {
      return testing::AssertionFailure()
          << "Value mismatch " << iter_value_a->first
          << " vs. " << iter_value_b->first;
    }
  }

  return testing::AssertionSuccess();
}

void SetInteger(RegistryDict* dict,
                const std::string& name,
                int value) {
  dict->SetValue(
      name,
      make_scoped_ptr<base::Value>(new base::FundamentalValue(value)));
}

void SetString(RegistryDict* dict,
               const std::string& name,
               const std::string&  value) {
  dict->SetValue(
      name,
      make_scoped_ptr<base::Value>(new base::StringValue(value)));
}

TEST(PRegParserWinTest, TestParseFile) {
  base::FilePath test_data_dir;
  ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir));

  // Prepare the test dictionary with some data so the test can check that the
  // PReg action triggers work, i.e. remove these items.
  RegistryDict dict;
  SetInteger(&dict, "DeleteValuesTest1", 1);
  SetString(&dict, "DeleteValuesTest2", "2");
  dict.SetKey("DeleteKeysTest1", make_scoped_ptr(new RegistryDict()));
  scoped_ptr<RegistryDict> delete_keys_test(new RegistryDict());
  SetInteger(delete_keys_test.get(), "DeleteKeysTest2Entry", 1);
  dict.SetKey("DeleteKeysTest2", delete_keys_test.Pass());
  SetInteger(&dict, "DelTest", 1);
  scoped_ptr<RegistryDict> subdict(new RegistryDict());
  SetInteger(subdict.get(), "DelValsTest1", 1);
  SetString(subdict.get(), "DelValsTest2", "2");
  subdict->SetKey("DelValsTest3", make_scoped_ptr(new RegistryDict()));
  dict.SetKey("DelValsTest", subdict.Pass());

  // Run the parser.
  base::FilePath test_file(
      test_data_dir.AppendASCII("chrome/test/data/policy/registry.pol"));
  PolicyLoadStatusSample status;
  ASSERT_TRUE(preg_parser::ReadFile(
      test_file, L"SOFTWARE\\Policies\\Chromium", &dict, &status));

  // Build the expected output dictionary.
  RegistryDict expected;
  scoped_ptr<RegistryDict> del_vals_dict(new RegistryDict());
  del_vals_dict->SetKey("DelValsTest3", make_scoped_ptr(new RegistryDict()));
  expected.SetKey("DelValsTest", del_vals_dict.Pass());
  SetInteger(&expected, "HomepageIsNewTabPage", 1);
  SetString(&expected, "HomepageLocation", "http://www.example.com");
  SetInteger(&expected, "RestoreOnStartup", 4);
  scoped_ptr<RegistryDict> startup_urls(new RegistryDict());
  SetString(startup_urls.get(), "1", "http://www.chromium.org");
  SetString(startup_urls.get(), "2", "http://www.example.com");
  expected.SetKey("RestoreOnStartupURLs", startup_urls.Pass());
  SetInteger(&expected, "ShowHomeButton", 1);
  SetString(&expected, "Snowman", "\xE2\x98\x83");

  EXPECT_TRUE(RegistryDictEquals(dict, expected));
}

}  // namespace
}  // namespace preg_parser
}  // namespace policy
