// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ash/crosapi/browser_loader.h"

#include "base/auto_reset.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/strings/utf_string_conversions.h"
#include "base/test/bind.h"
#include "base/test/scoped_command_line.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/test_future.h"
#include "chrome/browser/ash/crosapi/browser_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/component_updater/fake_cros_component_manager.h"
#include "chrome/test/base/browser_process_platform_part_test_api_chromeos.h"
#include "chromeos/ash/components/dbus/upstart/fake_upstart_client.h"
#include "components/component_updater/mock_component_updater_service.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/update_client/update_client.h"
#include "content/public/test/browser_task_environment.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::Return;

namespace crosapi {
namespace {

// Copied from browser_loader.cc
constexpr char kLacrosComponentName[] = "lacros-dogfood-dev";
constexpr char kLacrosComponentId[] = "ldobopbhiamakmncndpkeelenhdmgfhk";
constexpr char kLacrosMounterUpstartJob[] = "lacros_2dmounter";
constexpr char kLacrosUnmounterUpstartJob[] = "lacros_2dunmounter";

// This implementation of RAII for LacrosSelection is to make it easy reset
// the state between runs.
class ScopedLacrosSelectionCache {
 public:
  explicit ScopedLacrosSelectionCache(
      browser_util::LacrosSelectionPolicy lacros_selection) {
    SetLacrosSelection(lacros_selection);
  }
  ScopedLacrosSelectionCache(const ScopedLacrosSelectionCache&) = delete;
  ScopedLacrosSelectionCache& operator=(const ScopedLacrosSelectionCache&) =
      delete;
  ~ScopedLacrosSelectionCache() {
    browser_util::ClearLacrosSelectionCacheForTest();
  }

 private:
  void SetLacrosSelection(
      browser_util::LacrosSelectionPolicy lacros_selection) {
    policy::PolicyMap policy;
    policy.Set(policy::key::kLacrosSelection, policy::POLICY_LEVEL_MANDATORY,
               policy::POLICY_SCOPE_USER, policy::POLICY_SOURCE_CLOUD,
               base::Value(GetLacrosSelectionPolicyName(lacros_selection)),
               /*external_data_fetcher=*/nullptr);
    browser_util::CacheLacrosSelection(policy);
  }
};

}  // namespace

class BrowserLoaderTest : public testing::Test {
 public:
  BrowserLoaderTest() {
    // Create dependencies for object under test.
    component_manager_ =
        base::MakeRefCounted<component_updater::FakeCrOSComponentManager>();
    component_manager_->set_supported_components({kLacrosComponentName});
    component_manager_->ResetComponentState(
        kLacrosComponentName,
        component_updater::FakeCrOSComponentManager::ComponentInfo(
            component_updater::CrOSComponentManager::Error::NONE,
            base::FilePath("/install/path"), base::FilePath("/mount/path")));
    browser_part_ = std::make_unique<BrowserProcessPlatformPartTestApi>(
        g_browser_process->platform_part());
    browser_part_->InitializeCrosComponentManager(component_manager_);

    browser_loader_ = std::make_unique<BrowserLoader>(
        component_manager_, &mock_component_update_service_,
        &fake_upstart_client_);
  }

  ~BrowserLoaderTest() override {
    browser_part_->ShutdownCrosComponentManager();
  }

  // Public because this is test code.
  content::BrowserTaskEnvironment task_environment_;

 protected:
  component_updater::MockComponentUpdateService mock_component_update_service_;
  scoped_refptr<component_updater::FakeCrOSComponentManager> component_manager_;
  ash::FakeUpstartClient fake_upstart_client_;
  std::unique_ptr<BrowserProcessPlatformPartTestApi> browser_part_;
  std::unique_ptr<BrowserLoader> browser_loader_;

