// Copyright (c) 2012 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 <windows.h>

#include "base/base_paths.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/win/registry.h"
#include "chrome/installer/util/conditional_work_item_list.h"
#include "chrome/installer/util/work_item.h"
#include "chrome/installer/util/work_item_list.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::win::RegKey;

namespace {

const wchar_t kTestRoot[] = L"ListList";
const wchar_t kDataStr[] = L"data_111";
const wchar_t kName[] = L"name";

class WorkItemListTest : public testing::Test {
 protected:
  virtual void SetUp() {
    // Create a temporary key for testing
    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
    key.DeleteKey(kTestRoot);
    ASSERT_NE(ERROR_SUCCESS, key.Open(HKEY_CURRENT_USER, kTestRoot, KEY_READ));
    ASSERT_EQ(ERROR_SUCCESS,
        key.Create(HKEY_CURRENT_USER, kTestRoot, KEY_READ));

    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
  }

  virtual void TearDown() {
    logging::CloseLogFile();

    // Clean up the temporary key
    RegKey key(HKEY_CURRENT_USER, L"", KEY_ALL_ACCESS);
    ASSERT_EQ(ERROR_SUCCESS, key.DeleteKey(kTestRoot));
  }

  base::ScopedTempDir temp_dir_;
};

}  // namespace

// Execute a WorkItem list successfully and then rollback.
TEST_F(WorkItemListTest, ExecutionSuccess) {
  scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
  scoped_ptr<WorkItem> work_item;

  base::FilePath top_dir_to_create(temp_dir_.path());
  top_dir_to_create = top_dir_to_create.AppendASCII("a");
  base::FilePath dir_to_create(top_dir_to_create);
  dir_to_create = dir_to_create.AppendASCII("b");
  ASSERT_FALSE(base::PathExists(dir_to_create));

  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateDirWorkItem(dir_to_create)));
  work_item_list->AddWorkItem(work_item.release());

  std::wstring key_to_create(kTestRoot);
  key_to_create.push_back(base::FilePath::kSeparators[0]);
  key_to_create.append(L"ExecutionSuccess");

  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create)));
  work_item_list->AddWorkItem(work_item.release());

  std::wstring name(kName);
  std::wstring data(kDataStr);
  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create,
                                          name, data, false)));
  work_item_list->AddWorkItem(work_item.release());

  EXPECT_TRUE(work_item_list->Do());

  // Verify all WorkItems have been executed.
  RegKey key;
  EXPECT_EQ(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  std::wstring read_out;
  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
  EXPECT_EQ(0, read_out.compare(kDataStr));
  key.Close();
  EXPECT_TRUE(base::PathExists(dir_to_create));

  work_item_list->Rollback();

  // Verify everything is rolled back.
  // The value must have been deleted first in roll back otherwise the key
  // can not be deleted.
  EXPECT_NE(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  EXPECT_FALSE(base::PathExists(top_dir_to_create));
}

// Execute a WorkItem list. Fail in the middle. Rollback what has been done.
TEST_F(WorkItemListTest, ExecutionFailAndRollback) {
  scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
  scoped_ptr<WorkItem> work_item;

  base::FilePath top_dir_to_create(temp_dir_.path());
  top_dir_to_create = top_dir_to_create.AppendASCII("a");
  base::FilePath dir_to_create(top_dir_to_create);
  dir_to_create = dir_to_create.AppendASCII("b");
  ASSERT_FALSE(base::PathExists(dir_to_create));

  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateDirWorkItem(dir_to_create)));
  work_item_list->AddWorkItem(work_item.release());

  std::wstring key_to_create(kTestRoot);
  key_to_create.push_back(base::FilePath::kSeparators[0]);
  key_to_create.append(L"ExecutionFail");

  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create)));
  work_item_list->AddWorkItem(work_item.release());

  std::wstring not_created_key(kTestRoot);
  not_created_key.push_back(base::FilePath::kSeparators[0]);
  not_created_key.append(L"NotCreated");
  std::wstring name(kName);
  std::wstring data(kDataStr);
  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, not_created_key,
                                          name, data, false)));
  work_item_list->AddWorkItem(work_item.release());

  // This one will not be executed because we will fail early.
  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER,
                                           not_created_key)));
  work_item_list->AddWorkItem(work_item.release());

  EXPECT_FALSE(work_item_list->Do());

  // Verify the first 2 WorkItems have been executed.
  RegKey key;
  EXPECT_EQ(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  key.Close();
  EXPECT_TRUE(base::PathExists(dir_to_create));
  // The last one should not be there.
  EXPECT_NE(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, not_created_key.c_str(), KEY_READ));

  work_item_list->Rollback();

  // Verify everything is rolled back.
  EXPECT_NE(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  EXPECT_FALSE(base::PathExists(top_dir_to_create));
}

