// Copyright (c) 2011 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 "webkit/fileapi/file_system_operation.h"

#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/scoped_temp_dir.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/fileapi/file_system_callback_dispatcher.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_file_util.h"
#include "webkit/fileapi/file_system_mount_point_provider.h"
#include "webkit/fileapi/file_system_operation.h"
#include "webkit/fileapi/file_system_quota_util.h"
#include "webkit/fileapi/file_system_test_helper.h"
#include "webkit/fileapi/file_system_util.h"
#include "webkit/fileapi/local_file_util.h"
#include "webkit/fileapi/quota_file_util.h"
#include "webkit/quota/quota_manager.h"

using quota::QuotaClient;
using quota::QuotaManager;
using quota::QuotaManagerProxy;
using quota::StorageType;

namespace fileapi {

namespace {

const int kFileOperationStatusNotSet = 1;

class MockQuotaManager : public QuotaManager {
 public:
  MockQuotaManager(const FilePath& base_dir,
                   const GURL& origin,
                   StorageType type)
    : QuotaManager(false /* is_incognito */, base_dir,
                   base::MessageLoopProxy::current(),
                   base::MessageLoopProxy::current(),
                   NULL),
      origin_(origin),
      type_(type),
      usage_(0),
      quota_(kint64max),
      accessed_(0) {}

  virtual void GetUsageAndQuota(
      const GURL& origin, quota::StorageType type,
      const GetUsageAndQuotaCallback& callback) OVERRIDE {
    EXPECT_EQ(origin_, origin);
    EXPECT_EQ(type_, type);
    callback.Run(quota::kQuotaStatusOk, usage_, quota_);
  }

 private:
  friend class MockQuotaManagerProxy;
  void SetQuota(const GURL& origin, StorageType type, int64 quota) {
    EXPECT_EQ(origin_, origin);
    EXPECT_EQ(type_, type);
    quota_ = quota;
  }

  void RecordStorageAccessed(const GURL& origin, StorageType type) {
    EXPECT_EQ(origin_, origin);
    EXPECT_EQ(type_, type);
    ++accessed_;
  }

  void UpdateUsage(const GURL& origin, StorageType type, int64 delta) {
    EXPECT_EQ(origin_, origin);
    EXPECT_EQ(type_, type);
    usage_ += delta;
  }

  const GURL& origin_;
  const StorageType type_;
  int64 usage_;
  int64 quota_;
  int accessed_;
};

class MockQuotaManagerProxy : public QuotaManagerProxy {
 public:
  explicit MockQuotaManagerProxy(QuotaManager* quota_manager)
      : QuotaManagerProxy(quota_manager,
                          base::MessageLoopProxy::current()),
        registered_client_(NULL) {
  }

  virtual ~MockQuotaManagerProxy() {
    EXPECT_FALSE(registered_client_);
  }

  virtual void RegisterClient(QuotaClient* client) OVERRIDE {
    EXPECT_FALSE(registered_client_);
    registered_client_ = client;
  }

  void SimulateQuotaManagerDestroyed() {
    if (registered_client_) {
      // We cannot call this in the destructor as the client (indirectly)
      // holds a refptr of the proxy.
      registered_client_->OnQuotaManagerDestroyed();
      registered_client_ = NULL;
    }
  }

  // We don't mock them.
  virtual void NotifyOriginInUse(const GURL& origin) OVERRIDE {}
  virtual void NotifyOriginNoLongerInUse(const GURL& origin) OVERRIDE {}

  virtual void NotifyStorageAccessed(QuotaClient::ID client_id,
                                     const GURL& origin,
                                     StorageType type) OVERRIDE {
    mock_manager()->RecordStorageAccessed(origin, type);
  }

  virtual void NotifyStorageModified(QuotaClient::ID client_id,
                                     const GURL& origin,
                                     StorageType type,
                                     int64 delta) OVERRIDE {
    mock_manager()->UpdateUsage(origin, type, delta);
  }

