// Copyright (c) 2012 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 "testing/gtest/include/gtest/gtest.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/file_util.h"
#include "base/message_loop/message_loop.h"
#include "base/platform_file.h"
#include "base/stl_util.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/browsing_data/browsing_data_file_system_helper.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "webkit/browser/fileapi/file_system_context.h"
#include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/common/fileapi/file_system_types.h"

using content::BrowserContext;
using content::BrowserThread;

namespace {

// Shorter names for fileapi::* constants.
const fileapi::FileSystemType kTemporary = fileapi::kFileSystemTypeTemporary;
const fileapi::FileSystemType kPersistent = fileapi::kFileSystemTypePersistent;

// We'll use these three distinct origins for testing, both as strings and as
// GURLs in appropriate contexts.
const char kTestOrigin1[] = "http://host1:1/";
const char kTestOrigin2[] = "http://host2:2/";
const char kTestOrigin3[] = "http://host3:3/";

// Extensions and Devtools should be ignored.
const char kTestOriginExt[] = "chrome-extension://abcdefghijklmnopqrstuvwxyz/";
const char kTestOriginDevTools[] = "chrome-devtools://abcdefghijklmnopqrstuvw/";

const GURL kOrigin1(kTestOrigin1);
const GURL kOrigin2(kTestOrigin2);
const GURL kOrigin3(kTestOrigin3);
const GURL kOriginExt(kTestOriginExt);
const GURL kOriginDevTools(kTestOriginDevTools);

// TODO(mkwst): Update this size once the discussion in http://crbug.com/86114
// is concluded.
const int kEmptyFileSystemSize = 0;

typedef std::list<BrowsingDataFileSystemHelper::FileSystemInfo>
    FileSystemInfoList;
typedef scoped_ptr<FileSystemInfoList> ScopedFileSystemInfoList;

// The FileSystem APIs are all asynchronous; this testing class wraps up the
// boilerplate code necessary to deal with waiting for responses. In a nutshell,
// any async call whose response we want to test ought to be followed by a call
// to BlockUntilNotified(), which will (shockingly!) block until Notify() is
// called. For this to work, you'll need to ensure that each async call is
// implemented as a class method that that calls Notify() at an appropriate
// point.
class BrowsingDataFileSystemHelperTest : public testing::Test {
 public:
  BrowsingDataFileSystemHelperTest() {
    profile_.reset(new TestingProfile());

    helper_ = BrowsingDataFileSystemHelper::Create(
        BrowserContext::GetDefaultStoragePartition(profile_.get())->
            GetFileSystemContext());
    base::MessageLoop::current()->RunUntilIdle();
    canned_helper_ = new CannedBrowsingDataFileSystemHelper(profile_.get());
  }
  virtual ~BrowsingDataFileSystemHelperTest() {
    // Avoid memory leaks.
    profile_.reset();
    base::MessageLoop::current()->RunUntilIdle();
  }

  TestingProfile* GetProfile() {
    return profile_.get();
  }

  // Blocks on the current MessageLoop until Notify() is called.
  void BlockUntilNotified() {
    base::MessageLoop::current()->Run();
  }

  // Unblocks the current MessageLoop. Should be called in response to some sort
  // of async activity in a callback method.
  void Notify() {
    base::MessageLoop::current()->Quit();
  }

  // Callback that should be executed in response to
  // fileapi::FileSystemContext::OpenFileSystem.
  void OpenFileSystemCallback(const GURL& root,
                              const std::string& name,
                              base::PlatformFileError error) {
    open_file_system_result_ = error;
    Notify();
  }

  bool OpenFileSystem(const GURL& origin,
                      fileapi::FileSystemType type,
                      fileapi::OpenFileSystemMode open_mode) {
    BrowserContext::GetDefaultStoragePartition(profile_.get())->
        GetFileSystemContext()->OpenFileSystem(
            origin, type, open_mode,
            base::Bind(
                &BrowsingDataFileSystemHelperTest::OpenFileSystemCallback,
                base::Unretained(this)));
    BlockUntilNotified();
    return open_file_system_result_ == base::PLATFORM_FILE_OK;
  }

  // Calls fileapi::FileSystemContext::OpenFileSystem with
  // OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT flag
  // to verify the existence of a file system for a specified type and origin,
  // blocks until a response is available, then returns the result
  // synchronously to it's caller.
  bool FileSystemContainsOriginAndType(const GURL& origin,
                                       fileapi::FileSystemType type) {
    return OpenFileSystem(origin, type,
                          fileapi::OPEN_FILE_SYSTEM_FAIL_IF_NONEXISTENT);
  }

