// Copyright 2014 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/fileapi/fileapi_worker.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/files/file_util.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/browser/chromeos/drive/dummy_file_system.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 fileapi_internal {
namespace {

// Increments |num_called| for checking how many times the closure is called.
void Increment(int* num_called) {
  ++*num_called;
}

// Returns the |instance| as is.
FileSystemInterface* GetFileSystem(FileSystemInterface* instance) {
  return instance;
}

// A test file system that always returns |local_file_path|. For testing
// purpose, it checks if |open_mode| is the expected value, and record if the
// close callback is called.
class TestFileSystemForOpenFile : public DummyFileSystem {
 public:
  TestFileSystemForOpenFile(const base::FilePath& local_file_path,
                            OpenMode expected_open_mode)
      : local_file_path_(local_file_path),
        expected_open_mode_(expected_open_mode),
        closed_(false) {
  }

  void OpenFile(const base::FilePath& file_path,
                OpenMode open_mode,
                const std::string& mime_type,
                const drive::OpenFileCallback& callback) override {
    EXPECT_EQ(expected_open_mode_, open_mode);

    callback.Run(
        FILE_ERROR_OK,
        local_file_path_,
        base::Bind(&TestFileSystemForOpenFile::Close, base::Unretained(this)));
  }

  void Close() {
    closed_ = true;
  }

  bool closed() const { return closed_; }

 private:
  const base::FilePath local_file_path_;
  const OpenMode expected_open_mode_;
  bool closed_;
};

// Helper function of testing OpenFile() for write access. It checks that the
// file handle correctly writes to the expected file.
void VerifyWrite(
    int64 expected_size,
    const base::FilePath& expected_written_path,
    const std::string& write_data,
    base::File file,
    const base::Closure& close_callback) {
  // Check that the file was properly opened.
  EXPECT_TRUE(file.IsValid());
  EXPECT_FALSE(close_callback.is_null());

  // Check that the file has the expected length (i.e., truncated or not)
  base::File::Info info;
  EXPECT_TRUE(file.GetInfo(&info));
  EXPECT_EQ(expected_size, info.size);

  // Write some data.
  const int data_size = static_cast<int>(write_data.size());
  EXPECT_EQ(data_size, file.Write(0, write_data.c_str(), data_size));
  EXPECT_TRUE(file.SetLength(data_size));

  // Close.
  file.Close();
  close_callback.Run();

  // Checks that the written content goes to |expected_written_path|. I.e.,
  // the |file| handle is pointing to the file.
  std::string written;
  EXPECT_TRUE(base::ReadFileToString(expected_written_path, &written));
  EXPECT_EQ(write_data, written);
}

// Helper function of testing OpenFile() for read access. It checks that the
// file is readable and contains |expected_data|.
void VerifyRead(const std::string& expected_data,
                base::File file,
                const base::Closure& close_callback) {
  // Check that the file was properly opened.
  EXPECT_TRUE(file.IsValid());
  EXPECT_FALSE(close_callback.is_null());

  // Check that the file has the expected content.
  const int data_size = static_cast<int>(expected_data.size());
  base::File::Info info;
  EXPECT_TRUE(file.GetInfo(&info));
  EXPECT_EQ(data_size, info.size);

  std::vector<char> buffer(data_size);
  EXPECT_EQ(data_size, file.Read(0, buffer.data(), data_size));
  EXPECT_EQ(expected_data, std::string(buffer.begin(), buffer.end()));

  // Close.
  file.Close();
  close_callback.Run();
}

}  // namespace

class FileApiWorkerTest : public testing::Test {
 private:
  content::TestBrowserThreadBundle thread_bundle_;
};

TEST_F(FileApiWorkerTest, RunFileSystemCallbackSuccess) {
  DummyFileSystem dummy_file_system;

  FileSystemInterface* file_system = NULL;
  RunFileSystemCallback(
      base::Bind(&GetFileSystem, &dummy_file_system),
      google_apis::test_util::CreateCopyResultCallback(&file_system),
      base::Closure());

  EXPECT_EQ(&dummy_file_system, file_system);
}

TEST_F(FileApiWorkerTest, RunFileSystemCallbackFail) {
  FileSystemInterface* file_system = NULL;

  // Make sure on_error_callback is called if file_system_getter returns NULL.
  int num_called = 0;
  RunFileSystemCallback(
      base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(NULL)),
      google_apis::test_util::CreateCopyResultCallback(&file_system),
      base::Bind(&Increment, &num_called));
  EXPECT_EQ(1, num_called);

  // Just make sure this null |on_error_callback| doesn't cause a crash.
  RunFileSystemCallback(
      base::Bind(&GetFileSystem, static_cast<FileSystemInterface*>(NULL)),
      google_apis::test_util::CreateCopyResultCallback(&file_system),
      base::Closure());
}

