// Copyright (c) 2013 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/drive/download_handler.h"

#include <stdint.h>

#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "chrome/browser/chromeos/drive/file_system_util.h"
#include "chrome/test/base/testing_profile.h"
#include "components/drive/chromeos/dummy_file_system.h"
#include "components/drive/file_system_core_util.h"
#include "content/public/test/mock_download_item.h"
#include "content/public/test/mock_download_manager.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "google_apis/drive/test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace drive {

namespace {

// Test file system for verifying the behavior of DownloadHandler, by simulating
// various responses from FileSystem.
class DownloadHandlerTestFileSystem : public DummyFileSystem {
 public:
  DownloadHandlerTestFileSystem() : error_(FILE_ERROR_FAILED) {}

  void set_error(FileError error) { error_ = error; }

  // FileSystemInterface overrides.
  void GetResourceEntry(const base::FilePath& file_path,
                        const GetResourceEntryCallback& callback) override {
    callback.Run(error_, std::unique_ptr<ResourceEntry>(error_ == FILE_ERROR_OK
                                                            ? new ResourceEntry
                                                            : NULL));
  }

  void CreateDirectory(const base::FilePath& directory_path,
                       bool is_exclusive,
                       bool is_recursive,
                       const FileOperationCallback& callback) override {
    callback.Run(error_);
  }

  void FreeDiskSpaceIfNeededFor(
      int64_t num_bytes,
      const FreeDiskSpaceCallback& callback) override {
    free_disk_space_if_needed_for_num_bytes_.push_back(num_bytes);
    callback.Run(true);
  }

  std::vector<int64_t> free_disk_space_if_needed_for_num_bytes_;

 private:
  FileError error_;
};

class DownloadHandlerTestDownloadManager : public content::MockDownloadManager {
 public:
  void GetAllDownloads(
      content::DownloadManager::DownloadVector* downloads) override {
    for (auto* test_download : test_downloads_) {
      downloads->push_back(test_download);
    }
  }

  content::DownloadManager::DownloadVector test_downloads_;
};

class DownloadHandlerTestDownloadItem : public content::MockDownloadItem {
 public:
  bool IsDone() const override { return is_done_; }

  int64_t GetTotalBytes() const override { return total_bytes_; }

  int64_t GetReceivedBytes() const override { return received_bytes_; }

  bool is_done_ = false;
  int64_t total_bytes_ = 0;
  int64_t received_bytes_ = 0;
};

}  // namespace

class DownloadHandlerTest : public testing::Test {
 public:
  DownloadHandlerTest()
      : download_manager_(new DownloadHandlerTestDownloadManager) {}

  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());

    // Set expectations for download item.
    EXPECT_CALL(download_item_, GetState())
        .WillRepeatedly(testing::Return(content::DownloadItem::IN_PROGRESS));

    download_handler_.reset(new DownloadHandler(&test_file_system_));
    download_handler_->Initialize(download_manager_.get(), temp_dir_.GetPath());
    download_handler_->SetFreeDiskSpaceDelayForTesting(
        base::TimeDelta::FromMilliseconds(0));
  }

 protected:
  base::ScopedTempDir temp_dir_;
  content::TestBrowserThreadBundle thread_bundle_;
  TestingProfile profile_;
  std::unique_ptr<DownloadHandlerTestDownloadManager> download_manager_;
  std::unique_ptr<DownloadHandlerTestDownloadManager>
      incognito_download_manager_;
  DownloadHandlerTestFileSystem test_file_system_;
  std::unique_ptr<DownloadHandler> download_handler_;
  content::MockDownloadItem download_item_;
};

TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathNonDrivePath) {
  const base::FilePath non_drive_path(FILE_PATH_LITERAL("/foo/bar"));
  ASSERT_FALSE(util::IsUnderDriveMountPoint(non_drive_path));

  // Call SubstituteDriveDownloadPath()
  base::FilePath substituted_path;
  download_handler_->SubstituteDriveDownloadPath(
      non_drive_path,
      &download_item_,
      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
  content::RunAllBlockingPoolTasksUntilIdle();

  // Check the result.
  EXPECT_EQ(non_drive_path, substituted_path);
  EXPECT_FALSE(download_handler_->IsDriveDownload(&download_item_));
}

TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPath) {
  const base::FilePath drive_path =
      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");

  // Test the case that the download target directory already exists.
  test_file_system_.set_error(FILE_ERROR_OK);

  // Call SubstituteDriveDownloadPath()
  base::FilePath substituted_path;
  download_handler_->SubstituteDriveDownloadPath(
      drive_path,
      &download_item_,
      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
  content::RunAllBlockingPoolTasksUntilIdle();

  // Check the result.
  EXPECT_TRUE(temp_dir_.GetPath().IsParent(substituted_path));
  ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_));
  EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_));
}

TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathGetEntryFailure) {
  const base::FilePath drive_path =
      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");

  // Test the case that access to the download target directory failed for some
  // reason.
  test_file_system_.set_error(FILE_ERROR_FAILED);

  // Call SubstituteDriveDownloadPath()
  base::FilePath substituted_path;
  download_handler_->SubstituteDriveDownloadPath(
      drive_path,
      &download_item_,
      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
  content::RunAllBlockingPoolTasksUntilIdle();

  // Check the result.
  EXPECT_TRUE(substituted_path.empty());
}

// content::SavePackage calls SubstituteDriveDownloadPath before creating
// DownloadItem.
TEST_F(DownloadHandlerTest, SubstituteDriveDownloadPathForSavePackage) {
  const base::FilePath drive_path =
      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");
  test_file_system_.set_error(FILE_ERROR_OK);

  // Call SubstituteDriveDownloadPath()
  base::FilePath substituted_path;
  download_handler_->SubstituteDriveDownloadPath(
      drive_path,
      NULL,  // DownloadItem is not available at this moment.
      google_apis::test_util::CreateCopyResultCallback(&substituted_path));
  content::RunAllBlockingPoolTasksUntilIdle();

  // Check the result of SubstituteDriveDownloadPath().
  EXPECT_TRUE(temp_dir_.GetPath().IsParent(substituted_path));

  // |download_item_| is not a drive download yet.
  EXPECT_FALSE(download_handler_->IsDriveDownload(&download_item_));

  // Call SetDownloadParams().
  download_handler_->SetDownloadParams(drive_path, &download_item_);

  // |download_item_| is a drive download now.
  ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_));
  EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_));
}

TEST_F(DownloadHandlerTest, CheckForFileExistence) {
  const base::FilePath drive_path =
      util::GetDriveMountPointPath(&profile_).AppendASCII("test.dat");

  // Make |download_item_| a drive download.
  download_handler_->SetDownloadParams(drive_path, &download_item_);
  ASSERT_TRUE(download_handler_->IsDriveDownload(&download_item_));
  EXPECT_EQ(drive_path, download_handler_->GetTargetPath(&download_item_));

  // Test for the case when the path exists.
  test_file_system_.set_error(FILE_ERROR_OK);

  // Call CheckForFileExistence.
  bool file_exists = false;
  download_handler_->CheckForFileExistence(
      &download_item_,
      google_apis::test_util::CreateCopyResultCallback(&file_exists));
  content::RunAllBlockingPoolTasksUntilIdle();

  // Check the result.
  EXPECT_TRUE(file_exists);

  // Test for the case when the path does not exist.
  test_file_system_.set_error(FILE_ERROR_NOT_FOUND);

  // Call CheckForFileExistence again.
  download_handler_->CheckForFileExistence(
      &download_item_,
      google_apis::test_util::CreateCopyResultCallback(&file_exists));
  content::RunAllBlockingPoolTasksUntilIdle();

  // Check the result.
  EXPECT_FALSE(file_exists);
}

