// 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/chromeos/crostini/crostini_share_path.h"
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/run_loop.h"
#include "base/test/scoped_feature_list.h"
#include "base/test/scoped_task_environment.h"
#include "chrome/browser/chromeos/crostini/crostini_manager.h"
#include "chrome/browser/chromeos/crostini/crostini_pref_names.h"
#include "chrome/browser/chromeos/crostini/crostini_util.h"
#include "chrome/browser/chromeos/file_manager/path_util.h"
#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
#include "chrome/test/base/testing_profile.h"
#include "chromeos/chromeos_features.h"
#include "chromeos/chromeos_switches.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/fake_cicerone_client.h"
#include "chromeos/dbus/fake_concierge_client.h"
#include "chromeos/dbus/fake_seneschal_client.h"
#include "chromeos/dbus/seneschal/seneschal_service.pb.h"
#include "components/drive/drive_pref_names.h"
#include "components/prefs/pref_service.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace crostini {

class CrostiniSharePathTest : public testing::Test {
 public:
  const bool PERSIST_YES = true;
  const bool PERSIST_NO = false;
  enum class Persist { NO, YES };
  enum class SeneschalClientCalled { NO, YES };
  enum class Success { NO, YES };

  void SharePathCallback(
      Persist expected_persist,
      SeneschalClientCalled expected_seneschal_client_called,
      const vm_tools::seneschal::SharePathRequest::StorageLocation*
          expected_seneschal_storage_location,
      std::string expected_seneschal_path,
      Success expected_success,
      std::string expected_failure_reason,
      base::OnceClosure closure,
      bool success,
      std::string failure_reason) {
    const base::ListValue* prefs =
        profile()->GetPrefs()->GetList(prefs::kCrostiniSharedPaths);
    if (expected_persist == Persist::YES) {
      EXPECT_EQ(prefs->GetSize(), 1U);
      std::string share_path;
      prefs->GetString(0, &share_path);
      EXPECT_EQ(share_path_.value(), share_path);
    } else {
      EXPECT_EQ(prefs->GetSize(), 0U);
    }
    EXPECT_EQ(fake_seneschal_client_->share_path_called(),
              expected_seneschal_client_called == SeneschalClientCalled::YES);
    if (expected_seneschal_client_called == SeneschalClientCalled::YES) {
      EXPECT_EQ(fake_seneschal_client_->last_request().storage_location(),
                *expected_seneschal_storage_location);
      EXPECT_EQ(fake_seneschal_client_->last_request().shared_path().path(),
                expected_seneschal_path);
    }
    EXPECT_EQ(success, expected_success == Success::YES);
    EXPECT_EQ(failure_reason, expected_failure_reason);
    std::move(closure).Run();
  }

  void SharePersistedPathsCallback(bool success, std::string failure_reason) {
    EXPECT_TRUE(success);
    EXPECT_EQ(
        profile()->GetPrefs()->GetList(prefs::kCrostiniSharedPaths)->GetSize(),
        2U);
    run_loop()->QuitClosure().Run();
  }

  void SharePathErrorVmNotRunningCallback(base::OnceClosure closure,
                                          bool success,
                                          std::string failure_reason) {
    EXPECT_FALSE(fake_seneschal_client_->share_path_called());
    EXPECT_EQ(success, false);
    EXPECT_EQ(failure_reason, "Cannot share, VM not running");
    std::move(closure).Run();
  }

