// Copyright 2018 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 "base/base_paths.h"
#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/scoped_native_library.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_reg_util_win.h"
#include "base/threading/thread_restrictions.h"
#include "base/win/win_util.h"
#include "base/win/windows_version.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/conflicts/incompatible_applications_updater_win.h"
#include "chrome/browser/conflicts/module_database_win.h"
#include "chrome/browser/conflicts/proto/module_list.pb.h"
#include "chrome/browser/conflicts/third_party_conflicts_manager_win.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "components/prefs/pref_change_registrar.h"
#include "components/prefs/pref_service.h"
#include "components/viz/common/features.h"

// This class allows to wait until the kIncompatibleApplications preference is
// modified. This can only happen if a new incompatible application is found,
// since the pref starts empty during testing.
//
// Note: The browser process must be initialized before the creation of an
// instance of this class.
class IncompatibleApplicationsObserver {
 public:
  IncompatibleApplicationsObserver() {
    pref_change_registrar_.Init(g_browser_process->local_state());
    pref_change_registrar_.Add(
        prefs::kIncompatibleApplications,
        base::BindRepeating(&IncompatibleApplicationsObserver::
                                OnIncompatibleApplicationsChanged,
                            base::Unretained(this)));
  }

  ~IncompatibleApplicationsObserver() = default;

  // Wait until the kIncompatibleApplications preference is modified.
  void WaitForIncompatibleApplicationsChanged() {
    if (incompatible_applications_changed_)
      return;

    base::RunLoop run_loop;
    run_loop_quit_closure_ = run_loop.QuitClosure();
    run_loop.Run();
  }

 private:
  // Callback for |pref_change_registrar_|.
  void OnIncompatibleApplicationsChanged() {
    incompatible_applications_changed_ = true;

    if (run_loop_quit_closure_)
      std::move(run_loop_quit_closure_).Run();
  }

  bool incompatible_applications_changed_ = false;

  PrefChangeRegistrar pref_change_registrar_;

  base::RepeatingClosure run_loop_quit_closure_;

  DISALLOW_COPY_AND_ASSIGN(IncompatibleApplicationsObserver);
};

class IncompatibleApplicationsBrowserTest : public InProcessBrowserTest {
 protected:
  // The name of the application deemed incompatible.
  static constexpr wchar_t kApplicationName[] = L"FooBar123";

  IncompatibleApplicationsBrowserTest() : scoped_domain_(true) {}

  ~IncompatibleApplicationsBrowserTest() override = default;

  void SetUp() override {
    // TODO(crbug.com/850517): Don't do test-specific setup if the test isn't
    // going to do anything. It seems to conflict with the VizDisplayCompositor
    // feature.
    if (!features::IsVizDisplayCompositorEnabled()) {
      ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());

      ASSERT_NO_FATAL_FAILURE(
          registry_override_manager_.OverrideRegistry(HKEY_LOCAL_MACHINE));
      ASSERT_NO_FATAL_FAILURE(
          registry_override_manager_.OverrideRegistry(HKEY_CURRENT_USER));

      scoped_feature_list_.InitAndEnableFeature(
          features::kIncompatibleApplicationsWarning);

      ASSERT_NO_FATAL_FAILURE(CreateModuleList());
      ASSERT_NO_FATAL_FAILURE(InstallThirdPartyApplication());
    }