TEST_F(DownloadHandlerTest, FreeDiskSpace) {
  // Add a download item to download manager.
  DownloadHandlerTestDownloadItem download_item_a;
  download_item_a.is_done_ = false;
  download_item_a.total_bytes_ = 100;
  download_item_a.received_bytes_ = 10;
  download_manager_->test_downloads_.push_back(&download_item_a);

  // Free disk space for download_item_a.
  download_handler_->FreeDiskSpaceIfNeededImmediately();
  ASSERT_EQ(1u,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_[0]);

  // Confirm that FreeDiskSpaceIfNeeded is rate limited by calling it twice.
  download_handler_->FreeDiskSpaceIfNeeded();
  download_handler_->FreeDiskSpaceIfNeeded();
  ASSERT_EQ(1u,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());

  download_item_a.received_bytes_ = 20;

  base::RunLoop().RunUntilIdle();
  ASSERT_EQ(2u,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_[1]);

  // Observe incognito download manager and add another download item.
  // FreeDiskSpace should be called with considering both download items.
  incognito_download_manager_.reset(new DownloadHandlerTestDownloadManager);
  download_handler_->ObserveIncognitoDownloadManager(
      incognito_download_manager_.get());

  DownloadHandlerTestDownloadItem download_item_b;
  download_item_b.is_done_ = false;
  download_item_b.total_bytes_ = 200;
  download_item_b.received_bytes_ = 0;
  incognito_download_manager_->test_downloads_.push_back(&download_item_b);

  download_item_a.received_bytes_ = 30;

  download_handler_->FreeDiskSpaceIfNeededImmediately();
  ASSERT_EQ(3u,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_ +
                download_item_b.total_bytes_ - download_item_b.received_bytes_,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_[2]);

  // Free disk space after making both items completed. In this case
  // FreeDiskSpace should be called with 0 byte to keep
  // drive::internal::kMinFreeSpaceInBytes.
  download_item_a.is_done_ = true;
  download_item_b.is_done_ = true;

  download_handler_->FreeDiskSpaceIfNeeded();
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(4u,
            test_file_system_.free_disk_space_if_needed_for_num_bytes_.size());
  ASSERT_EQ(0, test_file_system_.free_disk_space_if_needed_for_num_bytes_[3]);
}

TEST_F(DownloadHandlerTest, CalculateRequestSpace) {
  DownloadHandlerTestDownloadItem download_item_a;
  download_item_a.is_done_ = false;
  download_item_a.total_bytes_ = 100;
  download_item_a.received_bytes_ = 0;

  DownloadHandlerTestDownloadItem download_item_b;
  download_item_b.is_done_ = false;
  download_item_b.total_bytes_ = 200;
  download_item_b.received_bytes_ = 10;

  content::DownloadManager::DownloadVector downloads;
  downloads.push_back(&download_item_a);
  downloads.push_back(&download_item_b);

  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_ +
                download_item_b.total_bytes_ - download_item_b.received_bytes_,
            download_handler_->CalculateRequestSpace(downloads));

  download_item_a.received_bytes_ = 10;

  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_ +
                download_item_b.total_bytes_ - download_item_b.received_bytes_,
            download_handler_->CalculateRequestSpace(downloads));

  download_item_b.is_done_ = true;

  // Since download_item_b is completed, it shouldn't be counted.
  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
            download_handler_->CalculateRequestSpace(downloads));

  // Add unknown size download item.
  DownloadHandlerTestDownloadItem download_item_c;
  download_item_c.is_done_ = false;
  download_item_c.total_bytes_ = 0;
  downloads.push_back(&download_item_c);

  // Unknown size download should be counted as 0 byte.
  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
            download_handler_->CalculateRequestSpace(downloads));

  // Add another unknown size download item.
  DownloadHandlerTestDownloadItem download_item_d;
  download_item_d.is_done_ = false;
  download_item_d.total_bytes_ = 0;
  downloads.push_back(&download_item_d);

  // Unknown size downloads should be counted as 0 byte.
  ASSERT_EQ(download_item_a.total_bytes_ - download_item_a.received_bytes_,
            download_handler_->CalculateRequestSpace(downloads));
}

}  // namespace drive