 private:
  base::AutoReset<bool> set_lacros_enabled_ =
      browser_util::SetLacrosEnabledForTest(true);
};

TEST_F(BrowserLoaderTest, OnLoadSelectionQuicklyChooseRootfs) {
  bool callback_called = false;
  fake_upstart_client_.set_start_job_cb(base::BindRepeating(
      [](bool* b, const std::string& job,
         const std::vector<std::string>& upstart_env) {
        EXPECT_EQ(job, kLacrosMounterUpstartJob);
        *b = true;
        return true;
      },
      &callback_called));
  // Set `was_installed` to false, in order to quickly mount rootfs
  // lacros-chrome.
  browser_loader_->OnLoadSelection(
      base::BindOnce([](const base::FilePath&, LacrosSelection selection,
                        base::Version version) {
        EXPECT_EQ(LacrosSelection::kRootfs, selection);
      }),
      false);
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(callback_called);
}

TEST_F(BrowserLoaderTest, OnLoadVersionSelectionNeitherIsAvailable) {
  // Use stateful when a rootfs lacros-chrome version is invalid.
  bool callback_called = false;
  fake_upstart_client_.set_start_job_cb(base::BindRepeating(
      [](bool* b, const std::string& job,
         const std::vector<std::string>& upstart_env) {
        EXPECT_EQ(job, kLacrosUnmounterUpstartJob);
        *b = true;
        return true;
      },
      &callback_called));
  // Pass in an invalid `base::Version`.
  browser_loader_->OnLoadVersionSelection(
      /*is_stateful_lacros_available=*/false,
      base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
                        base::Version version) { EXPECT_TRUE(path.empty()); }),
      /*rootfs_lacros_version=*/base::Version());
  task_environment_.RunUntilIdle();
  EXPECT_FALSE(callback_called);
}

TEST_F(BrowserLoaderTest, OnLoadVersionSelectionStatefulIsUnavailable) {
  // Use rootfs when a stateful lacros-chrome version is invalid.
  bool callback_called = false;
  fake_upstart_client_.set_start_job_cb(base::BindRepeating(
      [](bool* b, const std::string& job,
         const std::vector<std::string>& upstart_env) {
        EXPECT_EQ(job, kLacrosMounterUpstartJob);
        *b = true;
        return true;
      },
      &callback_called));
  // Pass in an invalid `base::Version`.
  browser_loader_->OnLoadVersionSelection(
      /*is_stateful_lacros_available=*/false,
      base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
                        base::Version version) {
        EXPECT_EQ(LacrosSelection::kRootfs, selection);
      }),
      /*rootfs_lacros_version=*/base::Version("2.0.0"));
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(callback_called);
}

TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsUnavailable) {
  std::u16string lacros_component_name =
      base::UTF8ToUTF16(base::StringPiece(kLacrosComponentName));
  EXPECT_CALL(mock_component_update_service_, GetComponents())
      .WillOnce(Return(std::vector<component_updater::ComponentInfo>{
          {kLacrosComponentId, "", lacros_component_name,
           base::Version("1.0.0"), ""}}));

  // Use stateful when a rootfs lacros-chrome version is invalid.
  bool callback_called = false;
  fake_upstart_client_.set_start_job_cb(base::BindRepeating(
      [](bool* b, const std::string& job,
         const std::vector<std::string>& upstart_env) {
        EXPECT_EQ(job, kLacrosUnmounterUpstartJob);
        *b = true;
        return true;
      },
      &callback_called));
  // Pass in an invalid `base::Version`.
  browser_loader_->OnLoadVersionSelection(
      /*is_stateful_lacros_available=*/true,
      base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
                        base::Version version) {
        EXPECT_EQ(LacrosSelection::kStateful, selection);
      }),
      /*rootfs_lacros_version=*/base::Version());
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(callback_called);
}

TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsNewer) {
  std::u16string lacros_component_name =
      base::UTF8ToUTF16(base::StringPiece(kLacrosComponentName));
  EXPECT_CALL(mock_component_update_service_, GetComponents())
      .WillOnce(Return(std::vector<component_updater::ComponentInfo>{
          {kLacrosComponentId, "", lacros_component_name,
           base::Version("1.0.0"), ""}}));

  bool callback_called = false;
  fake_upstart_client_.set_start_job_cb(base::BindRepeating(
      [](bool* b, const std::string& job,
         const std::vector<std::string>& upstart_env) {
        EXPECT_EQ(job, kLacrosMounterUpstartJob);
        *b = true;
        return true;
      },
      &callback_called));
  // Pass in a rootfs lacros-chrome version that is newer.
  browser_loader_->OnLoadVersionSelection(
      /*is_stateful_lacros_available=*/true,
      base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
                        base::Version version) {
        EXPECT_EQ(LacrosSelection::kRootfs, selection);
      }),
      /*rootfs_lacros_version=*/base::Version("2.0.0"));
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(callback_called);
}