  int storage_accessed_count() const {
    return mock_manager()->accessed_;
  }

  void SetQuota(const GURL& origin, StorageType type, int64 quota) {
    mock_manager()->SetQuota(origin, type, quota);
  }

 private:
  MockQuotaManager* mock_manager() const {
    return static_cast<MockQuotaManager*>(quota_manager());
  }
  QuotaClient* registered_client_;
};

FilePath ASCIIToFilePath(const std::string& str) {
  return FilePath().AppendASCII(str);
}

}  // namespace (anonymous)

// Test class for FileSystemOperation.  Note that this just tests low-level
// operations but doesn't test OpenFileSystem.
class FileSystemOperationTest : public testing::Test {
 public:
  FileSystemOperationTest()
      : status_(kFileOperationStatusNotSet),
        local_file_util_(new LocalFileUtil(QuotaFileUtil::CreateDefault())) {
    EXPECT_TRUE(base_.CreateUniqueTempDir());
  }

  FileSystemOperation* operation();

  void set_status(int status) { status_ = status; }
  int status() const { return status_; }
  void set_info(const base::PlatformFileInfo& info) { info_ = info; }
  const base::PlatformFileInfo& info() const { return info_; }
  void set_path(const FilePath& path) { path_ = path; }
  const FilePath& path() const { return path_; }
  void set_entries(const std::vector<base::FileUtilProxy::Entry>& entries) {
    entries_ = entries;
  }
  const std::vector<base::FileUtilProxy::Entry>& entries() const {
    return entries_;
  }

  virtual void SetUp();
  virtual void TearDown();

 protected:
  // Common temp base for nondestructive uses.
  ScopedTempDir base_;

  MockQuotaManagerProxy* quota_manager_proxy() {
    return static_cast<MockQuotaManagerProxy*>(quota_manager_proxy_.get());
  }

  GURL URLForPath(const FilePath& path) const {
    return test_helper_.GetURLForPath(path);
  }

  FilePath PlatformPath(const FilePath& virtual_path) {
    return test_helper_.GetLocalPath(virtual_path);
  }

  bool VirtualFileExists(const FilePath& virtual_path) {
    return file_util::PathExists(PlatformPath(virtual_path)) &&
        !file_util::DirectoryExists(PlatformPath(virtual_path));
  }

  bool VirtualDirectoryExists(const FilePath& virtual_path) {
    return file_util::DirectoryExists(PlatformPath(virtual_path));
  }

  FilePath CreateVirtualDirectory(const char* virtual_path_string) {
    FilePath virtual_path(ASCIIToFilePath(virtual_path_string));
    file_util::CreateDirectory(PlatformPath(virtual_path));
    return virtual_path;
  }

  FilePath CreateVirtualDirectoryInDir(const char* virtual_path_string,
                                       const FilePath& virtual_dir_path) {
    FilePath virtual_path(virtual_dir_path.AppendASCII(virtual_path_string));
    file_util::CreateDirectory(PlatformPath(virtual_path));
    return virtual_path;
  }

  FilePath CreateVirtualTemporaryFileInDir(const FilePath& virtual_dir_path) {
    FilePath absolute_dir_path(PlatformPath(virtual_dir_path));
    FilePath absolute_file_path;
    if (file_util::CreateTemporaryFileInDir(absolute_dir_path,
                                            &absolute_file_path))
      return virtual_dir_path.Append(absolute_file_path.BaseName());
    else
      return FilePath();
  }

  FilePath CreateVirtualTemporaryDirInDir(const FilePath& virtual_dir_path) {
    FilePath absolute_parent_dir_path(PlatformPath(virtual_dir_path));
    FilePath absolute_child_dir_path;
    if (file_util::CreateTemporaryDirInDir(absolute_parent_dir_path,
                                           FILE_PATH_LITERAL(""),
                                           &absolute_child_dir_path))
      return virtual_dir_path.Append(absolute_child_dir_path.BaseName());
    else
      return FilePath();
  }

