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

#include <memory>

#include "base/command_line.h"
#include "base/files/scoped_temp_dir.h"
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "components/drive/chromeos/drive_test_util.h"
#include "components/drive/chromeos/file_cache.h"
#include "components/drive/chromeos/resource_metadata.h"
#include "components/drive/event_logger.h"
#include "components/drive/job_scheduler.h"
#include "components/drive/resource_metadata_storage.h"
#include "components/drive/service/fake_drive_service.h"
#include "components/drive/service/test_util.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace drive {
namespace internal {

namespace {

struct DestroyHelper {
  template <typename T>
  void operator()(T* object) const {
    if (object) {
      object->Destroy();
    }
  }
};

}  // namespace

class AboutResourceLoaderTest : 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>();

    drive_service_ = std::make_unique<FakeDriveService>();
    ASSERT_TRUE(test_util::SetUpTestEntries(drive_service_.get()));

    scheduler_ = std::make_unique<JobScheduler>(
        pref_service_.get(), logger_.get(), drive_service_.get(),
        task_runner_.get(), nullptr);
    metadata_storage_.reset(
        new ResourceMetadataStorage(temp_dir_.GetPath(), task_runner_.get()));
    ASSERT_TRUE(metadata_storage_->Initialize());

    cache_.reset(new FileCache(metadata_storage_.get(), temp_dir_.GetPath(),
                               task_runner_.get(),
                               nullptr /* free_disk_space_getter */));
    ASSERT_TRUE(cache_->Initialize());

    metadata_.reset(new ResourceMetadata(metadata_storage_.get(), cache_.get(),
                                         task_runner_.get()));
    ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize());

    about_resource_loader_ = std::make_unique<AboutResourceLoader>(
        scheduler_.get(), task_runner_->GetMockTickClock());
  }

  void TearDown() override {
    // We need to manually reset the objects that implement the Destroy idiom,
    // that deletes the object on the |task_runner_|. This is simpler than
    // introducing custom deleters that capture the |task_runner_| and
    // invoke RunUntilIdle().
    metadata_.reset();
    cache_.reset();
    metadata_storage_.reset();
    task_runner_->RunUntilIdle();
  }

  // Adds a new file to the root directory of the service.
  std::unique_ptr<google_apis::FileResource> AddNewFile(
      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", "content text", drive_service_->GetRootResourceId(),
        title,
        false,  // shared_with_me
        google_apis::test_util::CreateCopyResultCallback(&error, &entry));
    task_runner_->RunUntilIdle();
    EXPECT_EQ(google_apis::HTTP_CREATED, error);
    return entry;
  }

  scoped_refptr<base::TestMockTimeTaskRunner> task_runner_;
  base::ScopedTempDir temp_dir_;
  std::unique_ptr<TestingPrefServiceSimple> pref_service_;
  std::unique_ptr<EventLogger> logger_;
  std::unique_ptr<FakeDriveService> drive_service_;
  std::unique_ptr<JobScheduler> scheduler_;
  std::unique_ptr<ResourceMetadataStorage, DestroyHelper> metadata_storage_;
  std::unique_ptr<FileCache, DestroyHelper> cache_;
  std::unique_ptr<ResourceMetadata, DestroyHelper> metadata_;
  std::unique_ptr<AboutResourceLoader> about_resource_loader_;
};

TEST_F(AboutResourceLoaderTest, AboutResourceLoader) {
  google_apis::DriveApiErrorCode error[6] = {};
  std::unique_ptr<google_apis::AboutResource> about[6];

  // No resource is cached at the beginning.
  ASSERT_FALSE(about_resource_loader_->cached_about_resource());

  // Since no resource is cached, this "Get" should trigger the update.
  about_resource_loader_->GetAboutResource(
      google_apis::test_util::CreateCopyResultCallback(error + 0, about + 0));
  // Since there is one in-flight update, the next "Get" just wait for it.
  about_resource_loader_->GetAboutResource(
      google_apis::test_util::CreateCopyResultCallback(error + 1, about + 1));

  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, error[0]);
  EXPECT_EQ(google_apis::HTTP_SUCCESS, error[1]);
  const int64_t first_changestamp = about[0]->largest_change_id();
  EXPECT_EQ(first_changestamp, about[1]->largest_change_id());
  ASSERT_TRUE(about_resource_loader_->cached_about_resource());
  EXPECT_EQ(
      first_changestamp,
      about_resource_loader_->cached_about_resource()->largest_change_id());

  // Increment changestamp by 1.
  AddNewFile("temp");
  // Explicitly calling UpdateAboutResource will start another API call.
  about_resource_loader_->UpdateAboutResource(
      google_apis::test_util::CreateCopyResultCallback(error + 2, about + 2));
  // It again waits for the in-flight UpdateAboutResoure call, even though this
  // time there is a cached result.
  about_resource_loader_->GetAboutResource(
      google_apis::test_util::CreateCopyResultCallback(error + 3, about + 3));

  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, error[2]);
  EXPECT_EQ(google_apis::HTTP_SUCCESS, error[3]);
  EXPECT_EQ(first_changestamp + 1, about[2]->largest_change_id());
  EXPECT_EQ(first_changestamp + 1, about[3]->largest_change_id());
  EXPECT_EQ(
      first_changestamp + 1,
      about_resource_loader_->cached_about_resource()->largest_change_id());

  // Increment changestamp by 1.
  AddNewFile("temp2");
  // Now no UpdateAboutResource task is running. Returns the cached result.
  about_resource_loader_->GetAboutResource(
      google_apis::test_util::CreateCopyResultCallback(error + 4, about + 4));
  // Explicitly calling UpdateAboutResource will start another API call.
  about_resource_loader_->UpdateAboutResource(
      google_apis::test_util::CreateCopyResultCallback(error + 5, about + 5));

  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_NO_CONTENT, error[4]);
  EXPECT_EQ(google_apis::HTTP_SUCCESS, error[5]);
  EXPECT_EQ(first_changestamp + 1, about[4]->largest_change_id());
  EXPECT_EQ(first_changestamp + 2, about[5]->largest_change_id());
  EXPECT_EQ(
      first_changestamp + 2,
      about_resource_loader_->cached_about_resource()->largest_change_id());

  EXPECT_EQ(3, drive_service_->about_resource_load_count());
}

TEST_F(AboutResourceLoaderTest, EvictCache) {
  google_apis::DriveApiErrorCode error;
  std::unique_ptr<google_apis::AboutResource> about;

  // No resource is cached at the beginning.
  ASSERT_FALSE(about_resource_loader_->cached_about_resource());

  // Since no resource is cached, this "Get" should trigger the update.
  about_resource_loader_->GetAboutResource(
      google_apis::test_util::CreateCopyResultCallback(&error, &about));

  task_runner_->RunUntilIdle();
  EXPECT_EQ(google_apis::HTTP_SUCCESS, error);

  // Should have a cached resource.
  ASSERT_TRUE(about_resource_loader_->cached_about_resource());

  // Advance the timer should evict the cache.
  task_runner_->FastForwardUntilNoTasksRemain();

  // Cache should be evicted.
  ASSERT_FALSE(about_resource_loader_->cached_about_resource());
}

}  // namespace internal
}  // namespace drive
