/*
 *  Copyright 2003 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

// Unittest for registry access API

#include "webrtc/base/gunit.h"
#include "webrtc/base/common.h"
#include "webrtc/base/win32regkey.h"

namespace rtc {

#ifndef EXPECT_SUCCEEDED
#define EXPECT_SUCCEEDED(x)  EXPECT_TRUE(SUCCEEDED(x))
#endif

#ifndef EXPECT_FAILED
#define EXPECT_FAILED(x)  EXPECT_TRUE(FAILED(x))
#endif

#define kBaseKey           L"Software\\Google\\__TEST"
#define kSubkeyName        L"subkey_test"

const wchar_t kRkey1[] = kBaseKey;
const wchar_t kRkey1SubkeyName[] = kSubkeyName;
const wchar_t kRkey1Subkey[] = kBaseKey L"\\" kSubkeyName;
const wchar_t kFullRkey1[] = L"HKCU\\" kBaseKey;
const wchar_t kFullRkey1Subkey[] = L"HKCU\\" kBaseKey L"\\" kSubkeyName;

const wchar_t kValNameInt[] = L"Int32 Value";
const DWORD kIntVal = 20;
const DWORD kIntVal2 = 30;

const wchar_t kValNameInt64[] = L"Int64 Value";
const DWORD64 kIntVal64 = 119600064000000000uI64;

const wchar_t kValNameFloat[] = L"Float Value";
const float kFloatVal = 12.3456789f;

const wchar_t kValNameDouble[] = L"Double Value";
const double kDoubleVal = 98.7654321;

const wchar_t kValNameStr[] = L"Str Value";
const wchar_t kStrVal[] = L"Some string data 1";
const wchar_t kStrVal2[] = L"Some string data 2";

const wchar_t kValNameBinary[] = L"Binary Value";
const char kBinaryVal[] = "Some binary data abcdefghi 1";
const char kBinaryVal2[] = "Some binary data abcdefghi 2";

const wchar_t kValNameMultiStr[] = L"MultiStr Value";
const wchar_t kMultiSZ[] = L"abc\0def\0P12345\0";
const wchar_t kEmptyMultiSZ[] = L"";
const wchar_t kInvalidMultiSZ[] = {L'6', L'7', L'8'};

// friend function of RegKey
void RegKeyHelperFunctionsTest() {
  // Try out some dud values
  std::wstring temp_key = L"";
  EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL);
  EXPECT_STREQ(temp_key.c_str(), L"");

  temp_key = L"a";
  EXPECT_TRUE(RegKey::GetRootKeyInfo(&temp_key) == NULL);
  EXPECT_STREQ(temp_key.c_str(), L"");

  // The basics
  temp_key = L"HKLM\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_LOCAL_MACHINE\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_LOCAL_MACHINE);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKCU\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_CURRENT_USER\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CURRENT_USER);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKU\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_USERS\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_USERS);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKCR\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"HKEY_CLASSES_ROOT\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  // Make sure it is case insensitive
  temp_key = L"hkcr\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"hkey_CLASSES_ROOT\\a";
  EXPECT_EQ(RegKey::GetRootKeyInfo(&temp_key), HKEY_CLASSES_ROOT);
  EXPECT_STREQ(temp_key.c_str(), L"a");

  //
  // Test RegKey::GetParentKeyInfo
  //

  // dud cases
  temp_key = L"";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
  EXPECT_STREQ(temp_key.c_str(), L"");

  temp_key = L"a";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
  EXPECT_STREQ(temp_key.c_str(), L"a");

  temp_key = L"a\\b";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"a");
  EXPECT_STREQ(temp_key.c_str(), L"b");

  temp_key = L"\\b";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(), L"");
  EXPECT_STREQ(temp_key.c_str(), L"b");

  // Some regular cases
  temp_key = L"HKEY_CLASSES_ROOT\\moon";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(),
               L"HKEY_CLASSES_ROOT");
  EXPECT_STREQ(temp_key.c_str(), L"moon");

  temp_key = L"HKEY_CLASSES_ROOT\\moon\\doggy";
  EXPECT_STREQ(RegKey::GetParentKeyInfo(&temp_key).c_str(),
               L"HKEY_CLASSES_ROOT\\moon");
  EXPECT_STREQ(temp_key.c_str(), L"doggy");

  //
  // Test MultiSZBytesToStringArray
  //

  std::vector<std::wstring> result;
  EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray(
      reinterpret_cast<const uint8*>(kMultiSZ), sizeof(kMultiSZ), &result));
  EXPECT_EQ(result.size(), 3);
  EXPECT_STREQ(result[0].c_str(), L"abc");
  EXPECT_STREQ(result[1].c_str(), L"def");
  EXPECT_STREQ(result[2].c_str(), L"P12345");

  EXPECT_SUCCEEDED(RegKey::MultiSZBytesToStringArray(
      reinterpret_cast<const uint8*>(kEmptyMultiSZ),
      sizeof(kEmptyMultiSZ), &result));
  EXPECT_EQ(result.size(), 0);
  EXPECT_FALSE(SUCCEEDED(RegKey::MultiSZBytesToStringArray(
      reinterpret_cast<const uint8*>(kInvalidMultiSZ),
      sizeof(kInvalidMultiSZ), &result)));
}

TEST(RegKeyTest, RegKeyHelperFunctionsTest) {
  RegKeyHelperFunctionsTest();
}

void RegKeyNonStaticFunctionsTest() {
  DWORD int_val = 0;
  DWORD64 int64_val = 0;
  wchar_t* str_val = NULL;
  uint8* binary_val = NULL;
  DWORD uint8_count = 0;

  // Just in case...
  // make sure the no test key residue is left from previous aborted runs
  RegKey::DeleteKey(kFullRkey1);

  // initial state
  RegKey r_key;
  EXPECT_TRUE(r_key.key() == NULL);

  // create a reg key
  EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1));

  // do the create twice - it should return the already created one
  EXPECT_SUCCEEDED(r_key.Create(HKEY_CURRENT_USER, kRkey1));

  // now do an open - should work just fine
  EXPECT_SUCCEEDED(r_key.Open(HKEY_CURRENT_USER, kRkey1));

  // get an in-existent value
  EXPECT_EQ(r_key.GetValue(kValNameInt, &int_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // set and get some values

  // set an INT 32
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameInt));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal);

  // set it again!
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal2));

  // read it again
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal2);

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameInt));

  // set an INT 64
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameInt64));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameInt64, &int64_val));
  EXPECT_EQ(int64_val, kIntVal64);

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameInt64));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameInt64));

  // set a string
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameStr));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val));
  EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0);
  delete[] str_val;

  // set it again
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal2));

  // read it again
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameStr, &str_val));
  EXPECT_TRUE(lstrcmp(str_val, kStrVal2) == 0);
  delete[] str_val;

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameStr));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameInt));

  // set a binary value
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), sizeof(kBinaryVal) - 1));

  // check that the value exists
  EXPECT_TRUE(r_key.HasValue(kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count));
  EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal) - 1) == 0);
  delete[] binary_val;

  // set it again
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal2), sizeof(kBinaryVal) - 1));

  // read it again
  EXPECT_SUCCEEDED(r_key.GetValue(kValNameBinary, &binary_val, &uint8_count));
  EXPECT_TRUE(memcmp(binary_val, kBinaryVal2, sizeof(kBinaryVal2) - 1) == 0);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(r_key.DeleteValue(kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(r_key.HasValue(kValNameBinary));

  // set some values and check the total count

  // set an INT 32
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt, kIntVal));

  // set an INT 64
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameInt64, kIntVal64));

  // set a string
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameStr, kStrVal));

  // set a binary value
  EXPECT_SUCCEEDED(r_key.SetValue(kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), sizeof(kBinaryVal) - 1));

  // get the value count
  uint32 value_count = r_key.GetValueCount();
  EXPECT_EQ(value_count, 4);

  // check the value names
  std::wstring value_name;
  DWORD type = 0;

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(0, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameInt);
  EXPECT_EQ(type, REG_DWORD);

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(1, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameInt64);
  EXPECT_EQ(type, REG_QWORD);

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(2, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameStr);
  EXPECT_EQ(type, REG_SZ);

  EXPECT_SUCCEEDED(r_key.GetValueNameAt(3, &value_name, &type));
  EXPECT_STREQ(value_name.c_str(), kValNameBinary);
  EXPECT_EQ(type, REG_BINARY);

  // check that there are no more values
  EXPECT_FAILED(r_key.GetValueNameAt(4, &value_name, &type));

  uint32 subkey_count = r_key.GetSubkeyCount();
  EXPECT_EQ(subkey_count, 0);

  // now create a subkey and make sure we can get the name
  RegKey temp_key;
  EXPECT_SUCCEEDED(temp_key.Create(HKEY_CURRENT_USER, kRkey1Subkey));

  // check the subkey exists
  EXPECT_TRUE(r_key.HasSubkey(kRkey1SubkeyName));

  // check the name
  EXPECT_EQ(r_key.GetSubkeyCount(), 1);

  std::wstring subkey_name;
  EXPECT_SUCCEEDED(r_key.GetSubkeyNameAt(0, &subkey_name));
  EXPECT_STREQ(subkey_name.c_str(), kRkey1SubkeyName);

  // delete the key
  EXPECT_SUCCEEDED(r_key.DeleteSubKey(kRkey1));

  // close this key
  EXPECT_SUCCEEDED(r_key.Close());

  // whack the whole key
  EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1));
}

void RegKeyStaticFunctionsTest() {
  DWORD int_val = 0;
  DWORD64 int64_val = 0;
  float float_val = 0;
  double double_val = 0;
  wchar_t* str_val = NULL;
  std::wstring wstr_val;
  uint8* binary_val = NULL;
  DWORD uint8_count = 0;

  // Just in case...
  // make sure the no test key residue is left from previous aborted runs
  RegKey::DeleteKey(kFullRkey1);

  // get an in-existent value from an un-existent key
  EXPECT_EQ(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // set int32
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt, kIntVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt));

  // get an in-existent value from an existent key
  EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &int_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt));

  // set int64
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameInt64, kIntVal64));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameInt64));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameInt64, &int64_val));
  EXPECT_EQ(int64_val, kIntVal64);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameInt64));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameInt64));

  // set float
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameFloat, kFloatVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameFloat));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val));
  EXPECT_EQ(float_val, kFloatVal);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameFloat));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameFloat));
  EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameFloat, &float_val));

  // set double
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameDouble, kDoubleVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameDouble));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val));
  EXPECT_EQ(double_val, kDoubleVal);

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameDouble));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameDouble));
  EXPECT_FAILED(RegKey::GetValue(kFullRkey1, kValNameDouble, &double_val));

  // set string
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameStr, kStrVal));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameStr));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &str_val));
  EXPECT_TRUE(lstrcmp(str_val, kStrVal) == 0);
  delete[] str_val;

  // read it back in std::wstring
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameStr, &wstr_val));
  EXPECT_STREQ(wstr_val.c_str(), kStrVal);

  // get an in-existent value from an existent key
  EXPECT_EQ(RegKey::GetValue(kFullRkey1, L"bogus", &str_val),
            HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND));

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameStr));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameStr));

  // set binary
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), sizeof(kBinaryVal)-1));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
      &binary_val, &uint8_count));
  EXPECT_TRUE(memcmp(binary_val, kBinaryVal, sizeof(kBinaryVal)-1) == 0);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // special case - set a binary value with length 0
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary,
      reinterpret_cast<const uint8*>(kBinaryVal), 0));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
      &binary_val, &uint8_count));
  EXPECT_EQ(uint8_count, 0);
  EXPECT_TRUE(binary_val == NULL);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // special case - set a NULL binary value
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1, kValNameBinary, NULL, 100));

  // check that the value exists
  EXPECT_TRUE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // read it back
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameBinary,
                                    &binary_val, &uint8_count));
  EXPECT_EQ(uint8_count, 0);
  EXPECT_TRUE(binary_val == NULL);
  delete[] binary_val;

  // delete the value
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1, kValNameBinary));

  // check that the value is gone
  EXPECT_FALSE(RegKey::HasValue(kFullRkey1, kValNameBinary));

  // test read/write REG_MULTI_SZ value
  std::vector<std::wstring> result;
  EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr,
      reinterpret_cast<const uint8*>(kMultiSZ), sizeof(kMultiSZ)));
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
  EXPECT_EQ(result.size(), 3);
  EXPECT_STREQ(result[0].c_str(), L"abc");
  EXPECT_STREQ(result[1].c_str(), L"def");
  EXPECT_STREQ(result[2].c_str(), L"P12345");
  EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr,
      reinterpret_cast<const uint8*>(kEmptyMultiSZ), sizeof(kEmptyMultiSZ)));
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
  EXPECT_EQ(result.size(), 0);
  // writing REG_MULTI_SZ value will automatically add ending null characters
  EXPECT_SUCCEEDED(RegKey::SetValueMultiSZ(kFullRkey1, kValNameMultiStr,
      reinterpret_cast<const uint8*>(kInvalidMultiSZ), sizeof(kInvalidMultiSZ)));
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1, kValNameMultiStr, &result));
  EXPECT_EQ(result.size(), 1);
  EXPECT_STREQ(result[0].c_str(), L"678");

  // Run the following test only in dev machine
  // This is because the build machine might not have admin privilege
#ifdef IS_PRIVATE_BUILD
  // get a temp file name
  wchar_t temp_path[MAX_PATH] = {0};
  EXPECT_LT(::GetTempPath(ARRAY_SIZE(temp_path), temp_path),
            static_cast<DWORD>(ARRAY_SIZE(temp_path)));
  wchar_t temp_file[MAX_PATH] = {0};
  EXPECT_NE(::GetTempFileName(temp_path, L"rkut_",
                              ::GetTickCount(), temp_file), 0);

  // test save
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt, kIntVal));
  EXPECT_SUCCEEDED(RegKey::SetValue(kFullRkey1Subkey, kValNameInt64, kIntVal64));
  EXPECT_SUCCEEDED(RegKey::Save(kFullRkey1Subkey, temp_file));
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt));
  EXPECT_SUCCEEDED(RegKey::DeleteValue(kFullRkey1Subkey, kValNameInt64));

  // test restore
  EXPECT_SUCCEEDED(RegKey::Restore(kFullRkey1Subkey, temp_file));
  int_val = 0;
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey, kValNameInt, &int_val));
  EXPECT_EQ(int_val, kIntVal);
  int64_val = 0;
  EXPECT_SUCCEEDED(RegKey::GetValue(kFullRkey1Subkey,
                                    kValNameInt64,
                                    &int64_val));
  EXPECT_EQ(int64_val, kIntVal64);

  // delete the temp file
  EXPECT_EQ(TRUE, ::DeleteFile(temp_file));
#endif

  // whack the whole key
  EXPECT_SUCCEEDED(RegKey::DeleteKey(kFullRkey1));
}

// Run both tests under the same test target. Because they access (read and
// write) the same registry keys they can't run in parallel with eachother.
TEST(RegKeyTest, RegKeyFunctionsTest) {
  RegKeyNonStaticFunctionsTest();
  RegKeyStaticFunctionsTest();
}

}  // namespace rtc