TEST_F(FileApiWorkerTest, OpenFileForCreateWrite) {
  const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
  const std::string kWriteData = "byebye";

  base::FilePath temp_path;
  base::CreateTemporaryFile(&temp_path);

  // CREATE => CREATE (fails if file exists.)
  TestFileSystemForOpenFile file_system(temp_path, CREATE_FILE);
  const int64 kExpectedSize = 0;

  OpenFile(kDummyPath,
           base::File::FLAG_CREATE | base::File::FLAG_WRITE,
           base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
           &file_system);
  content::RunAllBlockingPoolTasksUntilIdle();
  EXPECT_TRUE(file_system.closed());
}

TEST_F(FileApiWorkerTest, OpenFileForOpenAlwaysWrite) {
  const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
  const std::string kWriteData = "byebye";
  const std::string kInitialData = "hello";

  base::FilePath temp_path;
  base::CreateTemporaryFile(&temp_path);
  google_apis::test_util::WriteStringToFile(temp_path, kInitialData);

  // OPEN_ALWAYS => OPEN_OR_CREATE (success whether file exists or not.)
  // No truncation should take place.
  TestFileSystemForOpenFile file_system(temp_path, OPEN_OR_CREATE_FILE);
  const int64 kExpectedSize = static_cast<int64>(kInitialData.size());

  OpenFile(kDummyPath,
           base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE,
           base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
           &file_system);
  content::RunAllBlockingPoolTasksUntilIdle();
  EXPECT_TRUE(file_system.closed());
}

TEST_F(FileApiWorkerTest, OpenFileForOpenTruncatedWrite) {
  const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
  const std::string kInitialData = "hello";
  const std::string kWriteData = "byebye";

  base::FilePath temp_path;
  base::CreateTemporaryFile(&temp_path);
  google_apis::test_util::WriteStringToFile(temp_path, kInitialData);

  // OPEN_TRUNCATED => OPEN (failure when the file did not exist.)
  // It should truncate the file before passing to the callback.
  TestFileSystemForOpenFile file_system(temp_path, OPEN_FILE);
  const int64 kExpectedSize = 0;

  OpenFile(kDummyPath,
           base::File::FLAG_OPEN_TRUNCATED | base::File::FLAG_WRITE,
           base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
           &file_system);
  content::RunAllBlockingPoolTasksUntilIdle();
  EXPECT_TRUE(file_system.closed());
}

TEST_F(FileApiWorkerTest, OpenFileForOpenCreateAlwaysWrite) {
  const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
  const std::string kInitialData = "hello";
  const std::string kWriteData = "byebye";

  base::FilePath temp_path;
  base::CreateTemporaryFile(&temp_path);
  google_apis::test_util::WriteStringToFile(temp_path, kInitialData);

  // CREATE_ALWAYS => OPEN_OR_CREATE (success whether file exists or not.)
  // It should truncate the file before passing to the callback.
  TestFileSystemForOpenFile file_system(temp_path, OPEN_OR_CREATE_FILE);
  const int64 kExpectedSize = 0;

  OpenFile(kDummyPath,
           base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE,
           base::Bind(&VerifyWrite, kExpectedSize, temp_path, kWriteData),
           &file_system);
  content::RunAllBlockingPoolTasksUntilIdle();
  EXPECT_TRUE(file_system.closed());
}

TEST_F(FileApiWorkerTest, OpenFileForOpenRead) {
  const base::FilePath kDummyPath = base::FilePath::FromUTF8Unsafe("whatever");
  const std::string kInitialData = "hello";

  base::FilePath temp_path;
  base::CreateTemporaryFile(&temp_path);
  google_apis::test_util::WriteStringToFile(temp_path, kInitialData);

  // OPEN => OPEN (failure when the file did not exist.)
  TestFileSystemForOpenFile file_system(temp_path, OPEN_FILE);

  OpenFile(kDummyPath,
           base::File::FLAG_OPEN | base::File::FLAG_READ,
           base::Bind(&VerifyRead, kInitialData),
           &file_system);
  content::RunAllBlockingPoolTasksUntilIdle();
  EXPECT_TRUE(file_system.closed());
}

}  // namespace fileapi_internal
}  // namespace drive