TEST_F(WorkItemListTest, ConditionalExecutionSuccess) {
  scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
  scoped_ptr<WorkItem> work_item;

  base::FilePath top_dir_to_create(temp_dir_.path());
  top_dir_to_create = top_dir_to_create.AppendASCII("a");
  base::FilePath dir_to_create(top_dir_to_create);
  dir_to_create = dir_to_create.AppendASCII("b");
  ASSERT_FALSE(base::PathExists(dir_to_create));

  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateDirWorkItem(dir_to_create)));
  work_item_list->AddWorkItem(work_item.release());

  scoped_ptr<WorkItemList> conditional_work_item_list(
      WorkItem::CreateConditionalWorkItemList(
          new ConditionRunIfFileExists(dir_to_create)));

  std::wstring key_to_create(kTestRoot);
  key_to_create.push_back(base::FilePath::kSeparators[0]);
  key_to_create.append(L"ExecutionSuccess");
  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create)));
  conditional_work_item_list->AddWorkItem(work_item.release());

  std::wstring name(kName);
  std::wstring data(kDataStr);
  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create,
                                          name, data, false)));
  conditional_work_item_list->AddWorkItem(work_item.release());

  work_item_list->AddWorkItem(conditional_work_item_list.release());

  EXPECT_TRUE(work_item_list->Do());

  // Verify all WorkItems have been executed.
  RegKey key;
  EXPECT_EQ(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  std::wstring read_out;
  EXPECT_EQ(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
  EXPECT_EQ(0, read_out.compare(kDataStr));
  key.Close();
  EXPECT_TRUE(base::PathExists(dir_to_create));

  work_item_list->Rollback();

  // Verify everything is rolled back.
  // The value must have been deleted first in roll back otherwise the key
  // can not be deleted.
  EXPECT_NE(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  EXPECT_FALSE(base::PathExists(top_dir_to_create));
}

TEST_F(WorkItemListTest, ConditionalExecutionConditionFailure) {
  scoped_ptr<WorkItemList> work_item_list(WorkItem::CreateWorkItemList());
  scoped_ptr<WorkItem> work_item;

  base::FilePath top_dir_to_create(temp_dir_.path());
  top_dir_to_create = top_dir_to_create.AppendASCII("a");
  base::FilePath dir_to_create(top_dir_to_create);
  dir_to_create = dir_to_create.AppendASCII("b");
  ASSERT_FALSE(base::PathExists(dir_to_create));

  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateDirWorkItem(dir_to_create)));
  work_item_list->AddWorkItem(work_item.release());

  scoped_ptr<WorkItemList> conditional_work_item_list(
      WorkItem::CreateConditionalWorkItemList(
          new ConditionRunIfFileExists(dir_to_create.AppendASCII("c"))));

  std::wstring key_to_create(kTestRoot);
  key_to_create.push_back(base::FilePath::kSeparators[0]);
  key_to_create.append(L"ExecutionSuccess");
  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateCreateRegKeyWorkItem(HKEY_CURRENT_USER, key_to_create)));
  conditional_work_item_list->AddWorkItem(work_item.release());

  std::wstring name(kName);
  std::wstring data(kDataStr);
  work_item.reset(reinterpret_cast<WorkItem*>(
      WorkItem::CreateSetRegValueWorkItem(HKEY_CURRENT_USER, key_to_create,
                                          name, data, false)));
  conditional_work_item_list->AddWorkItem(work_item.release());

  work_item_list->AddWorkItem(conditional_work_item_list.release());

  EXPECT_TRUE(work_item_list->Do());

  // Verify that the WorkItems added as part of the conditional list have NOT
  // been executed.
  RegKey key;
  EXPECT_NE(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  std::wstring read_out;
  EXPECT_NE(ERROR_SUCCESS, key.ReadValue(name.c_str(), &read_out));
  key.Close();

  // Verify that the other work item was executed.
  EXPECT_TRUE(base::PathExists(dir_to_create));

  work_item_list->Rollback();

  // Verify everything is rolled back.
  // The value must have been deleted first in roll back otherwise the key
  // can not be deleted.
  EXPECT_NE(ERROR_SUCCESS,
      key.Open(HKEY_CURRENT_USER, key_to_create.c_str(), KEY_READ));
  EXPECT_FALSE(base::PathExists(top_dir_to_create));
}
