// 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 "components/drive/chromeos/file_system.h"

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <string>
#include <vector>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/test/test_mock_time_task_runner.h"
#include "components/drive/chromeos/drive_change_list_loader.h"
#include "components/drive/chromeos/drive_test_util.h"
#include "components/drive/chromeos/fake_free_disk_space_getter.h"
#include "components/drive/chromeos/file_system_observer.h"
#include "components/drive/chromeos/sync_client.h"
#include "components/drive/drive.pb.h"
#include "components/drive/drive_api_util.h"
#include "components/drive/event_logger.h"
#include "components/drive/file_change.h"
#include "components/drive/file_system_core_util.h"
#include "components/drive/job_scheduler.h"
#include "components/drive/service/fake_drive_service.h"
#include "components/drive/service/test_util.h"
#include "components/prefs/testing_pref_service.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "google_apis/drive/drive_api_parser.h"
#include "google_apis/drive/test_util.h"
#include "services/network/test/test_network_connection_tracker.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace drive {
namespace {

// Counts the number of invocation, and if it increased up to |expected_counter|
// quits the current message loop by calling |quit|.
void AsyncInitializationCallback(int* counter,
                                 int expected_counter,
                                 const base::Closure& quit,
                                 FileError error,
                                 std::unique_ptr<ResourceEntry> entry) {
  if (error != FILE_ERROR_OK || !entry) {
    // If we hit an error case, quit the message loop immediately.
    // Then the expectation in the test case can find it because the actual
    // value of |counter| is different from the expected one.
    quit.Run();
    return;
  }

  (*counter)++;
  if (*counter >= expected_counter)
    quit.Run();
}

bool CompareHashAndFilePath(const HashAndFilePath& a,
                            const HashAndFilePath& b) {
  const int result = a.hash.compare(b.hash);
  if (result < 0)
    return true;
  if (result > 0)
    return false;
  return a.path.AsUTF8Unsafe().compare(b.path.AsUTF8Unsafe()) < 0;
}

// This class is used to record directory changes and examine them later.
class MockDirectoryChangeObserver : public FileSystemObserver {
 public:
  MockDirectoryChangeObserver() = default;
  ~MockDirectoryChangeObserver() override = default;

  // FileSystemObserver overrides.
  void OnDirectoryChanged(const base::FilePath& directory_path) override {
    changed_directories_.push_back(directory_path);
  }

  void OnFileChanged(const FileChange& new_file_change) override {
    changed_files_.Apply(new_file_change);
  }

  void OnTeamDrivesUpdated(
      const std::set<std::string>& added_team_drive_ids,
      const std::set<std::string>& removed_team_drive_ids) override {
    added_team_drive_ids_ = added_team_drive_ids;
    removed_team_drive_ids_ = removed_team_drive_ids;
  }

  const std::vector<base::FilePath>& changed_directories() const {
    return changed_directories_;
  }

  const FileChange& changed_files() const { return changed_files_; }

  const std::set<std::string>& added_team_drive_ids() const {
    return added_team_drive_ids_;
  }

  const std::set<std::string>& removed_team_drive_ids() const {
    return removed_team_drive_ids_;
  }

 private:
  std::vector<base::FilePath> changed_directories_;
  FileChange changed_files_;
  std::set<std::string> added_team_drive_ids_;
  std::set<std::string> removed_team_drive_ids_;

  DISALLOW_COPY_AND_ASSIGN(MockDirectoryChangeObserver);
};

struct DestroyHelper {
  // FileSystemTest needs to be default constructible, so we provide a default
  // constructor here.
  DestroyHelper() = default;

  explicit DestroyHelper(
      scoped_refptr<base::TestMockTimeTaskRunner> task_runner)
      : task_runner_(task_runner) {}

  template <typename T>
  void operator()(T* object) const {
    DCHECK(task_runner_);
    if (object) {
      object->Destroy();
      task_runner_->RunUntilIdle();
    }
  }

  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
};

}  // namespace

class FileSystemTest : public testing::Test {
 protected:
  void SetUp() override {
    task_runner_ = base::MakeRefCounted<base::TestMockTimeTaskRunner>(
        base::TestMockTimeTaskRunner::Type::kBoundToThread);

    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    pref_service_ = std::make_unique<TestingPrefServiceSimple>();
    test_util::RegisterDrivePrefs(pref_service_->registry());

    logger_ = std::make_unique<EventLogger>();
    fake_drive_service_ = std::make_unique<FakeDriveService>();
    test_util::SetUpTestEntries(fake_drive_service_.get());

    fake_free_disk_space_getter_ = std::make_unique<FakeFreeDiskSpaceGetter>();

    network::TestNetworkConnectionTracker::GetInstance()->SetConnectionType(
        network::mojom::ConnectionType::CONNECTION_WIFI);
    scheduler_ = std::make_unique<JobScheduler>(
        pref_service_.get(), logger_.get(), fake_drive_service_.get(),
        network::TestNetworkConnectionTracker::GetInstance(),
        task_runner_.get(), nullptr);

    mock_directory_observer_ = std::make_unique<MockDirectoryChangeObserver>();

    SetUpResourceMetadataAndFileSystem();
  }

  void SetUpResourceMetadataAndFileSystem() {
    const base::FilePath metadata_dir = temp_dir_.GetPath().AppendASCII("meta");
    ASSERT_TRUE(base::CreateDirectory(metadata_dir));
    metadata_storage_ =
        std::unique_ptr<internal::ResourceMetadataStorage, DestroyHelper>(
            new internal::ResourceMetadataStorage(metadata_dir,
                                                  task_runner_.get()),
            DestroyHelper(task_runner_.get()));
    ASSERT_TRUE(metadata_storage_->Initialize());

    const base::FilePath cache_dir = temp_dir_.GetPath().AppendASCII("files");
    ASSERT_TRUE(base::CreateDirectory(cache_dir));
    cache_ = std::unique_ptr<internal::FileCache, DestroyHelper>(
        new internal::FileCache(metadata_storage_.get(), cache_dir,
                                task_runner_.get(),
                                fake_free_disk_space_getter_.get()),
        DestroyHelper(task_runner_.get()));
    ASSERT_TRUE(cache_->Initialize());

    resource_metadata_ =
        std::unique_ptr<internal::ResourceMetadata, DestroyHelper>(
            new internal::ResourceMetadata(metadata_storage_.get(),
                                           cache_.get(), task_runner_.get()),
            DestroyHelper(task_runner_.get()));
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata_->Initialize());

    const base::FilePath temp_file_dir = temp_dir_.GetPath().AppendASCII("tmp");
    ASSERT_TRUE(base::CreateDirectory(temp_file_dir));
    file_system_ = std::make_unique<FileSystem>(
        logger_.get(), cache_.get(), scheduler_.get(), resource_metadata_.get(),
        task_runner_.get(), temp_file_dir, task_runner_->GetMockClock());
    file_system_->AddObserver(mock_directory_observer_.get());

    // Disable delaying so that the sync starts immediately.
    file_system_->sync_client_for_testing()->set_delay_for_testing(
        base::TimeDelta::FromSeconds(0));