  FilePath CreateVirtualTemporaryDir() {
    return CreateVirtualTemporaryDirInDir(FilePath());
  }

  FileSystemTestOriginHelper test_helper_;

  // For post-operation status.
  int status_;
  base::PlatformFileInfo info_;
  FilePath path_;
  std::vector<base::FileUtilProxy::Entry> entries_;

 private:
  scoped_ptr<LocalFileUtil> local_file_util_;
  scoped_refptr<QuotaManager> quota_manager_;
  scoped_refptr<QuotaManagerProxy> quota_manager_proxy_;
  DISALLOW_COPY_AND_ASSIGN(FileSystemOperationTest);
};

namespace {

class MockDispatcher : public FileSystemCallbackDispatcher {
 public:
  explicit MockDispatcher(FileSystemOperationTest* test) : test_(test) { }

  virtual void DidFail(base::PlatformFileError status) {
    test_->set_status(status);
  }

  virtual void DidSucceed() {
    test_->set_status(base::PLATFORM_FILE_OK);
  }

  virtual void DidReadMetadata(
      const base::PlatformFileInfo& info,
      const FilePath& platform_path) {
    test_->set_info(info);
    test_->set_path(platform_path);
    test_->set_status(base::PLATFORM_FILE_OK);
  }

  virtual void DidReadDirectory(
      const std::vector<base::FileUtilProxy::Entry>& entries,
      bool /* has_more */) {
    test_->set_entries(entries);
  }

  virtual void DidOpenFileSystem(const std::string&, const GURL&) {
    NOTREACHED();
  }

  virtual void DidWrite(int64 bytes, bool complete) {
    NOTREACHED();
  }

 private:
  FileSystemOperationTest* test_;
};

}  // namespace (anonymous)

void FileSystemOperationTest::SetUp() {
  FilePath base_dir = base_.path().AppendASCII("filesystem");
  quota_manager_ = new MockQuotaManager(
      base_dir, test_helper_.origin(), test_helper_.storage_type());
  quota_manager_proxy_ = new MockQuotaManagerProxy(quota_manager_.get());
  test_helper_.SetUp(base_dir,
                     false /* incognito */,
                     false /* unlimited quota */,
                     quota_manager_proxy_.get(),
                     local_file_util_.get());
}

void FileSystemOperationTest::TearDown() {
  // Let the client go away before dropping a ref of the quota manager proxy.
  quota_manager_proxy()->SimulateQuotaManagerDestroyed();
  quota_manager_ = NULL;
  quota_manager_proxy_ = NULL;
  test_helper_.TearDown();
}

FileSystemOperation* FileSystemOperationTest::operation() {
  return test_helper_.NewOperation(new MockDispatcher(this));
}

TEST_F(FileSystemOperationTest, TestMoveFailureSrcDoesntExist) {
  GURL src(URLForPath(FilePath(FILE_PATH_LITERAL("a"))));
  GURL dest(URLForPath(FilePath(FILE_PATH_LITERAL("b"))));
  operation()->Move(src, dest);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
}

TEST_F(FileSystemOperationTest, TestMoveFailureContainsPath) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDirInDir(src_dir_path));
  operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status());
}

TEST_F(FileSystemOperationTest, TestMoveFailureSrcDirExistsDestFile) {
  // Src exists and is dir. Dest is a file.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_file_path(CreateVirtualTemporaryFileInDir(dest_dir_path));

  operation()->Move(URLForPath(src_dir_path), URLForPath(dest_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status());
}

TEST_F(FileSystemOperationTest, TestMoveFailureSrcFileExistsDestNonEmptyDir) {
  // Src exists and is a directory. Dest is a non-empty directory.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath child_file_path(CreateVirtualTemporaryFileInDir(dest_dir_path));

  operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, status());
}