  // Callback that should be executed in response to StartFetching(), and stores
  // found file systems locally so that they are available via GetFileSystems().
  void CallbackStartFetching(
      const std::list<BrowsingDataFileSystemHelper::FileSystemInfo>&
          file_system_info_list) {
    file_system_info_list_.reset(
        new std::list<BrowsingDataFileSystemHelper::FileSystemInfo>(
            file_system_info_list));
    Notify();
  }

  // Calls StartFetching() on the test's BrowsingDataFileSystemHelper
  // object, then blocks until the callback is executed.
  void FetchFileSystems() {
    helper_->StartFetching(
        base::Bind(&BrowsingDataFileSystemHelperTest::CallbackStartFetching,
                   base::Unretained(this)));
    BlockUntilNotified();
  }

  // Calls StartFetching() on the test's CannedBrowsingDataFileSystemHelper
  // object, then blocks until the callback is executed.
  void FetchCannedFileSystems() {
    canned_helper_->StartFetching(
        base::Bind(&BrowsingDataFileSystemHelperTest::CallbackStartFetching,
                   base::Unretained(this)));
    BlockUntilNotified();
  }

  // Sets up kOrigin1 with a temporary file system, kOrigin2 with a persistent
  // file system, and kOrigin3 with both.
  virtual void PopulateTestFileSystemData() {
    CreateDirectoryForOriginAndType(kOrigin1, kTemporary);
    CreateDirectoryForOriginAndType(kOrigin2, kPersistent);
    CreateDirectoryForOriginAndType(kOrigin3, kTemporary);
    CreateDirectoryForOriginAndType(kOrigin3, kPersistent);

    EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin1, kPersistent));
    EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin1, kTemporary));
    EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin2, kPersistent));
    EXPECT_FALSE(FileSystemContainsOriginAndType(kOrigin2, kTemporary));
    EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3, kPersistent));
    EXPECT_TRUE(FileSystemContainsOriginAndType(kOrigin3, kTemporary));
  }

  // Calls OpenFileSystem with OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT
  // to create a filesystem of a given type for a specified origin.
  void CreateDirectoryForOriginAndType(const GURL& origin,
                                       fileapi::FileSystemType type) {
    OpenFileSystem(origin, type,
                   fileapi::OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
    EXPECT_EQ(base::PLATFORM_FILE_OK, open_file_system_result_);
  }

  // Returns a list of the FileSystemInfo objects gathered in the most recent
  // call to StartFetching().
  FileSystemInfoList* GetFileSystems() {
    return file_system_info_list_.get();
  }

 protected:
  content::TestBrowserThreadBundle thread_bundle_;
  scoped_ptr<TestingProfile> profile_;

  // Temporary storage to pass information back from callbacks.
  base::PlatformFileError open_file_system_result_;
  ScopedFileSystemInfoList file_system_info_list_;

  scoped_refptr<BrowsingDataFileSystemHelper> helper_;
  scoped_refptr<CannedBrowsingDataFileSystemHelper> canned_helper_;

  DISALLOW_COPY_AND_ASSIGN(BrowsingDataFileSystemHelperTest);
};

