// 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/sync_client.h"

#include <memory>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/test_timeouts.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/drive/chromeos/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_cache.h"
#include "components/drive/chromeos/file_system/move_operation.h"
#include "components/drive/chromeos/file_system/operation_delegate.h"
#include "components/drive/chromeos/file_system/remove_operation.h"
#include "components/drive/chromeos/resource_metadata.h"
#include "components/drive/drive.pb.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/resource_entry_conversion.h"
#include "components/drive/service/fake_drive_service.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 "testing/gtest/include/gtest/gtest.h"

namespace drive {
namespace internal {

namespace {

// The content of files initially stored in the cache.
const char kLocalContent[] = "Hello!";

// The content of files stored in the service.
const char kRemoteContent[] = "World!";

// SyncClientTestDriveService will return DRIVE_CANCELLED when a request is
// made with the specified resource ID.
class SyncClientTestDriveService : public ::drive::FakeDriveService {
 public:
  SyncClientTestDriveService() : download_file_count_(0) {}

  // FakeDriveService override:
  google_apis::CancelCallback DownloadFile(
      const base::FilePath& local_cache_path,
      const std::string& resource_id,
      const google_apis::DownloadActionCallback& download_action_callback,
      const google_apis::GetContentCallback& get_content_callback,
      const google_apis::ProgressCallback& progress_callback) override {
    ++download_file_count_;
    if (resource_id == resource_id_to_be_cancelled_) {
      base::ThreadTaskRunnerHandle::Get()->PostTask(
          FROM_HERE,
          base::Bind(download_action_callback,
                     google_apis::DRIVE_CANCELLED,
                     base::FilePath()));
      return google_apis::CancelCallback();
    }
    if (resource_id == resource_id_to_be_paused_) {
      paused_action_ = base::Bind(download_action_callback,
                                  google_apis::DRIVE_OTHER_ERROR,
                                  base::FilePath());
      return google_apis::CancelCallback();
    }
    return FakeDriveService::DownloadFile(local_cache_path,
                                          resource_id,
                                          download_action_callback,
                                          get_content_callback,
                                          progress_callback);
  }

  int download_file_count() const { return download_file_count_; }

  void set_resource_id_to_be_cancelled(const std::string& resource_id) {
    resource_id_to_be_cancelled_ = resource_id;
  }

  void set_resource_id_to_be_paused(const std::string& resource_id) {
    resource_id_to_be_paused_ = resource_id;
  }

  const base::Closure& paused_action() const { return paused_action_; }

 private:
  int download_file_count_;
  std::string resource_id_to_be_cancelled_;
  std::string resource_id_to_be_paused_;
  base::Closure paused_action_;
};

}  // namespace

class SyncClientTest : public testing::Test {
 public:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    pref_service_.reset(new TestingPrefServiceSimple);
    test_util::RegisterDrivePrefs(pref_service_->registry());

    fake_network_change_notifier_.reset(
        new test_util::FakeNetworkChangeNotifier);

    logger_.reset(new EventLogger);

    drive_service_.reset(new SyncClientTestDriveService);

    scheduler_.reset(new JobScheduler(
        pref_service_.get(),
        logger_.get(),
        drive_service_.get(),
        base::ThreadTaskRunnerHandle::Get().get()));

    metadata_storage_.reset(new ResourceMetadataStorage(
        temp_dir_.GetPath(), base::ThreadTaskRunnerHandle::Get().get()));
    ASSERT_TRUE(metadata_storage_->Initialize());

    cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(),
                               base::ThreadTaskRunnerHandle::Get().get(),
                               NULL /* free_disk_space_getter */));
    ASSERT_TRUE(cache_->Initialize());

