// 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,
                            base::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,
                    base::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