    file_system_->team_drive_operation_queue_for_testing()
        ->DisableQueueForTesting();
  }

  // Loads the full resource list via FakeDriveService.
  bool LoadFullResourceList() {
    FileError error = FILE_ERROR_FAILED;
    file_system_->change_list_loader_for_testing()->LoadIfNeeded(
        google_apis::test_util::CreateCopyResultCallback(&error));
    task_runner_->RunUntilIdle();
    return error == FILE_ERROR_OK;
  }

  // Gets resource entry by path synchronously.
  std::unique_ptr<ResourceEntry> GetResourceEntrySync(
      const base::FilePath& file_path) {
    FileError error = FILE_ERROR_FAILED;
    std::unique_ptr<ResourceEntry> entry;
    file_system_->GetResourceEntry(
        file_path,
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    task_runner_->RunUntilIdle();

    return entry;
  }

  // Gets directory info by path synchronously.
  std::unique_ptr<ResourceEntryVector> ReadDirectorySync(
      const base::FilePath& file_path) {
    FileError error = FILE_ERROR_FAILED;
    std::unique_ptr<ResourceEntryVector> entries(new ResourceEntryVector);
    file_system_->ReadDirectory(
        file_path,
        base::Bind(&AccumulateReadDirectoryResult, entries.get()),
        google_apis::test_util::CreateCopyResultCallback(&error));
    task_runner_->RunUntilIdle();
    if (error != FILE_ERROR_OK)
      entries.reset();
    return entries;
  }

  // Used to implement ReadDirectorySync().
  static void AccumulateReadDirectoryResult(
      ResourceEntryVector* out_entries,
      std::unique_ptr<ResourceEntryVector> entries) {
    ASSERT_TRUE(entries);
    out_entries->insert(out_entries->end(), entries->begin(), entries->end());
  }

  // Returns true if an entry exists at |file_path|.
  bool EntryExists(const base::FilePath& file_path) {
    return GetResourceEntrySync(file_path) != nullptr;
  }

  // Flag for specifying the timestamp of the test filesystem cache.
  enum SetUpTestFileSystemParam {
    USE_OLD_TIMESTAMP,
    USE_SERVER_TIMESTAMP,
  };

  // Sets up a filesystem with directories: drive/root, drive/root/Dir1,
  // drive/root/Dir1/SubDir2 and files drive/root/File1, drive/root/Dir1/File2,
  // drive/root/Dir1/SubDir2/File3. If |use_up_to_date_timestamp| is true, sets
  // the start_page_token to that of FakeDriveService, indicating the cache is
  // holding the latest file system info.
  void SetUpTestFileSystem(SetUpTestFileSystemParam param) {
    // Destroy the existing resource metadata to close DB.
    resource_metadata_.reset();

    const base::FilePath metadata_dir = temp_dir_.GetPath().AppendASCII("meta");
    ASSERT_TRUE(base::CreateDirectory(metadata_dir));
    std::unique_ptr<internal::ResourceMetadataStorage, DestroyHelper>
        metadata_storage(new internal::ResourceMetadataStorage(
                             metadata_dir, task_runner_.get()),
                         DestroyHelper(task_runner_.get()));

    const base::FilePath cache_dir = temp_dir_.GetPath().AppendASCII("files");
    std::unique_ptr<internal::FileCache, DestroyHelper> cache(
        new internal::FileCache(metadata_storage.get(), cache_dir,
                                task_runner_.get(),
                                fake_free_disk_space_getter_.get()),
        DestroyHelper(task_runner_.get()));

    std::unique_ptr<internal::ResourceMetadata, DestroyHelper>
        resource_metadata(
            new internal::ResourceMetadata(metadata_storage_.get(), cache.get(),
                                           task_runner_.get()),
            DestroyHelper(task_runner_.get()));

    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->Initialize());

    const std::string start_page_token =
        param == USE_SERVER_TIMESTAMP
            ? fake_drive_service_->start_page_token().start_page_token()
            : "2";
    ASSERT_EQ(FILE_ERROR_OK,
              resource_metadata->SetStartPageToken(start_page_token));

    // drive/root
    ResourceEntry root;
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->GetResourceEntryByPath(
        util::GetDriveMyDriveRootPath(), &root));
    root.set_resource_id(fake_drive_service_->GetRootResourceId());
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->RefreshEntry(root));

    std::string local_id;

    // drive/root/File1
    ResourceEntry file1;
    file1.set_title("File1");
    file1.set_resource_id("resource_id:File1");
    file1.set_parent_local_id(root.local_id());
    file1.mutable_file_specific_info()->set_md5("md5#1");
    file1.mutable_file_info()->set_is_directory(false);
    file1.mutable_file_info()->set_size(1048576);
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(file1, &local_id));

    // drive/root/Dir1
    ResourceEntry dir1;
    dir1.set_title("Dir1");
    dir1.set_resource_id("resource_id:Dir1");
    dir1.set_parent_local_id(root.local_id());
    dir1.mutable_file_info()->set_is_directory(true);
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(dir1, &local_id));
    const std::string dir1_local_id = local_id;

    // drive/root/Dir1/File2
    ResourceEntry file2;
    file2.set_title("File2");
    file2.set_resource_id("resource_id:File2");
    file2.set_parent_local_id(dir1_local_id);
    file2.mutable_file_specific_info()->set_md5("md5#2");
    file2.mutable_file_info()->set_is_directory(false);
    file2.mutable_file_info()->set_size(555);
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(file2, &local_id));

    // drive/root/Dir1/SubDir2
    ResourceEntry dir2;
    dir2.set_title("SubDir2");
    dir2.set_resource_id("resource_id:SubDir2");
    dir2.set_parent_local_id(dir1_local_id);
    dir2.mutable_file_info()->set_is_directory(true);
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(dir2, &local_id));
    const std::string dir2_local_id = local_id;

    // drive/root/Dir1/SubDir2/File3
    ResourceEntry file3;
    file3.set_title("File3");
    file3.set_resource_id("resource_id:File3");
    file3.set_parent_local_id(dir2_local_id);
    file3.mutable_file_specific_info()->set_md5("md5#2");
    file3.mutable_file_info()->set_is_directory(false);
    file3.mutable_file_info()->set_size(12345);
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(file3, &local_id));

    // drive/team_drive
    ResourceEntry team_drive_root;
    ASSERT_EQ(FILE_ERROR_OK,
              resource_metadata->GetResourceEntryByPath(
                  util::GetDriveTeamDrivesRootPath(), &team_drive_root));

    // drive/team_drive/team_drive_1
    ResourceEntry td_dir;
    td_dir.set_title("team_drive_1");
    td_dir.set_resource_id("td_id_1");
    td_dir.set_parent_local_id(team_drive_root.local_id());
    td_dir.mutable_file_info()->set_is_directory(true);
    ASSERT_EQ(FILE_ERROR_OK, resource_metadata->AddEntry(td_dir, &local_id));

    // Recreate resource metadata.
    SetUpResourceMetadataAndFileSystem();
  }

  // Sets up two team drives, team_drive_a and team_drive_b and creates the
  // following:
  // - Directories:
  // -- team_drive_a/dir1
  // -- team_drive_a/dir1/nested_1
  // -- team_drive_b/dir2
  //
  // - Files:
  // -- team_drive_a/dir1/file1
  // -- team_drive_a/dir1/nested_1/file1
  // -- team_drive_b/dir2/file2
  bool SetupTeamDrives() {
    fake_drive_service_->AddTeamDrive("td_id_1", "team_drive_1", "");
    fake_drive_service_->AddTeamDrive("td_id_2", "team_drive_2", "");
    fake_drive_service_->AddTeamDrive("td_id_2_2", "team_drive_2", "");

    google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
    std::unique_ptr<google_apis::FileResource> entry;

    fake_drive_service_->AddNewFileWithResourceId(
        "td_1_dir_1_resource_id", util::kDriveFolderMimeType, std::string(),
        "td_id_1", "dir1",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    if (error != google_apis::HTTP_CREATED)
      return false;

    fake_drive_service_->AddNewFileWithResourceId(
        "td_1_dir_nested_1_resource_id", util::kDriveFolderMimeType,
        std::string(), "td_1_dir_1_resource_id", "nested_1",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    if (error != google_apis::HTTP_CREATED)
      return false;

    fake_drive_service_->AddNewFileWithResourceId(
        "td_2_dir_2_resource_id", util::kDriveFolderMimeType, std::string(),
        "td_id_2", "dir2",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    if (error != google_apis::HTTP_CREATED)
      return false;

    fake_drive_service_->AddNewFileWithResourceId(
        "dir1_file_1_resource_id", "audio/mpeg", "dir 1 file 1 content.",
        "td_1_dir_1_resource_id", "File 1.txt",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    if (error != google_apis::HTTP_CREATED)
      return false;

    fake_drive_service_->AddNewFileWithResourceId(
        "nested_1_file_1_resource_id", "audio/mpeg", "nested 1 file 1 content.",
        "td_1_dir_nested_1_resource_id", "Nested File 1.txt",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    if (error != google_apis::HTTP_CREATED)
      return false;

    fake_drive_service_->AddNewFileWithResourceId(
        "dir_2_file_1_resource_id", "audio/mpeg", "dir2 file1 content.",
        "td_2_dir_2_resource_id", "File 2.txt",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    if (error != google_apis::HTTP_CREATED)
      return false;

    fake_drive_service_->AddNewFileWithResourceId(
        "td_2_2_dir_1_resource_id", util::kDriveFolderMimeType, std::string(),
        "td_id_2_2", "dir1",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    if (error != google_apis::HTTP_CREATED)
      return false;

    return true;
  }

  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
  base::ScopedTempDir temp_dir_;
  // We don't use TestingProfile::GetPrefs() in favor of having less
  // dependencies to Profile in general.
  std::unique_ptr<TestingPrefServiceSimple> pref_service_;

  std::unique_ptr<EventLogger> logger_;
  std::unique_ptr<FakeDriveService> fake_drive_service_;
  std::unique_ptr<FakeFreeDiskSpaceGetter> fake_free_disk_space_getter_;
  std::unique_ptr<JobScheduler> scheduler_;
  std::unique_ptr<MockDirectoryChangeObserver> mock_directory_observer_;

  std::unique_ptr<internal::ResourceMetadataStorage, DestroyHelper>
      metadata_storage_;
  std::unique_ptr<internal::FileCache, DestroyHelper> cache_;
  std::unique_ptr<internal::ResourceMetadata, DestroyHelper> resource_metadata_;
  std::unique_ptr<FileSystem> file_system_;
};

TEST_F(FileSystemTest, SearchByHashes) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_SERVER_TIMESTAMP));

  std::set<std::string> hashes;
  FileError error;
  std::vector<HashAndFilePath> results;

  hashes.insert("md5#1");
  file_system_->SearchByHashes(
      hashes,
      google_apis::test_util::CreateCopyResultCallback(&error, &results));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  ASSERT_EQ(1u, results.size());
  EXPECT_EQ(FILE_PATH_LITERAL("drive/root/File1"), results[0].path.value());

  hashes.clear();
  hashes.insert("md5#2");
  file_system_->SearchByHashes(
      hashes,
      google_apis::test_util::CreateCopyResultCallback(&error, &results));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  ASSERT_EQ(2u, results.size());
  std::sort(results.begin(), results.end(), &CompareHashAndFilePath);
  EXPECT_EQ(FILE_PATH_LITERAL("drive/root/Dir1/File2"),
            results[0].path.value());
  EXPECT_EQ(FILE_PATH_LITERAL("drive/root/Dir1/SubDir2/File3"),
            results[1].path.value());

  hashes.clear();
  hashes.insert("md5#1");
  hashes.insert("md5#2");
  file_system_->SearchByHashes(
      hashes,
      google_apis::test_util::CreateCopyResultCallback(&error, &results));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  ASSERT_EQ(3u, results.size());
  std::sort(results.begin(), results.end(), &CompareHashAndFilePath);
  EXPECT_EQ(FILE_PATH_LITERAL("drive/root/File1"), results[0].path.value());
  EXPECT_EQ(FILE_PATH_LITERAL("drive/root/Dir1/File2"),
            results[1].path.value());
  EXPECT_EQ(FILE_PATH_LITERAL("drive/root/Dir1/SubDir2/File3"),
            results[2].path.value());
}

TEST_F(FileSystemTest, Copy) {
  base::FilePath src_file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_file_path(FILE_PATH_LITERAL("drive/root/Copied.txt"));
  EXPECT_TRUE(GetResourceEntrySync(src_file_path));
  EXPECT_FALSE(GetResourceEntrySync(dest_file_path));

  FileError error = FILE_ERROR_FAILED;
  file_system_->Copy(src_file_path,
                     dest_file_path,
                     false,  // preserve_last_modified,
                     google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Entry is added on the server.
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(dest_file_path);
  ASSERT_TRUE(entry);

  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_drive_service_->GetFileResource(
      entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_EQ(entry->title(), server_entry->title());
  EXPECT_FALSE(server_entry->IsDirectory());
}

TEST_F(FileSystemTest, Move) {
  base::FilePath src_file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  base::FilePath dest_file_path(
      FILE_PATH_LITERAL("drive/root/Directory 1/Moved.txt"));
  EXPECT_TRUE(GetResourceEntrySync(src_file_path));
  EXPECT_FALSE(GetResourceEntrySync(dest_file_path));
  std::unique_ptr<ResourceEntry> parent =
      GetResourceEntrySync(dest_file_path.DirName());
  ASSERT_TRUE(parent);

  FileError error = FILE_ERROR_FAILED;
  file_system_->Move(src_file_path,
                     dest_file_path,
                     google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Entry is moved on the server.
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(dest_file_path);
  ASSERT_TRUE(entry);

  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_drive_service_->GetFileResource(
      entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_EQ(entry->title(), server_entry->title());

  ASSERT_FALSE(server_entry->parents().empty());
  EXPECT_EQ(parent->resource_id(), server_entry->parents()[0].file_id());
}

TEST_F(FileSystemTest, Remove) {
  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
  ASSERT_TRUE(entry);

  FileError error = FILE_ERROR_FAILED;
  file_system_->Remove(
      file_path,
      false,  // is_resursive
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Entry is removed on the server.
  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_drive_service_->GetFileResource(
      entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_TRUE(server_entry->labels().is_trashed());
}

TEST_F(FileSystemTest, CreateDirectory) {
  base::FilePath directory_path(FILE_PATH_LITERAL("drive/root/New Directory"));
  EXPECT_FALSE(GetResourceEntrySync(directory_path));

  FileError error = FILE_ERROR_FAILED;
  file_system_->CreateDirectory(
      directory_path,
      true,  // is_exclusive
      false,  // is_recursive
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Directory is created on the server.
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(directory_path);
  ASSERT_TRUE(entry);

  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_drive_service_->GetFileResource(
      entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_EQ(entry->title(), server_entry->title());
  EXPECT_TRUE(server_entry->IsDirectory());
}

TEST_F(FileSystemTest, CreateFile) {
  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/New File.txt"));
  EXPECT_FALSE(GetResourceEntrySync(file_path));

  FileError error = FILE_ERROR_FAILED;
  file_system_->CreateFile(
      file_path,
      true,  // is_exclusive
      "text/plain",
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // File is created on the server.
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
  ASSERT_TRUE(entry);

  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_drive_service_->GetFileResource(
      entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_EQ(entry->title(), server_entry->title());
  EXPECT_FALSE(server_entry->IsDirectory());
}

TEST_F(FileSystemTest, TouchFile) {
  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
  ASSERT_TRUE(entry);

  base::Time last_accessed =
      base::Time::FromInternalValue(entry->file_info().last_accessed()) +
      base::TimeDelta::FromSeconds(1);
  base::Time last_modified =
      base::Time::FromInternalValue(entry->file_info().last_modified()) +
      base::TimeDelta::FromSeconds(1);

  FileError error = FILE_ERROR_FAILED;
  file_system_->TouchFile(
      file_path,
      last_accessed,
      last_modified,
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // File is touched on the server.
  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_drive_service_->GetFileResource(
      entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_EQ(last_accessed, server_entry->last_viewed_by_me_date());
  EXPECT_EQ(last_modified, server_entry->modified_date());
  EXPECT_EQ(last_modified, server_entry->modified_by_me_date());
}

TEST_F(FileSystemTest, TruncateFile) {
  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(file_path);
  ASSERT_TRUE(entry);

  const int64_t kLength = entry->file_info().size() + 100;

  FileError error = FILE_ERROR_FAILED;
  file_system_->TruncateFile(
      file_path,
      kLength,
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // File is touched on the server.
  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  fake_drive_service_->GetFileResource(
      entry->resource_id(),
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_EQ(kLength, server_entry->file_size());
}

TEST_F(FileSystemTest, DuplicatedAsyncInitialization) {
  base::RunLoop loop;

  int counter = 0;

  file_system_->GetResourceEntry(
      base::FilePath(FILE_PATH_LITERAL("drive/root")),
      base::BindOnce(&AsyncInitializationCallback, &counter, 2,
                     loop.QuitClosure()));
  file_system_->GetResourceEntry(
      base::FilePath(FILE_PATH_LITERAL("drive/root")),
      base::BindOnce(&AsyncInitializationCallback, &counter, 2,
                     loop.QuitClosure()));
  loop.Run();  // Wait to get our result
  EXPECT_EQ(2, counter);

  EXPECT_EQ(1, fake_drive_service_->file_list_load_count());
}

TEST_F(FileSystemTest, GetGrandRootEntry) {
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  EXPECT_EQ(util::kDriveGrandRootLocalId, entry->local_id());
}

TEST_F(FileSystemTest, GetOtherDirEntry) {
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/other"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  EXPECT_EQ(util::kDriveOtherDirLocalId, entry->local_id());
}

TEST_F(FileSystemTest, GetMyDriveRoot) {
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/root"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  EXPECT_EQ(fake_drive_service_->GetRootResourceId(), entry->resource_id());

  // After "fast fetch" is done, full resource list is fetched.
  EXPECT_EQ(1, fake_drive_service_->file_list_load_count());
}

TEST_F(FileSystemTest, GetTeamDriveRoot) {
  const base::FilePath kFilePath(FILE_PATH_LITERAL("drive/team_drives"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  EXPECT_EQ(util::kDriveTeamDrivesDirLocalId, entry->local_id());

  // After "fast fetch" is done, full resource list is fetched.
  EXPECT_EQ(1, fake_drive_service_->file_list_load_count());
}

TEST_F(FileSystemTest, GetExistingFile) {
  // Simulate the situation that full feed fetching takes very long time,
  // to test the recursive "fast fetch" feature is properly working.
  fake_drive_service_->set_never_return_all_file_list(true);

  const base::FilePath kFilePath(
      FILE_PATH_LITERAL("drive/root/Directory 1/SubDirectory File 1.txt"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  EXPECT_EQ("subdirectory_file_1_id", entry->resource_id());

  EXPECT_EQ(1, fake_drive_service_->about_resource_load_count());
  EXPECT_EQ(2, fake_drive_service_->directory_load_count());
  EXPECT_EQ(1, fake_drive_service_->blocked_file_list_load_count());
}

TEST_F(FileSystemTest, GetExistingDocument) {
  const base::FilePath kFilePath(
      FILE_PATH_LITERAL("drive/root/Document 1 excludeDir-test.gdoc"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  EXPECT_EQ("5_document_resource_id", entry->resource_id());
}

TEST_F(FileSystemTest, GetNonExistingFile) {
  const base::FilePath kFilePath(
      FILE_PATH_LITERAL("drive/root/nonexisting.file"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  EXPECT_FALSE(entry);
}

TEST_F(FileSystemTest, GetInSubSubdir) {
  const base::FilePath kFilePath(
      FILE_PATH_LITERAL("drive/root/Directory 1/Sub Directory Folder/"
                        "Sub Sub Directory Folder"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  ASSERT_EQ("sub_sub_directory_folder_id", entry->resource_id());
}

TEST_F(FileSystemTest, GetOrphanFile) {
  ASSERT_TRUE(LoadFullResourceList());

  // Entry without parents are placed under "drive/other".
  const base::FilePath kFilePath(
      FILE_PATH_LITERAL("drive/other/Orphan File 1.txt"));
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(kFilePath);
  ASSERT_TRUE(entry);
  EXPECT_EQ("1_orphanfile_resource_id", entry->resource_id());
}

TEST_F(FileSystemTest, ReadDirectory_Root) {
  // ReadDirectory() should kick off the resource list loading.
  std::unique_ptr<ResourceEntryVector> entries(
      ReadDirectorySync(base::FilePath::FromUTF8Unsafe("drive")));
  // The root directory should be read correctly.
  ASSERT_TRUE(entries);
  ASSERT_EQ(5U, entries->size());

  // The found three directories should be /drive/root, /drive/other,
  // /drive/trash and /drive/team_drives.
  std::set<base::FilePath> found;
  for (size_t i = 0; i < entries->size(); ++i)
    found.insert(base::FilePath::FromUTF8Unsafe((*entries)[i].title()));
  EXPECT_EQ(5U, found.size());
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe(
                    util::kDriveMyDriveRootDirName)));
  EXPECT_EQ(1U, found.count(
                    base::FilePath::FromUTF8Unsafe(util::kDriveOtherDirName)));
  EXPECT_EQ(1U, found.count(
                    base::FilePath::FromUTF8Unsafe(util::kDriveTrashDirName)));
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe(
                    util::kDriveTeamDrivesDirName)));
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe(
                    util::kDriveComputersDirName)));
}

TEST_F(FileSystemTest, ReadDirectory_TeamDrivesRoot) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_SERVER_TIMESTAMP));
  ASSERT_TRUE(SetupTeamDrives());

  // The first load trigger the loading of team drives.
  ReadDirectorySync(base::FilePath::FromUTF8Unsafe("."));

  // After the first load team drive data should be available for reading.
  std::unique_ptr<ResourceEntryVector> entries(
      ReadDirectorySync(base::FilePath::FromUTF8Unsafe("drive/team_drives")));
  // The root directory should be read correctly.
  ASSERT_TRUE(entries);
  ASSERT_EQ(3U, entries->size());

  std::multiset<base::FilePath> found;
  for (size_t i = 0; i < entries->size(); ++i) {
    found.insert(base::FilePath::FromUTF8Unsafe((*entries)[i].title()));
  }
  EXPECT_EQ(3U, found.size());
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe("team_drive_1")));
  EXPECT_EQ(2U, found.count(base::FilePath::FromUTF8Unsafe("team_drive_2")));
  EXPECT_EQ(1, fake_drive_service_->team_drive_list_load_count());
  EXPECT_EQ(3, fake_drive_service_->file_list_load_count());

  // We should be able to read from drive/team_drives/team_drive_1
  std::unique_ptr<ResourceEntryVector> team_drive_1_entries(ReadDirectorySync(
      base::FilePath::FromUTF8Unsafe("drive/team_drives/team_drive_1")));

  ASSERT_TRUE(team_drive_1_entries);
  ASSERT_EQ(1U, team_drive_1_entries->size());
  std::set<base::FilePath> team_drive_1_found;
  for (size_t i = 0; i < team_drive_1_entries->size(); ++i) {
    team_drive_1_found.insert(
        base::FilePath::FromUTF8Unsafe((*team_drive_1_entries)[i].title()));
  }
  EXPECT_EQ(1U, team_drive_1_found.size());
  EXPECT_EQ(1U,
            team_drive_1_found.count(base::FilePath::FromUTF8Unsafe("dir1")));
}

TEST_F(FileSystemTest, ReadDirectory_TeamDriveFolder) {
  ASSERT_TRUE(SetupTeamDrives());

  // The first load trigger the loading of team drives.
  ReadDirectorySync(base::FilePath::FromUTF8Unsafe("."));

  // Add a new entry to drive/team_drives/team_drive_1
  // Create a file in the test directory.
  std::unique_ptr<google_apis::FileResource> entry;
  {
    google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
    fake_drive_service_->AddNewFile(
        "text/plain", "(dummy data)", "td_id_1", "TestFile",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(google_apis::HTTP_CREATED, error);
  }

  // Notify the update to the file system.
  file_system_->CheckForUpdates();
  base::RunLoop().RunUntilIdle();

  std::unique_ptr<ResourceEntryVector> entries(ReadDirectorySync(
      base::FilePath::FromUTF8Unsafe("drive/team_drives/team_drive_1")));
  // The root directory should be read correctly.
  ASSERT_TRUE(entries);

  std::set<base::FilePath> found;
  for (size_t i = 0; i < entries->size(); ++i) {
    found.insert(base::FilePath::FromUTF8Unsafe((*entries)[i].title()));
  }
  EXPECT_EQ(2U, found.size());
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe("dir1")));
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe("TestFile")));
}

TEST_F(FileSystemTest, AddTeamDriveInChangeList) {
  ASSERT_TRUE(SetupTeamDrives());

  // The first load trigger the loading of team drives.
  ReadDirectorySync(base::FilePath::FromUTF8Unsafe("."));

  // Add a new team drive to the fake file system.
  {
    fake_drive_service_->AddTeamDrive("td_id_3", "team_drive_3");
    base::RunLoop().RunUntilIdle();
  }

  // Notify the update to the file system, which will add the team drive
  file_system_->CheckForUpdates();
  base::RunLoop().RunUntilIdle();

  std::unique_ptr<ResourceEntryVector> entries(
      ReadDirectorySync(base::FilePath::FromUTF8Unsafe("drive/team_drives/")));
  // The root directory should be read correctly.
  ASSERT_TRUE(entries);
  std::multiset<base::FilePath> found;
  for (size_t i = 0; i < entries->size(); ++i) {
    found.insert(base::FilePath::FromUTF8Unsafe((*entries)[i].title()));
  }
  EXPECT_EQ(4U, found.size());
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe("team_drive_3")));

  // Add a new entry to drive/team_drives/team_drive_3
  // Create a file in the test directory.
  std::unique_ptr<google_apis::FileResource> entry;
  {
    google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
    fake_drive_service_->AddNewFile(
        "text/plain", "(dummy data)", "td_id_3", "TestFile",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(google_apis::HTTP_CREATED, error);
  }

  // Notify the update to the file system.
  file_system_->CheckForUpdates();
  base::RunLoop().RunUntilIdle();

  entries = ReadDirectorySync(
      base::FilePath::FromUTF8Unsafe("drive/team_drives/team_drive_3"));
  // The root directory should be read correctly.
  ASSERT_TRUE(entries);

  found.clear();
  for (size_t i = 0; i < entries->size(); ++i) {
    found.insert(base::FilePath::FromUTF8Unsafe((*entries)[i].title()));
  }
  EXPECT_EQ(1U, found.size());
  EXPECT_EQ(1U, found.count(base::FilePath::FromUTF8Unsafe("TestFile")));
}

TEST_F(FileSystemTest, ReadDirectory_NonRootDirectory) {
  // ReadDirectory() should kick off the resource list loading.
  std::unique_ptr<ResourceEntryVector> entries(ReadDirectorySync(
      base::FilePath::FromUTF8Unsafe("drive/root/Directory 1")));
  // The non root directory should also be read correctly.
  // There was a bug (crbug.com/181487), which broke this behavior.
  // Make sure this is fixed.
  ASSERT_TRUE(entries);
  EXPECT_EQ(3U, entries->size());
}

TEST_F(FileSystemTest, LoadFileSystemFromUpToDateCache) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_SERVER_TIMESTAMP));

  // Kicks loading of cached file system and query for server update.
  EXPECT_TRUE(ReadDirectorySync(util::GetDriveMyDriveRootPath()));

  // SetUpTestFileSystem and FakeDriveService have the same
  // start_page_token (i.e. the local metadata is up to date), so no request for
  // new resource list (i.e., call to GetResourceList) should happen.
  EXPECT_EQ(0, fake_drive_service_->file_list_load_count());

  // Since the file system has verified that it holds the latest snapshot,
  // it should change its state to "loaded", which admits periodic refresh.
  // To test it, call CheckForUpdates and verify it does try to check updates.
  const int start_page_toke_load_count_before =
      fake_drive_service_->start_page_token_load_count();
  file_system_->CheckForUpdates();
  task_runner_->RunUntilIdle();
  EXPECT_LT(start_page_toke_load_count_before,
            fake_drive_service_->start_page_token_load_count());
}

TEST_F(FileSystemTest, LoadFileSystemFromCacheWhileOffline) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_OLD_TIMESTAMP));

  // Make GetResourceList fail for simulating offline situation. This will
  // leave the file system "loaded from cache, but not synced with server"
  // state.
  fake_drive_service_->set_offline(true);

  // Load the root.
  EXPECT_TRUE(ReadDirectorySync(util::GetDriveGrandRootPath()));
  // Loading of start page token should not happen as it's offline.
  EXPECT_EQ(0, fake_drive_service_->start_page_token_load_count());

  // Load "My Drive".
  EXPECT_TRUE(ReadDirectorySync(util::GetDriveMyDriveRootPath()));
  EXPECT_EQ(0, fake_drive_service_->start_page_token_load_count());

  // Tests that cached data can be loaded even if the server is not reachable.
  EXPECT_TRUE(EntryExists(base::FilePath(
      FILE_PATH_LITERAL("drive/root/File1"))));
  EXPECT_TRUE(EntryExists(base::FilePath(
      FILE_PATH_LITERAL("drive/root/Dir1"))));
  EXPECT_TRUE(EntryExists(base::FilePath(
      FILE_PATH_LITERAL("drive/root/Dir1/File2"))));
  EXPECT_TRUE(EntryExists(base::FilePath(
      FILE_PATH_LITERAL("drive/root/Dir1/SubDir2"))));
  EXPECT_TRUE(EntryExists(base::FilePath(
      FILE_PATH_LITERAL("drive/root/Dir1/SubDir2/File3"))));

  // Since the file system has at least succeeded to load cached snapshot,
  // the file system should be able to start periodic refresh.
  // To test it, call CheckForUpdates and verify it does try to check
  // updates, which will cause directory changes.
  fake_drive_service_->set_offline(false);

  file_system_->CheckForUpdates();

  task_runner_->RunUntilIdle();
  EXPECT_EQ(1, fake_drive_service_->start_page_token_load_count());
  EXPECT_EQ(1, fake_drive_service_->change_list_load_count());

  ASSERT_LE(0u, mock_directory_observer_->changed_directories().size());
  ASSERT_LE(1u, mock_directory_observer_->changed_files().size());
}

TEST_F(FileSystemTest, ReadDirectoryWhileRefreshing) {
  // Use old timestamp so the fast fetch will be performed.
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_OLD_TIMESTAMP));

  // The list of resources in "drive/root/Dir1" should be fetched.
  EXPECT_TRUE(ReadDirectorySync(base::FilePath(
      FILE_PATH_LITERAL("drive/root/Dir1"))));
  EXPECT_EQ(1, fake_drive_service_->directory_load_count());

  ASSERT_LE(1u, mock_directory_observer_->changed_directories().size());
}

TEST_F(FileSystemTest, GetResourceEntryNonExistentWhileRefreshing) {
  // Use old timestamp so the fast fetch will be performed.
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_OLD_TIMESTAMP));

  // If an entry is not found, parent directory's resource list is fetched.
  EXPECT_FALSE(GetResourceEntrySync(base::FilePath(
      FILE_PATH_LITERAL("drive/root/Dir1/NonExistentFile"))));
  EXPECT_EQ(1, fake_drive_service_->directory_load_count());

  ASSERT_LE(1u, mock_directory_observer_->changed_directories().size());
}

TEST_F(FileSystemTest, CreateDirectoryByImplicitLoad) {
  // Intentionally *not* calling LoadFullResourceList(), for testing that
  // CreateDirectory ensures the resource list is loaded before it runs.

  base::FilePath existing_directory(
      FILE_PATH_LITERAL("drive/root/Directory 1"));
  FileError error = FILE_ERROR_FAILED;
  file_system_->CreateDirectory(
      existing_directory,
      true,  // is_exclusive
      false,  // is_recursive
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();

  // It should fail because is_exclusive is set to true.
  EXPECT_EQ(FILE_ERROR_EXISTS, error);
}

TEST_F(FileSystemTest, CreateDirectoryRecursively) {
  // Intentionally *not* calling LoadFullResourceList(), for testing that
  // CreateDirectory ensures the resource list is loaded before it runs.

  base::FilePath new_directory(
      FILE_PATH_LITERAL("drive/root/Directory 1/a/b/c/d"));
  FileError error = FILE_ERROR_FAILED;
  file_system_->CreateDirectory(
      new_directory,
      true,  // is_exclusive
      true,  // is_recursive
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();

  EXPECT_EQ(FILE_ERROR_OK, error);

  std::unique_ptr<ResourceEntry> entry(GetResourceEntrySync(new_directory));
  ASSERT_TRUE(entry);
  EXPECT_TRUE(entry->file_info().is_directory());
}

TEST_F(FileSystemTest, ReadDirectoryAfterUpdateWhileLoading) {
  // Simulate the situation that full feed fetching takes very long time,
  // to test the recursive "fast fetch" feature is properly working.
  fake_drive_service_->set_never_return_all_file_list(true);

  // On the fake server, create the test directory.
  std::unique_ptr<google_apis::FileResource> parent;
  {
    google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
    fake_drive_service_->AddNewDirectory(
        fake_drive_service_->GetRootResourceId(), "UpdateWhileLoadingTestDir",
        AddNewDirectoryOptions(),
        google_apis::test_util::CreateCopyResultCallback(&error, &parent));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(google_apis::HTTP_CREATED, error);
  }

  // Fetch the directory. Currently it is empty.
  std::unique_ptr<ResourceEntryVector> before =
      ReadDirectorySync(base::FilePath(
          FILE_PATH_LITERAL("drive/root/UpdateWhileLoadingTestDir")));
  ASSERT_TRUE(before);
  EXPECT_EQ(0u, before->size());

  // Create a file in the test directory.
  std::unique_ptr<google_apis::FileResource> entry;
  {
    google_apis::DriveApiErrorCode error = google_apis::DRIVE_OTHER_ERROR;
    fake_drive_service_->AddNewFile(
        "text/plain",
        "(dummy data)",
        parent->file_id(),
        "TestFile",
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(google_apis::HTTP_CREATED, error);
  }

  // Notify the update to the file system.
  file_system_->CheckForUpdates();

  // Fast forward the clock, so that a new read of the directory is started.
  task_runner_->FastForwardBy(base::TimeDelta::FromMinutes(1));

  // Read the directory once again. Although the full feed fetching is not yet
  // finished, the "fast fetch" of the directory works and the refreshed content
  // is returned.
  std::unique_ptr<ResourceEntryVector> after = ReadDirectorySync(base::FilePath(
      FILE_PATH_LITERAL("drive/root/UpdateWhileLoadingTestDir")));
  ASSERT_TRUE(after);
  EXPECT_EQ(1u, after->size());
}

TEST_F(FileSystemTest, PinAndUnpin) {
  ASSERT_TRUE(LoadFullResourceList());

  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));

  // Get the file info.
  std::unique_ptr<ResourceEntry> entry(GetResourceEntrySync(file_path));
  ASSERT_TRUE(entry);

  // Pin the file.
  FileError error = FILE_ERROR_FAILED;
  file_system_->Pin(file_path,
                    google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  entry = GetResourceEntrySync(file_path);
  ASSERT_TRUE(entry);
  EXPECT_TRUE(entry->file_specific_info().cache_state().is_pinned());
  EXPECT_TRUE(entry->file_specific_info().cache_state().is_present());

  // Unpin the file.
  error = FILE_ERROR_FAILED;
  file_system_->Unpin(file_path,
                      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  entry = GetResourceEntrySync(file_path);
  ASSERT_TRUE(entry);
  EXPECT_FALSE(entry->file_specific_info().cache_state().is_pinned());

  // Pinned file gets synced and it results in entry state changes.
  ASSERT_EQ(0u, mock_directory_observer_->changed_directories().size());
  ASSERT_EQ(1u, mock_directory_observer_->changed_files().size());
  EXPECT_EQ(1u,
            mock_directory_observer_->changed_files().CountDirectory(
                base::FilePath(FILE_PATH_LITERAL("drive/root"))));
}

TEST_F(FileSystemTest, PinAndUnpin_NotSynced) {
  ASSERT_TRUE(LoadFullResourceList());

  base::FilePath file_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));

  // Get the file info.
  std::unique_ptr<ResourceEntry> entry(GetResourceEntrySync(file_path));
  ASSERT_TRUE(entry);

  // Unpin the file just after pinning. File fetch should be cancelled.
  FileError error_pin = FILE_ERROR_FAILED;
  file_system_->Pin(
      file_path,
      google_apis::test_util::CreateCopyResultCallback(&error_pin));

  FileError error_unpin = FILE_ERROR_FAILED;
  file_system_->Unpin(
      file_path,
      google_apis::test_util::CreateCopyResultCallback(&error_unpin));

  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error_pin);
  EXPECT_EQ(FILE_ERROR_OK, error_unpin);

  // No cache file available because the sync was cancelled by Unpin().
  entry = GetResourceEntrySync(file_path);
  ASSERT_TRUE(entry);
  EXPECT_FALSE(entry->file_specific_info().cache_state().is_present());
}

TEST_F(FileSystemTest, GetAvailableSpace) {
  FileError error = FILE_ERROR_OK;
  int64_t bytes_total;
  int64_t bytes_used;
  file_system_->GetAvailableSpace(
      google_apis::test_util::CreateCopyResultCallback(
          &error, &bytes_total, &bytes_used));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(6789012345LL, bytes_used);
  EXPECT_EQ(9876543210LL, bytes_total);
}

TEST_F(FileSystemTest, MarkCacheFileAsMountedAndUnmounted) {
  ASSERT_TRUE(LoadFullResourceList());

  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));

  // Make the file cached.
  FileError error = FILE_ERROR_FAILED;
  base::FilePath file_path;
  std::unique_ptr<ResourceEntry> entry;
  file_system_->GetFile(
      file_in_root,
      google_apis::test_util::CreateCopyResultCallback(
          &error, &file_path, &entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  // Test for mounting.
  error = FILE_ERROR_FAILED;
  file_path.clear();
  file_system_->MarkCacheFileAsMounted(
      file_in_root,
      google_apis::test_util::CreateCopyResultCallback(&error, &file_path));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  error = FILE_ERROR_FAILED;
  bool is_marked_as_mounted = false;
  file_system_->IsCacheFileMarkedAsMounted(
      file_in_root, google_apis::test_util::CreateCopyResultCallback(
                        &error, &is_marked_as_mounted));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  EXPECT_TRUE(is_marked_as_mounted);

  // Cannot remove a cache entry while it's being mounted.
  EXPECT_EQ(FILE_ERROR_IN_USE, cache_->Remove(entry->local_id()));

  // Test for unmounting.
  error = FILE_ERROR_FAILED;
  file_system_->MarkCacheFileAsUnmounted(
      file_path,
      google_apis::test_util::CreateCopyResultCallback(&error));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);

  error = FILE_ERROR_FAILED;
  is_marked_as_mounted = true;
  file_system_->IsCacheFileMarkedAsMounted(
      file_in_root, google_apis::test_util::CreateCopyResultCallback(
                        &error, &is_marked_as_mounted));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  EXPECT_FALSE(is_marked_as_mounted);

  // Now able to remove the cache entry.
  EXPECT_EQ(FILE_ERROR_OK, cache_->Remove(entry->local_id()));
}

TEST_F(FileSystemTest, FreeDiskSpaceIfNeededFor) {
  ASSERT_TRUE(LoadFullResourceList());

  base::FilePath file_in_root(FILE_PATH_LITERAL("drive/root/File 1.txt"));

  // Make the file cached.
  FileError error = FILE_ERROR_FAILED;
  base::FilePath file_path;
  std::unique_ptr<ResourceEntry> entry;
  file_system_->GetFile(file_in_root,
                        google_apis::test_util::CreateCopyResultCallback(
                            &error, &file_path, &entry));
  task_runner_->RunUntilIdle();
  EXPECT_EQ(FILE_ERROR_OK, error);
  ASSERT_TRUE(entry);
  EXPECT_TRUE(entry->file_specific_info().cache_state().is_present());

  bool available;
  file_system_->FreeDiskSpaceIfNeededFor(
      512LL << 40,
      google_apis::test_util::CreateCopyResultCallback(&available));
  task_runner_->RunUntilIdle();
  ASSERT_FALSE(available);

  entry = GetResourceEntrySync(file_in_root);
  ASSERT_TRUE(entry);
  EXPECT_FALSE(entry->file_specific_info().cache_state().is_present());
}

TEST_F(FileSystemTest, DebugMetadata) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_SERVER_TIMESTAMP));
  ASSERT_TRUE(SetupTeamDrives());

  // The first load will trigger the loading of team drives.
  ReadDirectorySync(base::FilePath::FromUTF8Unsafe("."));

  base::Time now = base::Time::Now();

  file_system_->CheckForUpdates();
  base::RunLoop().RunUntilIdle();

  FileSystemMetadata default_corpus_metadata;
  std::map<std::string, FileSystemMetadata> team_drive_metadata;

  file_system_->GetMetadata(google_apis::test_util::CreateCopyResultCallback(
      &default_corpus_metadata, &team_drive_metadata));
  base::RunLoop().RunUntilIdle();

  EXPECT_LE(now, default_corpus_metadata.last_update_check_time);
  EXPECT_FALSE(default_corpus_metadata.refreshing);
  EXPECT_EQ(FILE_ERROR_OK, default_corpus_metadata.last_update_check_error);
  EXPECT_EQ("654340", default_corpus_metadata.start_page_token);

  EXPECT_EQ(3UL, team_drive_metadata.size());
  EXPECT_FALSE(team_drive_metadata["td_id_1"].refreshing);
  EXPECT_EQ(util::GetDriveTeamDrivesRootPath().Append("team_drive_1").value(),
            team_drive_metadata["td_id_1"].path);
  EXPECT_LE(now, team_drive_metadata["td_id_1"].last_update_check_time);
  EXPECT_EQ("654345", team_drive_metadata["td_id_1"].start_page_token);
  EXPECT_EQ(FILE_ERROR_OK,
            team_drive_metadata["td_id_1"].last_update_check_error);

  EXPECT_FALSE(team_drive_metadata["td_id_2"].refreshing);
  EXPECT_EQ(util::GetDriveTeamDrivesRootPath().Append("team_drive_2").value(),
            team_drive_metadata["td_id_2"].path);
  EXPECT_LE(now, team_drive_metadata["td_id_2"].last_update_check_time);
  EXPECT_EQ("654346", team_drive_metadata["td_id_2"].start_page_token);
  EXPECT_EQ(FILE_ERROR_OK,
            team_drive_metadata["td_id_2"].last_update_check_error);

  EXPECT_FALSE(team_drive_metadata["td_id_2_2"].refreshing);
  EXPECT_EQ(util::GetDriveTeamDrivesRootPath().Append("team_drive_2").value(),
            team_drive_metadata["td_id_2_2"].path);
  EXPECT_LE(now, team_drive_metadata["td_id_2_2"].last_update_check_time);
  EXPECT_EQ("654347", team_drive_metadata["td_id_2_2"].start_page_token);
  EXPECT_EQ(FILE_ERROR_OK,
            team_drive_metadata["td_id_2_2"].last_update_check_error);
}