    metadata_.reset(new internal::ResourceMetadata(
        metadata_storage_.get(), cache_.get(),
        base::ThreadTaskRunnerHandle::Get()));
    ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());

    about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get()));
    loader_controller_.reset(new LoaderController);
    change_list_loader_.reset(new ChangeListLoader(
        logger_.get(),
        base::ThreadTaskRunnerHandle::Get().get(),
        metadata_.get(),
        scheduler_.get(),
        about_resource_loader_.get(),
        loader_controller_.get()));
    ASSERT_NO_FATAL_FAILURE(SetUpTestData());

    sync_client_.reset(
        new SyncClient(base::ThreadTaskRunnerHandle::Get().get(), &delegate_,
                       scheduler_.get(), metadata_.get(), cache_.get(),
                       loader_controller_.get(), temp_dir_.GetPath()));

    // Disable delaying so that DoSyncLoop() starts immediately.
    sync_client_->set_delay_for_testing(base::TimeDelta::FromSeconds(0));
  }

  // Adds a file to the service root and |resource_ids_|.
  void AddFileEntry(const std::string& title) {
    google_apis::DriveApiErrorCode error = google_apis::DRIVE_FILE_ERROR;
    std::unique_ptr<google_apis::FileResource> entry;
    drive_service_->AddNewFile(
        "text/plain",
        kRemoteContent,
        drive_service_->GetRootResourceId(),
        title,
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    base::RunLoop().RunUntilIdle();
    ASSERT_EQ(google_apis::HTTP_CREATED, error);
    ASSERT_TRUE(entry);
    resource_ids_[title] = entry->file_id();
  }

  // Sets up data for tests.
  void SetUpTestData() {
    // Prepare a temp file.
    base::FilePath temp_file;
    EXPECT_TRUE(
        base::CreateTemporaryFileInDir(temp_dir_.GetPath(), &temp_file));
    ASSERT_TRUE(google_apis::test_util::WriteStringToFile(temp_file,
                                                          kLocalContent));

    // Add file entries to the service.
    ASSERT_NO_FATAL_FAILURE(AddFileEntry("foo"));
    ASSERT_NO_FATAL_FAILURE(AddFileEntry("bar"));
    ASSERT_NO_FATAL_FAILURE(AddFileEntry("baz"));
    ASSERT_NO_FATAL_FAILURE(AddFileEntry("fetched"));
    ASSERT_NO_FATAL_FAILURE(AddFileEntry("dirty"));
    ASSERT_NO_FATAL_FAILURE(AddFileEntry("removed"));
    ASSERT_NO_FATAL_FAILURE(AddFileEntry("moved"));

    // Load data from the service to the metadata.
    FileError error = FILE_ERROR_FAILED;
    change_list_loader_->LoadIfNeeded(
        google_apis::test_util::CreateCopyResultCallback(&error));
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(FILE_ERROR_OK, error);

    // Prepare 3 pinned-but-not-present files.
    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("foo")));
    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("bar")));
    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("baz")));

    // Prepare a pinned-and-fetched file.
    const std::string md5_fetched = "md5";
    EXPECT_EQ(FILE_ERROR_OK,
              cache_->Store(GetLocalId("fetched"), md5_fetched,
                            temp_file, FileCache::FILE_OPERATION_COPY));
    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("fetched")));

    // Prepare a pinned-and-fetched-and-dirty file.
    EXPECT_EQ(FILE_ERROR_OK,
              cache_->Store(GetLocalId("dirty"), std::string(),
                            temp_file, FileCache::FILE_OPERATION_COPY));
    EXPECT_EQ(FILE_ERROR_OK, cache_->Pin(GetLocalId("dirty")));

    // Prepare a removed file.
    file_system::RemoveOperation remove_operation(
        base::ThreadTaskRunnerHandle::Get().get(), &delegate_, metadata_.get(),
        cache_.get());
    remove_operation.Remove(
        util::GetDriveMyDriveRootPath().AppendASCII("removed"),
        false,  // is_recursive
        google_apis::test_util::CreateCopyResultCallback(&error));
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(FILE_ERROR_OK, error);

    // Prepare a moved file.
    file_system::MoveOperation move_operation(
        base::ThreadTaskRunnerHandle::Get().get(), &delegate_, metadata_.get());
    move_operation.Move(
        util::GetDriveMyDriveRootPath().AppendASCII("moved"),
        util::GetDriveMyDriveRootPath().AppendASCII("moved_new_title"),
        google_apis::test_util::CreateCopyResultCallback(&error));
    base::RunLoop().RunUntilIdle();
    EXPECT_EQ(FILE_ERROR_OK, error);
  }

 protected:
  std::string GetLocalId(const std::string& title) {
    EXPECT_EQ(1U, resource_ids_.count(title));
    std::string local_id;
    EXPECT_EQ(FILE_ERROR_OK,
              metadata_->GetIdByResourceId(resource_ids_[title], &local_id));
    return local_id;
  }

  content::TestBrowserThreadBundle thread_bundle_;
  base::ScopedTempDir temp_dir_;
  std::unique_ptr<TestingPrefServiceSimple> pref_service_;
  std::unique_ptr<test_util::FakeNetworkChangeNotifier>
      fake_network_change_notifier_;
  std::unique_ptr<EventLogger> logger_;
  std::unique_ptr<SyncClientTestDriveService> drive_service_;
  file_system::OperationDelegate delegate_;
  std::unique_ptr<JobScheduler> scheduler_;
  std::unique_ptr<ResourceMetadataStorage, test_util::DestroyHelperForTests>
      metadata_storage_;
  std::unique_ptr<FileCache, test_util::DestroyHelperForTests> cache_;
  std::unique_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_;
  std::unique_ptr<AboutResourceLoader> about_resource_loader_;
  std::unique_ptr<LoaderController> loader_controller_;
  std::unique_ptr<ChangeListLoader> change_list_loader_;
  std::unique_ptr<SyncClient> sync_client_;

  std::map<std::string, std::string> resource_ids_;  // Name-to-id map.
};