  CrostiniSharePathTest()
      : scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::UI),
        test_browser_thread_bundle_(
            content::TestBrowserThreadBundle::REAL_IO_THREAD) {
    chromeos::DBusThreadManager::Initialize();
    fake_concierge_client_ = static_cast<chromeos::FakeConciergeClient*>(
        chromeos::DBusThreadManager::Get()->GetConciergeClient());
    fake_seneschal_client_ = static_cast<chromeos::FakeSeneschalClient*>(
        chromeos::DBusThreadManager::Get()->GetSeneschalClient());
  }

  ~CrostiniSharePathTest() override { chromeos::DBusThreadManager::Shutdown(); }

  void SetUp() override {
    run_loop_ = std::make_unique<base::RunLoop>();
    profile_ = std::make_unique<TestingProfile>();

    base::CommandLine::ForCurrentProcess()->AppendSwitch(
        chromeos::switches::kCrostiniFiles);

    // Setup for DriveFS.
    features_.InitAndEnableFeature(chromeos::features::kDriveFs);
    user_manager.AddUser(AccountId::FromUserEmailGaiaId(
        profile()->GetProfileUserName(), "12345"));
    profile()->GetPrefs()->SetString(drive::prefs::kDriveFsProfileSalt, "a");
    drivefs_ =
        base::FilePath("/media/fuse/drivefs-84675c855b63e12f384d45f033826980");

    // Setup Downloads and path to share.
    downloads_ = file_manager::util::GetDownloadsFolderForProfile(profile());
    share_path_ = downloads_.Append("path");

    ASSERT_TRUE(base::CreateDirectory(share_path_));

    // Create 'vm-running' VM instance which is running.
    vm_tools::concierge::VmInfo vm_info;
    CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting(
        "vm-running", vm_info);
  }

  void TearDown() override {
    run_loop_.reset();
    profile_.reset();
  }

 protected:
  base::RunLoop* run_loop() { return run_loop_.get(); }
  Profile* profile() { return profile_.get(); }
  base::FilePath downloads_;
  base::FilePath share_path_;
  base::FilePath drivefs_;

  // Owned by chromeos::DBusThreadManager
  chromeos::FakeSeneschalClient* fake_seneschal_client_;
  chromeos::FakeConciergeClient* fake_concierge_client_;

  std::unique_ptr<base::RunLoop>
      run_loop_;  // run_loop_ must be created on the UI thread.
  std::unique_ptr<TestingProfile> profile_;
  base::test::ScopedFeatureList features_;
  chromeos::FakeChromeUserManager user_manager;

 private:
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  content::TestBrowserThreadBundle test_browser_thread_bundle_;
  DISALLOW_COPY_AND_ASSIGN(CrostiniSharePathTest);
};