TEST_F(FileSystemOperationTest, TestMoveFailureSrcFileExistsDestDir) {
  // Src exists and is a file. Dest is a directory.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath src_file_path(CreateVirtualTemporaryFileInDir(src_dir_path));
  FilePath dest_dir_path(CreateVirtualTemporaryDir());

  operation()->Move(URLForPath(src_file_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status());
}

TEST_F(FileSystemOperationTest, TestMoveFailureDestParentDoesntExist) {
  // Dest. parent path does not exist.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath nonexisting_file = FilePath(FILE_PATH_LITERAL("NonexistingDir")).
      Append(FILE_PATH_LITERAL("NonexistingFile"));

  operation()->Move(URLForPath(src_dir_path), URLForPath(nonexisting_file));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
}

TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndOverwrite) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath src_file_path(CreateVirtualTemporaryFileInDir(src_dir_path));
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_file_path(CreateVirtualTemporaryFileInDir(dest_dir_path));

  operation()->Move(URLForPath(src_file_path), URLForPath(dest_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualFileExists(dest_file_path));

  // Move is considered 'write' access (for both side), and won't be counted
  // as read access.
  EXPECT_EQ(0, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestMoveSuccessSrcFileAndNew) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath src_file_path(CreateVirtualTemporaryFileInDir(src_dir_path));
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_file_path(dest_dir_path.Append(FILE_PATH_LITERAL("NewFile")));

  operation()->Move(URLForPath(src_file_path), URLForPath(dest_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualFileExists(dest_file_path));
}

TEST_F(FileSystemOperationTest, TestMoveSuccessSrcDirAndOverwrite) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDir());

  operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_FALSE(VirtualDirectoryExists(src_dir_path));

  // Make sure we've overwritten but not moved the source under the |dest_dir|.
  EXPECT_TRUE(VirtualDirectoryExists(dest_dir_path));
  EXPECT_FALSE(VirtualDirectoryExists(
      dest_dir_path.Append(src_dir_path.BaseName())));
}

TEST_F(FileSystemOperationTest, TestMoveSuccessSrcDirAndNew) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_parent_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_child_dir_path(dest_parent_dir_path.
      Append(FILE_PATH_LITERAL("NewDirectory")));

  operation()->Move(URLForPath(src_dir_path), URLForPath(dest_child_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_FALSE(VirtualDirectoryExists(src_dir_path));
  EXPECT_TRUE(VirtualDirectoryExists(dest_child_dir_path));
}

TEST_F(FileSystemOperationTest, TestMoveSuccessSrcDirRecursive) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath child_dir_path(CreateVirtualTemporaryDirInDir(src_dir_path));
  FilePath grandchild_file_path(
      CreateVirtualTemporaryFileInDir(child_dir_path));

  FilePath dest_dir_path(CreateVirtualTemporaryDir());

  operation()->Move(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualDirectoryExists(dest_dir_path.Append(
      child_dir_path.BaseName())));
  EXPECT_TRUE(VirtualFileExists(dest_dir_path.Append(
      child_dir_path.BaseName()).Append(
      grandchild_file_path.BaseName())));
}

TEST_F(FileSystemOperationTest, TestCopyFailureSrcDoesntExist) {
  operation()->Copy(URLForPath(FilePath(FILE_PATH_LITERAL("a"))),
                    URLForPath(FilePath(FILE_PATH_LITERAL("b"))));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
}

TEST_F(FileSystemOperationTest, TestCopyFailureContainsPath) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDirInDir(src_dir_path));
  operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status());
}

TEST_F(FileSystemOperationTest, TestCopyFailureSrcDirExistsDestFile) {
  // Src exists and is dir. Dest is a file.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_file_path(CreateVirtualTemporaryFileInDir(dest_dir_path));

  operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status());
}

TEST_F(FileSystemOperationTest, TestCopyFailureSrcFileExistsDestNonEmptyDir) {
  // Src exists and is a directory. Dest is a non-empty directory.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath child_file_path(CreateVirtualTemporaryFileInDir(dest_dir_path));

  operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY, status());
}

