// Copyright 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 "base/stl_util.h"
#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
#include "chrome/browser/sync_file_system/local/local_file_change_tracker.h"
#include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_file_util.h"
#include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/isolated_context.h"
#include "webkit/browser/fileapi/sandbox_file_system_test_helper.h"
#include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/fileapi/file_system_types.h"
#include "webkit/common/quota/quota_types.h"

using base::PlatformFileError;
using fileapi::FileSystemContext;
using fileapi::FileSystemOperationContext;
using fileapi::FileSystemURL;
using fileapi::FileSystemURLSet;
using fileapi::SandboxFileSystemTestHelper;
using quota::QuotaManager;
using quota::QuotaStatusCode;

namespace sync_file_system {

class SyncableFileSystemTest : public testing::Test {
 public:
  SyncableFileSystemTest()
      : file_system_(GURL("http://example.com/"),
                     base::MessageLoopProxy::current().get(),
                     base::MessageLoopProxy::current().get()),
        weak_factory_(this) {}

  virtual void SetUp() {
    ASSERT_TRUE(data_dir_.CreateUniqueTempDir());

    file_system_.SetUp();

    sync_context_ =
        new LocalFileSyncContext(data_dir_.path(),
                                 base::MessageLoopProxy::current().get(),
                                 base::MessageLoopProxy::current().get());
    ASSERT_EQ(
        sync_file_system::SYNC_STATUS_OK,
        file_system_.MaybeInitializeFileSystemContext(sync_context_.get()));
  }

  virtual void TearDown() {
    if (sync_context_.get())
      sync_context_->ShutdownOnUIThread();
    sync_context_ = NULL;

    file_system_.TearDown();

    // Make sure we don't leave the external filesystem.
    // (CannedSyncableFileSystem::TearDown does not do this as there may be
    // multiple syncable file systems registered for the name)
    RevokeSyncableFileSystem();
  }

 protected:
  void VerifyAndClearChange(const FileSystemURL& url,
                            const FileChange& expected_change) {
    SCOPED_TRACE(testing::Message() << url.DebugString() <<
                 " expecting:" << expected_change.DebugString());
    // Get the changes for URL and verify.
    FileChangeList changes;
    change_tracker()->GetChangesForURL(url, &changes);
    ASSERT_EQ(1U, changes.size());
    SCOPED_TRACE(testing::Message() << url.DebugString() <<
                 " actual:" << changes.DebugString());
    EXPECT_EQ(expected_change, changes.front());

    // Clear the URL from the change tracker.
    change_tracker()->ClearChangesForURL(url);
  }

  FileSystemURL URL(const std::string& path) {
    return file_system_.URL(path);
  }

  FileSystemContext* file_system_context() {
    return file_system_.file_system_context();
  }

  LocalFileChangeTracker* change_tracker() {
    return file_system_.backend()->change_tracker();
  }

  ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;

  base::ScopedTempDir data_dir_;
  content::TestBrowserThreadBundle thread_bundle_;
  CannedSyncableFileSystem file_system_;

 private:
  scoped_refptr<LocalFileSyncContext> sync_context_;

  base::WeakPtrFactory<SyncableFileSystemTest> weak_factory_;

  DISALLOW_COPY_AND_ASSIGN(SyncableFileSystemTest);
};

// Brief combined testing. Just see if all the sandbox feature works.
TEST_F(SyncableFileSystemTest, SyncableLocalSandboxCombined) {
  // Opens a syncable file system.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.OpenFileSystem());

  // Do some operations.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.CreateDirectory(URL("dir")));
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.CreateFile(URL("dir/foo")));

  const int64 kOriginalQuota = QuotaManager::kSyncableStorageDefaultHostQuota;

  const int64 kQuota = 12345 * 1024;
  QuotaManager::kSyncableStorageDefaultHostQuota = kQuota;
  int64 usage, quota;
  EXPECT_EQ(quota::kQuotaStatusOk,
            file_system_.GetUsageAndQuota(&usage, &quota));

  // Returned quota must be what we overrode. Usage must be greater than 0
  // as creating a file or directory consumes some space.
  EXPECT_EQ(kQuota, quota);
  EXPECT_GT(usage, 0);

  // Truncate to extend an existing file and see if the usage reflects it.
  const int64 kFileSizeToExtend = 333;
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.CreateFile(URL("dir/foo")));

  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend));

  int64 new_usage;
  EXPECT_EQ(quota::kQuotaStatusOk,
            file_system_.GetUsageAndQuota(&new_usage, &quota));
  EXPECT_EQ(kFileSizeToExtend, new_usage - usage);

  // Shrink the quota to the current usage, try to extend the file further
  // and see if it fails.
  QuotaManager::kSyncableStorageDefaultHostQuota = new_usage;
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_NO_SPACE,
            file_system_.TruncateFile(URL("dir/foo"), kFileSizeToExtend + 1));

  usage = new_usage;
  EXPECT_EQ(quota::kQuotaStatusOk,
            file_system_.GetUsageAndQuota(&new_usage, &quota));
  EXPECT_EQ(usage, new_usage);

  // Deletes the file system.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.DeleteFileSystem());

  // Now the usage must be zero.
  EXPECT_EQ(quota::kQuotaStatusOk,
            file_system_.GetUsageAndQuota(&usage, &quota));
  EXPECT_EQ(0, usage);

  // Restore the system default quota.
  QuotaManager::kSyncableStorageDefaultHostQuota = kOriginalQuota;
}