TEST_F(FileSystemTest, TeamDrivesChangesObserved) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_SERVER_TIMESTAMP));
  ASSERT_TRUE(SetupTeamDrives());

  // The first load will trigger the loading of team drives.
  ReadDirectorySync(base::FilePath::FromUTF8Unsafe("."));

  // This is the initial set of team drives.
  EXPECT_EQ(3UL, mock_directory_observer_->added_team_drive_ids().size());
  EXPECT_TRUE(mock_directory_observer_->removed_team_drive_ids().empty());

  fake_drive_service_->AddTeamDrive("td_id_3", "team_drive_3");
  // TODO(slangley): Add support for removing a team drive in fake file service.
  base::RunLoop().RunUntilIdle();

  // Notify the update to the file system, which will add the team drive
  file_system_->CheckForUpdates();
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(1UL, mock_directory_observer_->added_team_drive_ids().size());
  EXPECT_EQ(1UL,
            mock_directory_observer_->added_team_drive_ids().count("td_id_3"));
  EXPECT_TRUE(mock_directory_observer_->removed_team_drive_ids().empty());
}

TEST_F(FileSystemTest, CheckUpdatesWithIds) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_SERVER_TIMESTAMP));
  ASSERT_TRUE(SetupTeamDrives());

  // The first load will trigger the loading of team drives.
  ReadDirectorySync(base::FilePath::FromUTF8Unsafe("."));

  // Check a non existent team drive id, no other sources should be updated.
  file_system_->CheckForUpdates({"non_existant_team_drive_id"});
  base::RunLoop().RunUntilIdle();

  FileSystemMetadata default_corpus_metadata;
  std::map<std::string, FileSystemMetadata> team_drive_metadata;

  file_system_->GetMetadata(google_apis::test_util::CreateCopyResultCallback(
      &default_corpus_metadata, &team_drive_metadata));
  base::RunLoop().RunUntilIdle();

  const base::Time default_time;
  EXPECT_EQ(default_time, default_corpus_metadata.last_update_check_time);
  EXPECT_EQ(default_time,
            team_drive_metadata["td_id_1"].last_update_check_time);
  EXPECT_EQ(default_time,
            team_drive_metadata["td_id_2"].last_update_check_time);
  EXPECT_EQ(default_time,
            team_drive_metadata["td_id_2_2"].last_update_check_time);

  base::Time now = base::Time::Now();

  // Update just the default corpus.
  file_system_->CheckForUpdates({""});
  base::RunLoop().RunUntilIdle();

  file_system_->GetMetadata(google_apis::test_util::CreateCopyResultCallback(
      &default_corpus_metadata, &team_drive_metadata));
  base::RunLoop().RunUntilIdle();

  EXPECT_LE(now, default_corpus_metadata.last_update_check_time);
  EXPECT_EQ(default_time,
            team_drive_metadata["td_id_1"].last_update_check_time);
  EXPECT_EQ(default_time,
            team_drive_metadata["td_id_2"].last_update_check_time);
  EXPECT_EQ(default_time,
            team_drive_metadata["td_id_2_2"].last_update_check_time);

  // Update two team drives.
  now = base::Time::Now();
  file_system_->CheckForUpdates({"td_id_1", "td_id_2"});
  base::RunLoop().RunUntilIdle();

  file_system_->GetMetadata(google_apis::test_util::CreateCopyResultCallback(
      &default_corpus_metadata, &team_drive_metadata));
  base::RunLoop().RunUntilIdle();

  EXPECT_GE(now, default_corpus_metadata.last_update_check_time);
  EXPECT_LE(now, team_drive_metadata["td_id_1"].last_update_check_time);
  EXPECT_LE(now, team_drive_metadata["td_id_2"].last_update_check_time);
  EXPECT_EQ(default_time,
            team_drive_metadata["td_id_2_2"].last_update_check_time);

  // Update everything.
  now = base::Time::Now();
  file_system_->CheckForUpdates({"", "td_id_1", "td_id_2", "td_id_2_2"});
  base::RunLoop().RunUntilIdle();

  file_system_->GetMetadata(google_apis::test_util::CreateCopyResultCallback(
      &default_corpus_metadata, &team_drive_metadata));
  base::RunLoop().RunUntilIdle();

  EXPECT_LE(now, default_corpus_metadata.last_update_check_time);
  EXPECT_LE(now, team_drive_metadata["td_id_1"].last_update_check_time);
  EXPECT_LE(now, team_drive_metadata["td_id_2"].last_update_check_time);
  EXPECT_LE(now, team_drive_metadata["td_id_2_2"].last_update_check_time);
}

TEST_F(FileSystemTest, RemoveNonExistingTeamDrive) {
  ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_SERVER_TIMESTAMP));
  ASSERT_TRUE(SetupTeamDrives());

  // The first load will trigger the loading of team drives.
  ReadDirectorySync(base::FilePath::FromUTF8Unsafe("."));

  // Create a file change with a delete team drive, ensure file_system_ does not
  // crash.
  const base::FilePath path =
      util::GetDriveTeamDrivesRootPath().Append("team_drive_2");
  std::unique_ptr<ResourceEntry> entry = GetResourceEntrySync(path);
  ASSERT_TRUE(entry);

  drive::FileChange change;
  change.Update(path, *entry, FileChange::CHANGE_TYPE_DELETE);

  // First time should be removed.
  file_system_->OnTeamDrivesChanged(change);
  std::set<std::string> expected_changes = {"td_id_2"};
  EXPECT_EQ(expected_changes,
            mock_directory_observer_->removed_team_drive_ids());

  // Second time should be no changes, and no crash.
  file_system_->OnTeamDrivesChanged(change);
  expected_changes = {};
  EXPECT_EQ(expected_changes,
            mock_directory_observer_->removed_team_drive_ids());
}

}   // namespace drive