    InProcessBrowserTest::SetUp();
  }

  // Returns the path to the module list.
  base::FilePath GetModuleListPath() const {
    return scoped_temp_dir_.GetPath().Append(L"ModuleList.bin");
  }

  // Returns the path to the DLL that is injected into the process.
  base::FilePath GetDllPath() const {
    return scoped_temp_dir_.GetPath()
        .Append(kApplicationName)
        .Append(L"foo_bar.dll");
  }

 private:
  // Writes an empty serialized ModuleList proto to |GetModuleListPath()|.
  void CreateModuleList() {
    chrome::conflicts::ModuleList module_list;
    // Include an empty blacklist and whitelist.
    module_list.mutable_blacklist();
    module_list.mutable_whitelist();

    std::string contents;
    ASSERT_TRUE(module_list.SerializeToString(&contents));
    ASSERT_EQ(base::WriteFile(GetModuleListPath(), contents.data(),
                              static_cast<int>(contents.size())),
              static_cast<int>(contents.size()));
  }

  // Registers an uninstallation entry for the third-party application, and
  // creates a DLL meant to be injected into the process.
  void InstallThirdPartyApplication() {
    // This module should not be a static dependency of the test executable, but
    // should be a build-system dependency or a module that is present on any
    // Windows machine.
    static constexpr wchar_t kTestDllName[] = L"conflicts_dll.dll";
    static constexpr wchar_t kRegistryKeyPathFormat[] =
        L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%ls";

    // Note: Using the application name for the product id.
    const base::string16 registry_key_path =
        base::StringPrintf(kRegistryKeyPathFormat, kApplicationName);
    base::win::RegKey registry_key(HKEY_CURRENT_USER, registry_key_path.c_str(),
                                   KEY_WRITE);

    const base::FilePath dll_path = GetDllPath();
    ASSERT_EQ(registry_key.WriteValue(L"DisplayName", kApplicationName),
              ERROR_SUCCESS);
    ASSERT_EQ(registry_key.WriteValue(L"InstallLocation",
                                      dll_path.DirName().value().c_str()),
              ERROR_SUCCESS);

    // The UninstallString is required but its value doesn't matter.
    ASSERT_EQ(
        registry_key.WriteValue(L"UninstallString", L"c:\\foo\\uninstall.exe"),
        ERROR_SUCCESS);

    // Copy the test DLL to the install directory so that it will get associated
    // with the application by the IncompatibleApplicationsUpdater.
    base::FilePath test_dll_path;
    ASSERT_TRUE(base::PathService::Get(base::DIR_EXE, &test_dll_path));
    test_dll_path = test_dll_path.Append(kTestDllName);

    ASSERT_TRUE(base::CreateDirectory(dll_path.DirName()));
    ASSERT_TRUE(base::CopyFile(test_dll_path, dll_path));
  }

  // The feature is always disabled on domain-joined machines.
  base::win::ScopedDomainStateForTesting scoped_domain_;

  // Temp directory used to host the install directory and the module list.
  base::ScopedTempDir scoped_temp_dir_;

  // Overrides HKLM and HKCU so that the InstalledApplications instance doesn't
  // pick up real applications on the test machine.
  registry_util::RegistryOverrideManager registry_override_manager_;

  // Enables the IncompatibleApplicationsWarning feature.
  base::test::ScopedFeatureList scoped_feature_list_;

  DISALLOW_COPY_AND_ASSIGN(IncompatibleApplicationsBrowserTest);
};

// static
constexpr wchar_t IncompatibleApplicationsBrowserTest::kApplicationName[];

// This is an integration test for the identification of incompatible
// applications.
//
// This test makes sure that all the different classes interact together
// correctly.
//
// Note: This doesn't test that the chrome://settings/incompatibleApplications
// page is shown after a browser crash.
IN_PROC_BROWSER_TEST_F(IncompatibleApplicationsBrowserTest,
                       InjectIncompatibleDLL) {
  if (base::win::GetVersion() < base::win::Version::WIN10)
    return;

  // TODO(crbug.com/850517) This fails in viz_browser_tests in official builds.
  if (features::IsVizDisplayCompositorEnabled())
    return;

  ModuleDatabase* module_database = ModuleDatabase::GetInstance();

  // Speed up the test.
  module_database->IncreaseInspectionPriority();

  // Create the observer early so the change is guaranteed to be observed.
  auto incompatible_applications_observer =
      std::make_unique<IncompatibleApplicationsObserver>();

  // Simulate the download of the module list component.
  module_database->third_party_conflicts_manager()->LoadModuleList(
      GetModuleListPath());

  // Injects the DLL into the process.
  base::ScopedAllowBlockingForTesting scoped_allow_blocking;
  base::ScopedNativeLibrary dll(GetDllPath());
  ASSERT_TRUE(dll.is_valid());

  // Wait until the application gets marked as problematic.
  incompatible_applications_observer->WaitForIncompatibleApplicationsChanged();

  // Verify the cache.
  EXPECT_TRUE(IncompatibleApplicationsUpdater::HasCachedApplications());
  auto incompatible_applications =
      IncompatibleApplicationsUpdater::GetCachedApplications();
  ASSERT_EQ(incompatible_applications.size(), 1u);
  const auto& incompatible_application = incompatible_applications[0];
  EXPECT_EQ(incompatible_application.info.name, kApplicationName);
  EXPECT_EQ(incompatible_application.blacklist_action->message_type(),
            chrome::conflicts::BlacklistMessageType::UNINSTALL);
}