TEST_F(FileSystemOperationTest, TestCopyFailureSrcFileExistsDestDir) {
  // Src exists and is a file. Dest is a directory.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath src_file_path(CreateVirtualTemporaryFileInDir(src_dir_path));
  FilePath dest_dir_path(CreateVirtualTemporaryDir());

  operation()->Copy(URLForPath(src_file_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION, status());
}

TEST_F(FileSystemOperationTest, TestCopyFailureDestParentDoesntExist) {
  // Dest. parent path does not exist.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath nonexisting_path = FilePath(FILE_PATH_LITERAL("DontExistDir"));
  file_util::EnsureEndsWithSeparator(&nonexisting_path);
  FilePath nonexisting_file_path(nonexisting_path.Append(
      FILE_PATH_LITERAL("DontExistFile")));

  operation()->Copy(URLForPath(src_dir_path),
                    URLForPath(nonexisting_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
}

TEST_F(FileSystemOperationTest, TestCopyFailureByQuota) {
  base::PlatformFileInfo info;

  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath src_file_path(CreateVirtualTemporaryFileInDir(src_dir_path));
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_file_path(dest_dir_path.Append(FILE_PATH_LITERAL("NewFile")));

  quota_manager_proxy()->SetQuota(test_helper_.origin(),
                                  test_helper_.storage_type(),
                                  11);

  operation()->Truncate(URLForPath(src_file_path), 6);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());

  EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(src_file_path), &info));
  EXPECT_EQ(6, info.size);

  operation()->Copy(URLForPath(src_file_path), URLForPath(dest_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status());
  EXPECT_FALSE(VirtualFileExists(dest_file_path));
}

TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndOverwrite) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath src_file_path(CreateVirtualTemporaryFileInDir(src_dir_path));
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_file_path(CreateVirtualTemporaryFileInDir(dest_dir_path));

  operation()->Copy(URLForPath(src_file_path), URLForPath(dest_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualFileExists(dest_file_path));
  EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestCopySuccessSrcFileAndNew) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath src_file_path(CreateVirtualTemporaryFileInDir(src_dir_path));
  FilePath dest_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_file_path(dest_dir_path.Append(FILE_PATH_LITERAL("NewFile")));

  operation()->Copy(URLForPath(src_file_path), URLForPath(dest_file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualFileExists(dest_file_path));
  EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndOverwrite) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_dir_path(CreateVirtualTemporaryDir());

  operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());

  // Make sure we've overwritten but not copied the source under the |dest_dir|.
  EXPECT_TRUE(VirtualDirectoryExists(dest_dir_path));
  EXPECT_FALSE(VirtualDirectoryExists(
      dest_dir_path.Append(src_dir_path.BaseName())));
  EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirAndNew) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_parent_dir_path(CreateVirtualTemporaryDir());
  FilePath dest_child_dir_path(dest_parent_dir_path.
      Append(FILE_PATH_LITERAL("NewDirectory")));

  operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_child_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualDirectoryExists(dest_child_dir_path));
  EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestCopySuccessSrcDirRecursive) {
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  FilePath child_dir_path(CreateVirtualTemporaryDirInDir(src_dir_path));
  FilePath grandchild_file_path(
      CreateVirtualTemporaryFileInDir(child_dir_path));

  FilePath dest_dir_path(CreateVirtualTemporaryDir());

  operation()->Copy(URLForPath(src_dir_path), URLForPath(dest_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualDirectoryExists(dest_dir_path.Append(
      child_dir_path.BaseName())));
  EXPECT_TRUE(VirtualFileExists(dest_dir_path.Append(
      child_dir_path.BaseName()).Append(
      grandchild_file_path.BaseName())));
  EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestCreateFileFailure) {
  // Already existing file and exclusive true.
  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));
  operation()->CreateFile(URLForPath(file_path), true);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status());
}

