// 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 "chrome/browser/conflicts/third_party_conflicts_manager_win.h"

#include <utility>

#include "base/base_paths.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/optional.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/win/windows_version.h"
#include "chrome/browser/conflicts/module_info_win.h"
#include "chrome/browser/conflicts/proto/module_list.pb.h"
#include "chrome/common/chrome_features.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/testing_browser_process.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"

class ThirdPartyConflictsManagerTest : public testing::Test,
                                       public ModuleDatabaseEventSource {
 public:
  ThirdPartyConflictsManagerTest()
      : scoped_testing_local_state_(TestingBrowserProcess::GetGlobal()) {}

  void SetUp() override {
    ASSERT_TRUE(scoped_temp_dir_.CreateUniqueTempDir());

    scoped_feature_list_.InitWithFeatures(
        // Enabled features.
        {features::kIncompatibleApplicationsWarning,
         features::kThirdPartyModulesBlocking},
        // Disabled features.
        {});
  }

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

  // 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()));
  }

  void OnManagerInitializationComplete(
      base::Closure quit_closure,
      ThirdPartyConflictsManager::State final_state) {
    final_state_ = final_state;
    std::move(quit_closure).Run();
  }

  const base::Optional<ThirdPartyConflictsManager::State>& final_state() {
    return final_state_;
  }

  // ModuleDatabaseEventSource:
  void AddObserver(ModuleDatabaseObserver* observer) override {}
  void RemoveObserver(ModuleDatabaseObserver* observer) override {}

 private:
  content::TestBrowserThreadBundle test_browser_thread_bundle_;
  ScopedTestingLocalState scoped_testing_local_state_;

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

  base::test::ScopedFeatureList scoped_feature_list_;

  base::Optional<ThirdPartyConflictsManager::State> final_state_;

  DISALLOW_COPY_AND_ASSIGN(ThirdPartyConflictsManagerTest);
};

std::pair<ModuleInfoKey, ModuleInfoData> CreateExeModuleInfo() {
  base::FilePath exe_path;
  base::PathService::Get(base::FILE_EXE, &exe_path);

  std::pair<ModuleInfoKey, ModuleInfoData> module_info(
      std::piecewise_construct,
      std::forward_as_tuple(std::move(exe_path), 0, 0),
      std::forward_as_tuple());

  module_info.second.inspection_result =
      base::make_optional<ModuleInspectionResult>();

  return module_info;
}

TEST_F(ThirdPartyConflictsManagerTest, InitializeUpdaters) {
  ThirdPartyConflictsManager third_party_conflicts_manager(this);

  // The ThirdPartyConflictsManager class looks for the certificate info of the
  // current exe via the ModuleDatabaseObserver interface.
  auto exe_module_info = CreateExeModuleInfo();
  third_party_conflicts_manager.OnNewModuleFound(exe_module_info.first,
                                                 exe_module_info.second);

  third_party_conflicts_manager.OnModuleDatabaseIdle();
  ASSERT_NO_FATAL_FAILURE(CreateModuleList());
  third_party_conflicts_manager.LoadModuleList(GetModuleListPath());

  base::RunLoop run_loop;
  third_party_conflicts_manager.ForceInitialization(base::BindRepeating(
      &ThirdPartyConflictsManagerTest::OnManagerInitializationComplete,
      base::Unretained(this), run_loop.QuitClosure()));

  run_loop.Run();

  ASSERT_TRUE(final_state().has_value());

  const auto kExpectedFinalState =
      base::win::GetVersion() >= base::win::VERSION_WIN10
          ? ThirdPartyConflictsManager::State::kWarningAndBlockingInitialized
          : ThirdPartyConflictsManager::State::kBlockingInitialized;
  EXPECT_EQ(final_state().value(), kExpectedFinalState);
}

TEST_F(ThirdPartyConflictsManagerTest, InvalidModuleList) {
  ThirdPartyConflictsManager third_party_conflicts_manager(this);

  third_party_conflicts_manager.OnModuleDatabaseIdle();

  // Pass in an empty path which will ensure that the deserialization will fail.
  third_party_conflicts_manager.LoadModuleList(GetModuleListPath());

  base::RunLoop run_loop;
  third_party_conflicts_manager.ForceInitialization(base::BindRepeating(
      &ThirdPartyConflictsManagerTest::OnManagerInitializationComplete,
      base::Unretained(this), run_loop.QuitClosure()));

  run_loop.Run();

  ASSERT_TRUE(final_state().has_value());
  EXPECT_EQ(final_state().value(),
            ThirdPartyConflictsManager::State::kModuleListInvalidFailure);
}

TEST_F(ThirdPartyConflictsManagerTest, DestroyManager) {
  auto third_party_conflicts_manager =
      std::make_unique<ThirdPartyConflictsManager>(this);

  third_party_conflicts_manager->OnModuleDatabaseIdle();
  ASSERT_NO_FATAL_FAILURE(CreateModuleList());
  third_party_conflicts_manager->LoadModuleList(GetModuleListPath());

  base::RunLoop run_loop;
  third_party_conflicts_manager->ForceInitialization(base::BindRepeating(
      &ThirdPartyConflictsManagerTest::OnManagerInitializationComplete,
      base::Unretained(this), run_loop.QuitClosure()));

  // Delete the instance while it is initializing.
  third_party_conflicts_manager = nullptr;
  run_loop.Run();

  ASSERT_TRUE(final_state().has_value());
  EXPECT_EQ(final_state().value(),
            ThirdPartyConflictsManager::State::kDestroyed);
}
