// 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 "remoting/host/pairing_registry_delegate_win.h"

#include <shlwapi.h>

#include "base/guid.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "base/win/registry.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace remoting {

using protocol::PairingRegistry;

class PairingRegistryDelegateWinTest : public testing::Test {
 public:
  virtual void SetUp() OVERRIDE {
    key_name_ = base::GenerateGUID();

    base::win::RegKey root;
    EXPECT_TRUE(root.Create(HKEY_CURRENT_USER, UTF8ToWide(key_name_).c_str(),
                            KEY_READ | KEY_WRITE) == ERROR_SUCCESS);

    EXPECT_TRUE(privileged_.Create(root.Handle(), L"privileged",
                                   KEY_READ | KEY_WRITE) == ERROR_SUCCESS);
    EXPECT_TRUE(unprivileged_.Create(root.Handle(), L"unprivileged",
                                     KEY_READ | KEY_WRITE) == ERROR_SUCCESS);
  }

  virtual void TearDown() OVERRIDE {
    privileged_.Close();
    unprivileged_.Close();
    EXPECT_TRUE(SHDeleteKey(HKEY_CURRENT_USER,
                            UTF8ToWide(key_name_).c_str()) == ERROR_SUCCESS);
  }

 protected:
  std::string key_name_;
  base::win::RegKey privileged_;
  base::win::RegKey unprivileged_;
};

TEST_F(PairingRegistryDelegateWinTest, SaveAndLoad) {
  scoped_ptr<PairingRegistryDelegateWin> delegate(
      new PairingRegistryDelegateWin());
  delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());

  // Check that registry is initially empty.
  EXPECT_TRUE(delegate->LoadAll()->empty());

  // Add a couple of pairings.
  PairingRegistry::Pairing pairing1(base::Time::Now(), "xxx", "xxx", "xxx");
  PairingRegistry::Pairing pairing2(base::Time::Now(), "yyy", "yyy", "yyy");
  EXPECT_TRUE(delegate->Save(pairing1));
  EXPECT_TRUE(delegate->Save(pairing2));

  // Verify that there are two pairings in the store now.
  EXPECT_EQ(delegate->LoadAll()->GetSize(), 2u);

  // Verify that they can be retrieved.
  EXPECT_EQ(delegate->Load(pairing1.client_id()), pairing1);
  EXPECT_EQ(delegate->Load(pairing2.client_id()), pairing2);

  // Delete the first pairing.
  EXPECT_TRUE(delegate->Delete(pairing1.client_id()));

  // Verify that there is only one pairing left.
  EXPECT_EQ(delegate->Load(pairing1.client_id()), PairingRegistry::Pairing());
  EXPECT_EQ(delegate->Load(pairing2.client_id()), pairing2);

  // Verify that the only remaining value is |pairing2|.
  EXPECT_EQ(delegate->LoadAll()->GetSize(), 1u);
  scoped_ptr<base::ListValue> pairings = delegate->LoadAll();
  base::DictionaryValue* json;
  EXPECT_TRUE(pairings->GetDictionary(0, &json));
  EXPECT_EQ(PairingRegistry::Pairing::CreateFromValue(*json), pairing2);

  // Delete the rest and verify.
  EXPECT_TRUE(delegate->DeleteAll());
  EXPECT_TRUE(delegate->LoadAll()->empty());
}

// Verifies that the delegate is stateless by using two different instances.
TEST_F(PairingRegistryDelegateWinTest, Stateless) {
  scoped_ptr<PairingRegistryDelegateWin> load_delegate(
      new PairingRegistryDelegateWin());
  load_delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());
  scoped_ptr<PairingRegistryDelegateWin> save_delegate(
      new PairingRegistryDelegateWin());
  save_delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());

  PairingRegistry::Pairing pairing(base::Time::Now(), "xxx", "xxx", "xxx");
  EXPECT_TRUE(save_delegate->Save(pairing));
  EXPECT_EQ(load_delegate->Load(pairing.client_id()), pairing);
}

TEST_F(PairingRegistryDelegateWinTest, Unprivileged) {
  scoped_ptr<PairingRegistryDelegateWin> delegate(
      new PairingRegistryDelegateWin());
  delegate->SetRootKeys(privileged_.Handle(), unprivileged_.Handle());

  PairingRegistry::Pairing pairing(base::Time::Now(), "xxx", "xxx", "xxx");
  EXPECT_TRUE(delegate->Save(pairing));
  EXPECT_EQ(delegate->Load(pairing.client_id()), pairing);

  // Strip the delegate from write access and validate that it still can be used
  // to read the pairings.
  delegate.reset(new PairingRegistryDelegateWin());
  delegate->SetRootKeys(NULL, unprivileged_.Handle());

  PairingRegistry::Pairing unprivileged_pairing =
      delegate->Load(pairing.client_id());
  EXPECT_EQ(pairing.client_id(), unprivileged_pairing.client_id());
  EXPECT_EQ(pairing.client_name(), unprivileged_pairing.client_name());
  EXPECT_EQ(pairing.created_time(), unprivileged_pairing.created_time());

  // Verify that the shared secret if not available.
  EXPECT_TRUE(unprivileged_pairing.shared_secret().empty());

  // Verify that a pairing cannot be saved.
  EXPECT_FALSE(delegate->Save(pairing));
}

}  // namespace remoting