TEST_F(FileSystemOperationTest, TestCreateFileSuccessFileExists) {
  // Already existing file and exclusive false.
  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));
  operation()->CreateFile(URLForPath(file_path), false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualFileExists(file_path));
}

TEST_F(FileSystemOperationTest, TestCreateFileSuccessExclusive) {
  // File doesn't exist but exclusive is true.
  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(dir_path.Append(FILE_PATH_LITERAL("FileDoesntExist")));
  operation()->CreateFile(URLForPath(file_path), true);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualFileExists(file_path));
}

TEST_F(FileSystemOperationTest, TestCreateFileSuccessFileDoesntExist) {
  // Non existing file.
  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(dir_path.Append(FILE_PATH_LITERAL("FileDoesntExist")));
  operation()->CreateFile(URLForPath(file_path), false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
}

TEST_F(FileSystemOperationTest,
       TestCreateDirFailureDestParentDoesntExist) {
  // Dest. parent path does not exist.
  FilePath nonexisting_path(FilePath(
      FILE_PATH_LITERAL("DirDoesntExist")));
  FilePath nonexisting_file_path(nonexisting_path.Append(
      FILE_PATH_LITERAL("FileDoesntExist")));
  operation()->CreateDirectory(
      URLForPath(nonexisting_file_path), false, false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
}

TEST_F(FileSystemOperationTest, TestCreateDirFailureDirExists) {
  // Exclusive and dir existing at path.
  FilePath src_dir_path(CreateVirtualTemporaryDir());
  operation()->CreateDirectory(URLForPath(src_dir_path), true, false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status());
}

TEST_F(FileSystemOperationTest, TestCreateDirFailureFileExists) {
  // Exclusive true and file existing at path.
  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));
  operation()->CreateDirectory(URLForPath(file_path), true, false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_EXISTS, status());
}

TEST_F(FileSystemOperationTest, TestCreateDirSuccess) {
  // Dir exists and exclusive is false.
  FilePath dir_path(CreateVirtualTemporaryDir());
  operation()->CreateDirectory(URLForPath(dir_path), false, false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());

  // Dir doesn't exist.
  FilePath nonexisting_dir_path(FilePath(
      FILE_PATH_LITERAL("nonexistingdir")));
  operation()->CreateDirectory(
      URLForPath(nonexisting_dir_path), false, false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualDirectoryExists(nonexisting_dir_path));
}

TEST_F(FileSystemOperationTest, TestCreateDirSuccessExclusive) {
  // Dir doesn't exist.
  FilePath nonexisting_dir_path(FilePath(
      FILE_PATH_LITERAL("nonexistingdir")));

  operation()->CreateDirectory(
      URLForPath(nonexisting_dir_path), true, false);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(VirtualDirectoryExists(nonexisting_dir_path));
}