TEST_F(CrostiniSharePathTest, SuccessDownloadsRoot) {
  SharePath(profile(), "vm-running", downloads_, PERSIST_NO,
            base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                           base::Unretained(this), Persist::NO,
                           SeneschalClientCalled::YES,
                           &vm_tools::seneschal::SharePathRequest::DOWNLOADS,
                           "", Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SuccessNoPersist) {
  SharePath(profile(), "vm-running", share_path_, PERSIST_NO,
            base::BindOnce(
                &CrostiniSharePathTest::SharePathCallback,
                base::Unretained(this), Persist::NO, SeneschalClientCalled::YES,
                &vm_tools::seneschal::SharePathRequest::DOWNLOADS, "path",
                Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SuccessPersist) {
  SharePath(
      profile(), "vm-running", share_path_, PERSIST_YES,
      base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                     base::Unretained(this), Persist::YES,
                     SeneschalClientCalled::YES,
                     &vm_tools::seneschal::SharePathRequest::DOWNLOADS, "path",
                     Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SuccessDriveFsMyDrive) {
  SharePath(profile(), "vm-running", drivefs_.Append("root").Append("my"),
            PERSIST_NO,
            base::BindOnce(
                &CrostiniSharePathTest::SharePathCallback,
                base::Unretained(this), Persist::NO, SeneschalClientCalled::YES,
                &vm_tools::seneschal::SharePathRequest::DRIVEFS_MY_DRIVE, "my",
                Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SuccessDriveFsMyDriveRoot) {
  SharePath(profile(), "vm-running", drivefs_.Append("root"), PERSIST_NO,
            base::BindOnce(
                &CrostiniSharePathTest::SharePathCallback,
                base::Unretained(this), Persist::NO, SeneschalClientCalled::YES,
                &vm_tools::seneschal::SharePathRequest::DRIVEFS_MY_DRIVE, "",
                Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, FailDriveFsRoot) {
  SharePath(profile(), "vm-running", drivefs_, PERSIST_NO,
            base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                           base::Unretained(this), Persist::NO,
                           SeneschalClientCalled::NO, nullptr, "", Success::NO,
                           "Path is not allowed", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SuccessDriveFsTeamDrives) {
  SharePath(profile(), "vm-running",
            drivefs_.Append("team_drives").Append("team"), PERSIST_NO,
            base::BindOnce(
                &CrostiniSharePathTest::SharePathCallback,
                base::Unretained(this), Persist::NO, SeneschalClientCalled::YES,
                &vm_tools::seneschal::SharePathRequest::DRIVEFS_TEAM_DRIVES,
                "team", Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SuccessDriveFsComputers) {
  SharePath(profile(), "vm-running", drivefs_.Append("Computers").Append("pc"),
            PERSIST_NO,
            base::BindOnce(
                &CrostiniSharePathTest::SharePathCallback,
                base::Unretained(this), Persist::NO, SeneschalClientCalled::YES,
                &vm_tools::seneschal::SharePathRequest::DRIVEFS_COMPUTERS, "pc",
                Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, FailDriveFsTrash) {
  SharePath(profile(), "vm-running",
            drivefs_.Append(".Trash").Append("in-the-trash"), PERSIST_NO,
            base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                           base::Unretained(this), Persist::NO,
                           SeneschalClientCalled::NO, nullptr, "", Success::NO,
                           "Path is not allowed", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SuccessRemovable) {
  SharePath(profile(), "vm-running", base::FilePath("/media/removable/MyUSB"),
            PERSIST_NO,
            base::BindOnce(
                &CrostiniSharePathTest::SharePathCallback,
                base::Unretained(this), Persist::NO, SeneschalClientCalled::YES,
                &vm_tools::seneschal::SharePathRequest::REMOVABLE, "MyUSB",
                Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, FailRemovableRoot) {
  SharePath(profile(), "vm-running", base::FilePath("/media/removable"),
            PERSIST_NO,
            base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                           base::Unretained(this), Persist::NO,
                           SeneschalClientCalled::NO, nullptr, "", Success::NO,
                           "Path is not allowed", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SharePathErrorSeneschal) {
  vm_tools::concierge::StartVmResponse start_vm_response;
  start_vm_response.set_status(vm_tools::concierge::VM_STATUS_RUNNING);
  start_vm_response.mutable_vm_info()->set_seneschal_server_handle(123);
  fake_concierge_client_->set_start_vm_response(start_vm_response);

  vm_tools::seneschal::SharePathResponse share_path_response;
  share_path_response.set_success(false);
  share_path_response.set_failure_reason("test failure");
  fake_seneschal_client_->set_share_path_response(share_path_response);

  SharePath(
      profile(), "error-seneschal", share_path_, PERSIST_YES,
      base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                     base::Unretained(this), Persist::YES,
                     SeneschalClientCalled::YES,
                     &vm_tools::seneschal::SharePathRequest::DOWNLOADS, "path",
                     Success::NO, "test failure", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SharePathErrorPathNotAbsolute) {
  const base::FilePath path("not/absolute/dir");
  SharePath(profile(), "vm-running", path, PERSIST_YES,
            base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                           base::Unretained(this), Persist::NO,
                           SeneschalClientCalled::NO, nullptr, "", Success::NO,
                           "Path must be absolute", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SharePathErrorReferencesParent) {
  const base::FilePath path("/path/../references/parent");
  SharePath(profile(), "vm-running", path, PERSIST_NO,
            base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                           base::Unretained(this), Persist::NO,
                           SeneschalClientCalled::NO, nullptr, "", Success::NO,
                           "Path must be absolute", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SharePathErrorNotUnderDownloads) {
  const base::FilePath path("/not/under/downloads");
  SharePath(profile(), "vm-running", path, PERSIST_YES,
            base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                           base::Unretained(this), Persist::NO,
                           SeneschalClientCalled::NO, nullptr, "", Success::NO,
                           "Path is not allowed", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SharePathVmToBeRestarted) {
  SharePath(
      profile(), "vm-to-be-started", share_path_, PERSIST_YES,
      base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                     base::Unretained(this), Persist::YES,
                     SeneschalClientCalled::YES,
                     &vm_tools::seneschal::SharePathRequest::DOWNLOADS, "path",
                     Success::YES, "", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SharePathErrorVmCouldNotBeStarted) {
  vm_tools::concierge::StartVmResponse start_vm_response;
  start_vm_response.set_status(vm_tools::concierge::VM_STATUS_FAILURE);
  fake_concierge_client_->set_start_vm_response(start_vm_response);

  SharePath(
      profile(), "error-vm-could-not-be-started", share_path_, PERSIST_YES,
      base::BindOnce(&CrostiniSharePathTest::SharePathCallback,
                     base::Unretained(this), Persist::YES,
                     SeneschalClientCalled::NO, nullptr, "", Success::NO,
                     "VM could not be started", run_loop()->QuitClosure()));
  run_loop()->Run();
}

TEST_F(CrostiniSharePathTest, SharePersistedPaths) {
  base::FilePath share_path2_ = downloads_.AppendASCII("path");
  ASSERT_TRUE(base::CreateDirectory(share_path2_));
  vm_tools::concierge::VmInfo vm_info;
  CrostiniManager::GetForProfile(profile())->AddRunningVmForTesting(
      kCrostiniDefaultVmName, vm_info);
  base::ListValue shared_paths = base::ListValue();
  shared_paths.GetList().push_back(base::Value(share_path_.value()));
  shared_paths.GetList().push_back(base::Value(share_path2_.value()));
  profile()->GetPrefs()->Set(prefs::kCrostiniSharedPaths, shared_paths);
  SharePersistedPaths(
      profile(),
      base::BindOnce(&CrostiniSharePathTest::SharePersistedPathsCallback,
                     base::Unretained(this)));
  run_loop()->Run();
}

}  // namespace crostini