TEST_F(SyncClientTest, StartProcessingBacklog) {
  sync_client_->StartProcessingBacklog();
  base::RunLoop().RunUntilIdle();

  ResourceEntry entry;
  // Pinned files get downloaded.
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());

  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("bar"), &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());

  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("baz"), &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());

  // Dirty file gets uploaded.
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("dirty"), &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());

  // Removed entry is not found.
  google_apis::DriveApiErrorCode status = google_apis::DRIVE_OTHER_ERROR;
  std::unique_ptr<google_apis::FileResource> server_entry;
  drive_service_->GetFileResource(
      resource_ids_["removed"],
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_TRUE(server_entry->labels().is_trashed());

  // Moved entry was moved.
  status = google_apis::DRIVE_OTHER_ERROR;
  drive_service_->GetFileResource(
      resource_ids_["moved"],
      google_apis::test_util::CreateCopyResultCallback(&status, &server_entry));
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, status);
  ASSERT_TRUE(server_entry);
  EXPECT_EQ("moved_new_title", server_entry->title());
}

TEST_F(SyncClientTest, AddFetchTask) {
  sync_client_->AddFetchTask(GetLocalId("foo"));
  base::RunLoop().RunUntilIdle();

  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
}

TEST_F(SyncClientTest, AddFetchTaskAndCancelled) {
  // Trigger fetching of a file which results in cancellation.
  drive_service_->set_resource_id_to_be_cancelled(resource_ids_["foo"]);
  sync_client_->AddFetchTask(GetLocalId("foo"));
  base::RunLoop().RunUntilIdle();

  // The file should be unpinned if the user wants the download to be cancelled.
  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_pinned());
}

TEST_F(SyncClientTest, RemoveFetchTask) {
  sync_client_->AddFetchTask(GetLocalId("foo"));
  sync_client_->AddFetchTask(GetLocalId("bar"));
  sync_client_->AddFetchTask(GetLocalId("baz"));

  sync_client_->RemoveFetchTask(GetLocalId("foo"));
  sync_client_->RemoveFetchTask(GetLocalId("baz"));
  base::RunLoop().RunUntilIdle();

  // Only "bar" should be fetched.
  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());

  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("bar"), &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());

  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("baz"), &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());

}

TEST_F(SyncClientTest, ExistingPinnedFiles) {
  // Start checking the existing pinned files. This will collect the resource
  // IDs of pinned files, with stale local cache files.
  sync_client_->StartCheckingExistingPinnedFiles();
  base::RunLoop().RunUntilIdle();

  // "fetched" and "dirty" are the existing pinned files.
  // The non-dirty one should be synced, but the dirty one should not.
  base::FilePath cache_file;
  std::string content;
  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(GetLocalId("fetched"), &cache_file));
  EXPECT_TRUE(base::ReadFileToString(cache_file, &content));
  EXPECT_EQ(kRemoteContent, content);
  content.clear();

  EXPECT_EQ(FILE_ERROR_OK, cache_->GetFile(GetLocalId("dirty"), &cache_file));
  EXPECT_TRUE(base::ReadFileToString(cache_file, &content));
  EXPECT_EQ(kLocalContent, content);
}

TEST_F(SyncClientTest, RetryOnDisconnection) {
  // Let the service go down.
  drive_service_->set_offline(true);
  // Change the network connection state after some delay, to test that
  // FILE_ERROR_NO_CONNECTION is handled by SyncClient correctly.
  // Without this delay, JobScheduler will keep the jobs unrun and SyncClient
  // will receive no error.
  base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
      FROM_HERE,
      base::Bind(&test_util::FakeNetworkChangeNotifier::SetConnectionType,
                 base::Unretained(fake_network_change_notifier_.get()),
                 net::NetworkChangeNotifier::CONNECTION_NONE),
      TestTimeouts::tiny_timeout());

  // Try fetch and upload.
  sync_client_->AddFetchTask(GetLocalId("foo"));
  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED),
                              GetLocalId("dirty"));
  base::RunLoop().RunUntilIdle();

  // Not yet fetched nor uploaded.
  ResourceEntry entry;
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_present());
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("dirty"), &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_dirty());

  // Switch to online.
  fake_network_change_notifier_->SetConnectionType(
      net::NetworkChangeNotifier::CONNECTION_WIFI);
  drive_service_->set_offline(false);
  base::RunLoop().RunUntilIdle();

  // Fetched and uploaded.
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("foo"), &entry));
  EXPECT_TRUE(entry.file_specific_info().cache_state().is_present());
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryById(GetLocalId("dirty"), &entry));
  EXPECT_FALSE(entry.file_specific_info().cache_state().is_dirty());
}