TEST_F(FileSystemOperationTest, TestExistsAndMetadataFailure) {
  FilePath nonexisting_dir_path(FilePath(
      FILE_PATH_LITERAL("nonexistingdir")));
  operation()->GetMetadata(URLForPath(nonexisting_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());

  operation()->FileExists(URLForPath(nonexisting_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());

  file_util::EnsureEndsWithSeparator(&nonexisting_dir_path);
  operation()->DirectoryExists(URLForPath(nonexisting_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
}

TEST_F(FileSystemOperationTest, TestExistsAndMetadataSuccess) {
  FilePath dir_path(CreateVirtualTemporaryDir());
  int read_access = 0;

  operation()->DirectoryExists(URLForPath(dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  ++read_access;

  operation()->GetMetadata(URLForPath(dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_TRUE(info().is_directory);
  EXPECT_EQ(PlatformPath(dir_path), path());
  ++read_access;

  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));
  operation()->FileExists(URLForPath(file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  ++read_access;

  operation()->GetMetadata(URLForPath(file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_FALSE(info().is_directory);
  EXPECT_EQ(PlatformPath(file_path), path());
  ++read_access;

  EXPECT_EQ(read_access, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestTypeMismatchErrors) {
  FilePath dir_path(CreateVirtualTemporaryDir());
  operation()->FileExists(URLForPath(dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_FILE, status());

  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));
  ASSERT_FALSE(file_path.empty());
  operation()->DirectoryExists(URLForPath(file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY, status());
}

TEST_F(FileSystemOperationTest, TestReadDirFailure) {
  // Path doesn't exist
  FilePath nonexisting_dir_path(FilePath(
      FILE_PATH_LITERAL("NonExistingDir")));
  file_util::EnsureEndsWithSeparator(&nonexisting_dir_path);
  operation()->ReadDirectory(URLForPath(nonexisting_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());

  // File exists.
  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));
  operation()->ReadDirectory(URLForPath(file_path));
  MessageLoop::current()->RunAllPending();
  // TODO(kkanetkar) crbug.com/54309 to change the error code.
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());
}

TEST_F(FileSystemOperationTest, TestReadDirSuccess) {
  //      parent_dir
  //       |       |
  //  child_dir  child_file
  // Verify reading parent_dir.
  FilePath parent_dir_path(CreateVirtualTemporaryDir());
  FilePath child_file_path(CreateVirtualTemporaryFileInDir(parent_dir_path));
  FilePath child_dir_path(CreateVirtualTemporaryDirInDir(parent_dir_path));
  ASSERT_FALSE(child_dir_path.empty());

  operation()->ReadDirectory(URLForPath(parent_dir_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(kFileOperationStatusNotSet, status());
  EXPECT_EQ(2u, entries().size());

  for (size_t i = 0; i < entries().size(); ++i) {
    if (entries()[i].is_directory) {
      EXPECT_EQ(child_dir_path.BaseName().value(),
                entries()[i].name);
    } else {
      EXPECT_EQ(child_file_path.BaseName().value(),
                entries()[i].name);
    }
  }
  EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestRemoveFailure) {
  // Path doesn't exist.
  FilePath nonexisting_path(FilePath(
      FILE_PATH_LITERAL("NonExistingDir")));
  file_util::EnsureEndsWithSeparator(&nonexisting_path);

  operation()->Remove(URLForPath(nonexisting_path), false /* recursive */);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_FOUND, status());

  // It's an error to try to remove a non-empty directory if recursive flag
  // is false.
  //      parent_dir
  //       |       |
  //  child_dir  child_file
  // Verify deleting parent_dir.
  FilePath parent_dir_path(CreateVirtualTemporaryDir());
  FilePath child_file_path(CreateVirtualTemporaryFileInDir(parent_dir_path));
  FilePath child_dir_path(CreateVirtualTemporaryDirInDir(parent_dir_path));
  ASSERT_FALSE(child_dir_path.empty());

  operation()->Remove(URLForPath(parent_dir_path), false /* recursive */);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NOT_EMPTY,
            status());
}

TEST_F(FileSystemOperationTest, TestRemoveSuccess) {
  FilePath empty_dir_path(CreateVirtualTemporaryDir());
  EXPECT_TRUE(VirtualDirectoryExists(empty_dir_path));

  operation()->Remove(URLForPath(empty_dir_path), false /* recursive */);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_FALSE(VirtualDirectoryExists(empty_dir_path));

  // Removing a non-empty directory with recursive flag == true should be ok.
  //      parent_dir
  //       |       |
  //  child_dir  child_file
  // Verify deleting parent_dir.
  FilePath parent_dir_path(CreateVirtualTemporaryDir());
  FilePath child_file_path(CreateVirtualTemporaryFileInDir(parent_dir_path));
  FilePath child_dir_path(CreateVirtualTemporaryDirInDir(parent_dir_path));
  ASSERT_FALSE(child_dir_path.empty());

  operation()->Remove(URLForPath(parent_dir_path), true /* recursive */);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_FALSE(VirtualDirectoryExists(parent_dir_path));

  // Remove is not a 'read' access.
  EXPECT_EQ(0, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestTruncate) {
  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));

  char test_data[] = "test data";
  int data_size = static_cast<int>(sizeof(test_data));
  EXPECT_EQ(data_size,
            file_util::WriteFile(PlatformPath(file_path),
                                 test_data, data_size));

  // Check that its length is the size of the data written.
  operation()->GetMetadata(URLForPath(file_path));
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());
  EXPECT_FALSE(info().is_directory);
  EXPECT_EQ(data_size, info().size);

  // Extend the file by truncating it.
  int length = 17;
  operation()->Truncate(URLForPath(file_path), length);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());

  // Check that its length is now 17 and that it's all zeroes after the test
  // data.
  base::PlatformFileInfo info;

  EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info));
  EXPECT_EQ(length, info.size);
  char data[100];
  EXPECT_EQ(length, file_util::ReadFile(PlatformPath(file_path), data, length));
  for (int i = 0; i < length; ++i) {
    if (i < static_cast<int>(sizeof(test_data)))
      EXPECT_EQ(test_data[i], data[i]);
    else
      EXPECT_EQ(0, data[i]);
  }

  // Shorten the file by truncating it.
  length = 3;
  operation()->Truncate(URLForPath(file_path), length);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());

  // Check that its length is now 3 and that it contains only bits of test data.
  EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info));
  EXPECT_EQ(length, info.size);
  EXPECT_EQ(length, file_util::ReadFile(PlatformPath(file_path), data, length));
  for (int i = 0; i < length; ++i)
    EXPECT_EQ(test_data[i], data[i]);

  // Truncate is not a 'read' access.  (Here expected access count is 1
  // since we made 1 read access for GetMetadata.)
  EXPECT_EQ(1, quota_manager_proxy()->storage_accessed_count());
}

TEST_F(FileSystemOperationTest, TestTruncateFailureByQuota) {
  base::PlatformFileInfo info;

  FilePath dir_path(CreateVirtualTemporaryDir());
  FilePath file_path(CreateVirtualTemporaryFileInDir(dir_path));

  quota_manager_proxy()->SetQuota(test_helper_.origin(),
                                  test_helper_.storage_type(),
                                  10);

  operation()->Truncate(URLForPath(file_path), 10);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());

  EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info));
  EXPECT_EQ(10, info.size);

  operation()->Truncate(URLForPath(file_path), 11);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE, status());

  EXPECT_TRUE(file_util::GetFileInfo(PlatformPath(file_path), &info));
  EXPECT_EQ(10, info.size);
}