TEST_F(BrowserLoaderTest, OnLoadVersionSelectionRootfsIsOlder) {
  // Use stateful when a rootfs lacros-chrome version is older.
  std::u16string lacros_component_name =
      base::UTF8ToUTF16(base::StringPiece(kLacrosComponentName));
  EXPECT_CALL(mock_component_update_service_, GetComponents())
      .WillOnce(Return(std::vector<component_updater::ComponentInfo>{
          {kLacrosComponentId, "", lacros_component_name,
           base::Version("3.0.0"), ""}}));

  bool callback_called = false;
  fake_upstart_client_.set_start_job_cb(base::BindRepeating(
      [](bool* b, const std::string& job,
         const std::vector<std::string>& upstart_env) {
        EXPECT_EQ(job, kLacrosUnmounterUpstartJob);
        *b = true;
        return true;
      },
      &callback_called));
  // Pass in a rootfs lacros-chrome version that is older.
  browser_loader_->OnLoadVersionSelection(
      /*is_stateful_lacros_available=*/true,
      base::BindOnce([](const base::FilePath& path, LacrosSelection selection,
                        base::Version version) {
        EXPECT_EQ(LacrosSelection::kStateful, selection);
      }),
      /*rootfs_lacros_version=*/base::Version("2.0.0"));
  task_environment_.RunUntilIdle();
  EXPECT_TRUE(callback_called);
}

TEST_F(BrowserLoaderTest, OnLoadSelectionPolicyIsRootfs) {
  ScopedLacrosSelectionCache cache(
      browser_util::LacrosSelectionPolicy::kRootfs);
  base::test::ScopedCommandLine command_line;
  command_line.GetProcessCommandLine()->AppendSwitchASCII(
      browser_util::kLacrosSelectionSwitch,
      browser_util::kLacrosSelectionStateful);

  base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> future;
  browser_loader_->Load(future.GetCallback<const base::FilePath&,
                                           LacrosSelection, base::Version>());

  const LacrosSelection selection = future.Get<1>();
  EXPECT_EQ(selection, LacrosSelection::kRootfs);
}

TEST_F(BrowserLoaderTest, OnLoadSelectionPolicyIsStateful) {
  ScopedLacrosSelectionCache cache(
      browser_util::LacrosSelectionPolicy::kStateful);
  base::test::ScopedCommandLine command_line;
  command_line.GetProcessCommandLine()->AppendSwitchASCII(
      browser_util::kLacrosSelectionSwitch,
      browser_util::kLacrosSelectionRootfs);

  base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> future;
  browser_loader_->Load(future.GetCallback<const base::FilePath&,
                                           LacrosSelection, base::Version>());

  const LacrosSelection selection = future.Get<1>();
  EXPECT_EQ(selection, LacrosSelection::kStateful);
}

TEST_F(BrowserLoaderTest,
       OnLoadSelectionPolicyIsUserChoiceAndCommandLineIsRootfs) {
  ScopedLacrosSelectionCache cache(
      browser_util::LacrosSelectionPolicy::kUserChoice);
  base::test::ScopedCommandLine command_line;
  command_line.GetProcessCommandLine()->AppendSwitchASCII(
      browser_util::kLacrosSelectionSwitch,
      browser_util::kLacrosSelectionRootfs);

  base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> future;
  browser_loader_->Load(future.GetCallback<const base::FilePath&,
                                           LacrosSelection, base::Version>());

  const LacrosSelection selection = future.Get<1>();
  EXPECT_EQ(selection, LacrosSelection::kRootfs);
}

TEST_F(BrowserLoaderTest,
       OnLoadSelectionPolicyIsUserChoiceAndCommandLineIsStateful) {
  ScopedLacrosSelectionCache cache(
      browser_util::LacrosSelectionPolicy::kUserChoice);
  base::test::ScopedCommandLine command_line;
  command_line.GetProcessCommandLine()->AppendSwitchASCII(
      browser_util::kLacrosSelectionSwitch,
      browser_util::kLacrosSelectionStateful);

  base::test::TestFuture<base::FilePath, LacrosSelection, base::Version> future;
  browser_loader_->Load(future.GetCallback<const base::FilePath&,
                                           LacrosSelection, base::Version>());

  const LacrosSelection selection = future.Get<1>();
  EXPECT_EQ(selection, LacrosSelection::kStateful);
}

}  // namespace crosapi