// Verifies that the BrowsingDataFileSystemHelper correctly finds the test file
// system data, and that each file system returned contains the expected data.
TEST_F(BrowsingDataFileSystemHelperTest, FetchData) {
  PopulateTestFileSystemData();

  FetchFileSystems();

  EXPECT_EQ(3UL, file_system_info_list_->size());

  // Order is arbitrary, verify all three origins.
  bool test_hosts_found[3] = {false, false, false};
  for (std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator info =
       file_system_info_list_->begin(); info != file_system_info_list_->end();
       ++info) {
    if (info->origin == kOrigin1) {
      EXPECT_FALSE(test_hosts_found[0]);
      test_hosts_found[0] = true;
      EXPECT_FALSE(ContainsKey(info->usage_map, kPersistent));
      EXPECT_TRUE(ContainsKey(info->usage_map, kTemporary));
      EXPECT_EQ(kEmptyFileSystemSize,
                info->usage_map[fileapi::kFileSystemTypeTemporary]);
    } else if (info->origin == kOrigin2) {
      EXPECT_FALSE(test_hosts_found[1]);
      test_hosts_found[1] = true;
      EXPECT_TRUE(ContainsKey(info->usage_map, kPersistent));
      EXPECT_FALSE(ContainsKey(info->usage_map, kTemporary));
      EXPECT_EQ(kEmptyFileSystemSize, info->usage_map[kPersistent]);
    } else if (info->origin == kOrigin3) {
      EXPECT_FALSE(test_hosts_found[2]);
      test_hosts_found[2] = true;
      EXPECT_TRUE(ContainsKey(info->usage_map, kPersistent));
      EXPECT_TRUE(ContainsKey(info->usage_map, kTemporary));
      EXPECT_EQ(kEmptyFileSystemSize, info->usage_map[kPersistent]);
      EXPECT_EQ(kEmptyFileSystemSize, info->usage_map[kTemporary]);
    } else {
      ADD_FAILURE() << info->origin.spec() << " isn't an origin we added.";
    }
  }
  for (size_t i = 0; i < arraysize(test_hosts_found); i++) {
    EXPECT_TRUE(test_hosts_found[i]);
  }
}

// Verifies that the BrowsingDataFileSystemHelper correctly deletes file
// systems via DeleteFileSystemOrigin().
TEST_F(BrowsingDataFileSystemHelperTest, DeleteData) {
  PopulateTestFileSystemData();

  helper_->DeleteFileSystemOrigin(kOrigin1);
  helper_->DeleteFileSystemOrigin(kOrigin2);

  FetchFileSystems();

  EXPECT_EQ(1UL, file_system_info_list_->size());
  BrowsingDataFileSystemHelper::FileSystemInfo info =
      *(file_system_info_list_->begin());
  EXPECT_EQ(kOrigin3, info.origin);
  EXPECT_TRUE(ContainsKey(info.usage_map, kPersistent));
  EXPECT_TRUE(ContainsKey(info.usage_map, kTemporary));
  EXPECT_EQ(kEmptyFileSystemSize, info.usage_map[kPersistent]);
  EXPECT_EQ(kEmptyFileSystemSize, info.usage_map[kTemporary]);
}

// Verifies that the CannedBrowsingDataFileSystemHelper correctly reports
// whether or not it currently contains file systems.
TEST_F(BrowsingDataFileSystemHelperTest, Empty) {
  ASSERT_TRUE(canned_helper_->empty());
  canned_helper_->AddFileSystem(kOrigin1, kTemporary, 0);
  ASSERT_FALSE(canned_helper_->empty());
  canned_helper_->Reset();
  ASSERT_TRUE(canned_helper_->empty());
}

// Verifies that AddFileSystem correctly adds file systems, and that both
// the type and usage metadata are reported as provided.
TEST_F(BrowsingDataFileSystemHelperTest, CannedAddFileSystem) {
  canned_helper_->AddFileSystem(kOrigin1, kPersistent, 200);
  canned_helper_->AddFileSystem(kOrigin2, kTemporary, 100);

  FetchCannedFileSystems();

  EXPECT_EQ(2U, file_system_info_list_->size());
  std::list<BrowsingDataFileSystemHelper::FileSystemInfo>::iterator info =
      file_system_info_list_->begin();
  EXPECT_EQ(kOrigin1, info->origin);
  EXPECT_TRUE(ContainsKey(info->usage_map, kPersistent));
  EXPECT_FALSE(ContainsKey(info->usage_map, kTemporary));
  EXPECT_EQ(200, info->usage_map[kPersistent]);

  info++;
  EXPECT_EQ(kOrigin2, info->origin);
  EXPECT_FALSE(ContainsKey(info->usage_map, kPersistent));
  EXPECT_TRUE(ContainsKey(info->usage_map, kTemporary));
  EXPECT_EQ(100, info->usage_map[kTemporary]);
}

// Verifies that the CannedBrowsingDataFileSystemHelper correctly ignores
// extension and devtools schemes.
TEST_F(BrowsingDataFileSystemHelperTest, IgnoreExtensionsAndDevTools) {
  ASSERT_TRUE(canned_helper_->empty());
  canned_helper_->AddFileSystem(kOriginExt, kTemporary, 0);
  ASSERT_TRUE(canned_helper_->empty());
  canned_helper_->AddFileSystem(kOriginDevTools, kTemporary, 0);
  ASSERT_TRUE(canned_helper_->empty());
}

}  // namespace