TEST_F(FileSystemOperationTest, TestTouchFile) {
  FilePath file_path(CreateVirtualTemporaryFileInDir(FilePath()));
  FilePath platform_path = PlatformPath(file_path);

  base::PlatformFileInfo info;

  EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info));
  EXPECT_FALSE(info.is_directory);
  EXPECT_EQ(0, info.size);
  const base::Time last_modified = info.last_modified;
  const base::Time last_accessed = info.last_accessed;

  const base::Time new_modified_time = base::Time::UnixEpoch();
  const base::Time new_accessed_time = new_modified_time +
    base::TimeDelta::FromHours(77);;
  ASSERT_NE(last_modified, new_modified_time);
  ASSERT_NE(last_accessed, new_accessed_time);

  operation()->TouchFile(URLForPath(file_path), new_accessed_time,
      new_modified_time);
  MessageLoop::current()->RunAllPending();
  EXPECT_EQ(base::PLATFORM_FILE_OK, status());

  EXPECT_TRUE(file_util::GetFileInfo(platform_path, &info));
  // We compare as time_t here to lower our resolution, to avoid false
  // negatives caused by conversion to the local filesystem's native
  // representation and back.
  EXPECT_EQ(new_modified_time.ToTimeT(), info.last_modified.ToTimeT());
  EXPECT_EQ(new_accessed_time.ToTimeT(), info.last_accessed.ToTimeT());
}

}  // namespace fileapi