TEST_F(SyncClientTest, ScheduleRerun) {
  // Add a fetch task for "foo", this should result in being paused.
  drive_service_->set_resource_id_to_be_paused(resource_ids_["foo"]);
  sync_client_->AddFetchTask(GetLocalId("foo"));
  base::RunLoop().RunUntilIdle();

  // While the first task is paused, add a task again.
  // This results in scheduling rerun of the task.
  sync_client_->AddFetchTask(GetLocalId("foo"));
  base::RunLoop().RunUntilIdle();

  // Resume the paused task.
  drive_service_->set_resource_id_to_be_paused(std::string());
  ASSERT_FALSE(drive_service_->paused_action().is_null());
  drive_service_->paused_action().Run();
  base::RunLoop().RunUntilIdle();

  // Task should be run twice.
  EXPECT_EQ(2, drive_service_->download_file_count());
}

TEST_F(SyncClientTest, Dependencies) {
  // Create directories locally.
  const base::FilePath kPath1(FILE_PATH_LITERAL("drive/root/dir1"));
  const base::FilePath kPath2 = kPath1.AppendASCII("dir2");

  ResourceEntry parent;
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryByPath(kPath1.DirName(), &parent));

  ResourceEntry entry1;
  entry1.set_parent_local_id(parent.local_id());
  entry1.set_title(kPath1.BaseName().AsUTF8Unsafe());
  entry1.mutable_file_info()->set_is_directory(true);
  entry1.set_metadata_edit_state(ResourceEntry::DIRTY);
  std::string local_id1;
  EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(entry1, &local_id1));

  ResourceEntry entry2;
  entry2.set_parent_local_id(local_id1);
  entry2.set_title(kPath2.BaseName().AsUTF8Unsafe());
  entry2.mutable_file_info()->set_is_directory(true);
  entry2.set_metadata_edit_state(ResourceEntry::DIRTY);
  std::string local_id2;
  EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(entry2, &local_id2));

  // Start syncing the child first.
  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED), local_id2);
  // Start syncing the parent later.
  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED), local_id1);
  base::RunLoop().RunUntilIdle();

  // Both entries are synced.
  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(local_id1, &entry1));
  EXPECT_EQ(ResourceEntry::CLEAN, entry1.metadata_edit_state());
  EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryById(local_id2, &entry2));
  EXPECT_EQ(ResourceEntry::CLEAN, entry2.metadata_edit_state());
}

TEST_F(SyncClientTest, WaitForUpdateTaskToComplete) {
  // Create a directory locally.
  const base::FilePath kPath(FILE_PATH_LITERAL("drive/root/dir1"));

  ResourceEntry parent;
  EXPECT_EQ(FILE_ERROR_OK,
            metadata_->GetResourceEntryByPath(kPath.DirName(), &parent));

  ResourceEntry entry;
  entry.set_parent_local_id(parent.local_id());
  entry.set_title(kPath.BaseName().AsUTF8Unsafe());
  entry.mutable_file_info()->set_is_directory(true);
  entry.set_metadata_edit_state(ResourceEntry::DIRTY);
  std::string local_id;
  EXPECT_EQ(FILE_ERROR_OK, metadata_->AddEntry(entry, &local_id));

  // Sync task is not yet avialable.
  FileError error = FILE_ERROR_FAILED;
  EXPECT_FALSE(sync_client_->WaitForUpdateTaskToComplete(
      local_id, google_apis::test_util::CreateCopyResultCallback(&error)));

  // Start syncing the directory and wait for it to complete.
  sync_client_->AddUpdateTask(ClientContext(USER_INITIATED), local_id);

  EXPECT_TRUE(sync_client_->WaitForUpdateTaskToComplete(
      local_id, google_apis::test_util::CreateCopyResultCallback(&error)));

  base::RunLoop().RunUntilIdle();

  // The callback is called.
  EXPECT_EQ(FILE_ERROR_OK, error);
}

}  // namespace internal
}  // namespace drive