// Combined testing with LocalFileChangeTracker.
TEST_F(SyncableFileSystemTest, ChangeTrackerSimple) {
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.OpenFileSystem());

  const char kPath0[] = "dir a";
  const char kPath1[] = "dir a/dir";   // child of kPath0
  const char kPath2[] = "dir a/file";  // child of kPath0
  const char kPath3[] = "dir b";

  // Do some operations.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.CreateDirectory(URL(kPath0)));  // Creates a dir.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.CreateDirectory(URL(kPath1)));  // Creates another.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.CreateFile(URL(kPath2)));       // Creates a file.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.TruncateFile(URL(kPath2), 1));  // Modifies the file.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.TruncateFile(URL(kPath2), 2));  // Modifies it again.

  FileSystemURLSet urls;
  file_system_.GetChangedURLsInTracker(&urls);

  EXPECT_EQ(3U, urls.size());
  EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
  EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
  EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));

  VerifyAndClearChange(URL(kPath0),
                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
  VerifyAndClearChange(URL(kPath1),
                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
  VerifyAndClearChange(URL(kPath2),
                       FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
                                  sync_file_system::SYNC_FILE_TYPE_FILE));

  // Creates and removes a same directory.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.CreateDirectory(URL(kPath3)));
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.Remove(URL(kPath3), false /* recursive */));

  // The changes will be offset.
  urls.clear();
  file_system_.GetChangedURLsInTracker(&urls);
  EXPECT_TRUE(urls.empty());

  // Recursively removes the kPath0 directory.
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.Remove(URL(kPath0), true /* recursive */));

  urls.clear();
  file_system_.GetChangedURLsInTracker(&urls);

  // kPath0 and its all chidren (kPath1 and kPath2) must have been deleted.
  EXPECT_EQ(3U, urls.size());
  EXPECT_TRUE(ContainsKey(urls, URL(kPath0)));
  EXPECT_TRUE(ContainsKey(urls, URL(kPath1)));
  EXPECT_TRUE(ContainsKey(urls, URL(kPath2)));

  VerifyAndClearChange(URL(kPath0),
                       FileChange(FileChange::FILE_CHANGE_DELETE,
                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
  VerifyAndClearChange(URL(kPath1),
                       FileChange(FileChange::FILE_CHANGE_DELETE,
                                  sync_file_system::SYNC_FILE_TYPE_DIRECTORY));
  VerifyAndClearChange(URL(kPath2),
                       FileChange(FileChange::FILE_CHANGE_DELETE,
                                  sync_file_system::SYNC_FILE_TYPE_FILE));
}

// Make sure directory operation is disabled (when it's configured so).
TEST_F(SyncableFileSystemTest, DisableDirectoryOperations) {
  bool was_enabled = IsSyncFSDirectoryOperationEnabled();
  SetEnableSyncFSDirectoryOperation(false);
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            file_system_.OpenFileSystem());

  // Try some directory operations (which should fail).
  EXPECT_EQ(base::PLATFORM_FILE_ERROR_INVALID_OPERATION,
            file_system_.CreateDirectory(URL("dir")));

  // Set up another (non-syncable) local file system.
  SandboxFileSystemTestHelper other_file_system_(
      GURL("http://foo.com/"), fileapi::kFileSystemTypeTemporary);
  other_file_system_.SetUp(file_system_.file_system_context());

  // Create directory '/a' and file '/a/b' in the other file system.
  const FileSystemURL kSrcDir = other_file_system_.CreateURLFromUTF8("/a");
  const FileSystemURL kSrcChild = other_file_system_.CreateURLFromUTF8("/a/b");

  bool created = false;
  scoped_ptr<FileSystemOperationContext> operation_context;

  operation_context.reset(other_file_system_.NewOperationContext());
  operation_context->set_allowed_bytes_growth(1024);
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            other_file_system_.file_util()->CreateDirectory(
                operation_context.get(),
                kSrcDir, false /* exclusive */, false /* recursive */));

  operation_context.reset(other_file_system_.NewOperationContext());
  operation_context->set_allowed_bytes_growth(1024);
  EXPECT_EQ(base::PLATFORM_FILE_OK,
            other_file_system_.file_util()->EnsureFileExists(
                operation_context.get(), kSrcChild, &created));
  EXPECT_TRUE(created);

  // Now try copying the directory into the syncable file system, which should
  // fail if directory operation is disabled. (http://crbug.com/161442)
  EXPECT_NE(base::PLATFORM_FILE_OK,
            file_system_.Copy(kSrcDir, URL("dest")));

  other_file_system_.TearDown();
  SetEnableSyncFSDirectoryOperation(was_enabled);
}

}  // namespace sync_file_system
