// 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 "storage/browser/fileapi/file_system_context.h"

#include <stddef.h>

#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread_task_runner_handle.h"
#include "build/build_config.h"
#include "storage/browser/fileapi/external_mount_points.h"
#include "storage/browser/fileapi/file_system_backend.h"
#include "storage/browser/fileapi/isolated_context.h"
#include "storage/browser/test/mock_quota_manager.h"
#include "storage/browser/test/mock_special_storage_policy.h"
#include "storage/browser/test/test_file_system_options.h"
#include "testing/gtest/include/gtest/gtest.h"

#define FPL(x) FILE_PATH_LITERAL(x)

#if defined(FILE_PATH_USES_DRIVE_LETTERS)
#define DRIVE FPL("C:")
#else
#define DRIVE
#endif

using storage::ExternalMountPoints;
using storage::FileSystemBackend;
using storage::FileSystemContext;
using storage::FileSystemMountOption;
using storage::FileSystemURL;
using storage::IsolatedContext;

namespace content {

namespace {

const char kTestOrigin[] = "http://chromium.org/";

GURL CreateRawFileSystemURL(const std::string& type_str,
                            const std::string& fs_id) {
  std::string url_str = base::StringPrintf(
      "filesystem:http://chromium.org/%s/%s/root/file",
      type_str.c_str(),
      fs_id.c_str());
  return GURL(url_str);
}

class FileSystemContextTest : public testing::Test {
 public:
  FileSystemContextTest() {}

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

    storage_policy_ = new MockSpecialStoragePolicy();

    mock_quota_manager_ = new MockQuotaManager(
        false /* is_incognito */, data_dir_.GetPath(),
        base::ThreadTaskRunnerHandle::Get().get(), storage_policy_.get());
  }

 protected:
  FileSystemContext* CreateFileSystemContextForTest(
      storage::ExternalMountPoints* external_mount_points) {
    return new FileSystemContext(
        base::ThreadTaskRunnerHandle::Get().get(),
        base::ThreadTaskRunnerHandle::Get().get(), external_mount_points,
        storage_policy_.get(), mock_quota_manager_->proxy(),
        std::vector<std::unique_ptr<FileSystemBackend>>(),
        std::vector<storage::URLRequestAutoMountHandler>(), data_dir_.GetPath(),
        CreateAllowFileAccessOptions());
  }

  // Verifies a *valid* filesystem url has expected values.
  void ExpectFileSystemURLMatches(const FileSystemURL& url,
                                  const GURL& expect_origin,
                                  storage::FileSystemType expect_mount_type,
                                  storage::FileSystemType expect_type,
                                  const base::FilePath& expect_path,
                                  const base::FilePath& expect_virtual_path,
                                  const std::string& expect_filesystem_id) {
    EXPECT_TRUE(url.is_valid());

    EXPECT_EQ(expect_origin, url.origin());
    EXPECT_EQ(expect_mount_type, url.mount_type());
    EXPECT_EQ(expect_type, url.type());
    EXPECT_EQ(expect_path, url.path());
    EXPECT_EQ(expect_virtual_path, url.virtual_path());
    EXPECT_EQ(expect_filesystem_id, url.filesystem_id());
  }

 private:
  base::ScopedTempDir data_dir_;
  base::test::ScopedTaskEnvironment scoped_task_environment_;
  scoped_refptr<storage::SpecialStoragePolicy> storage_policy_;
  scoped_refptr<MockQuotaManager> mock_quota_manager_;
};

// It is not valid to pass NULL ExternalMountPoints to FileSystemContext on
// ChromeOS.
#if !defined(OS_CHROMEOS)
TEST_F(FileSystemContextTest, NullExternalMountPoints) {
  scoped_refptr<FileSystemContext> file_system_context(
      CreateFileSystemContextForTest(NULL));

  // Cracking system external mount and isolated mount points should work.
  std::string isolated_name = "root";
  std::string isolated_id =
      IsolatedContext::GetInstance()->RegisterFileSystemForPath(
          storage::kFileSystemTypeNativeLocal,
          std::string(),
          base::FilePath(DRIVE FPL("/test/isolated/root")),
          &isolated_name);
  // Register system external mount point.
  ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
      "system",
      storage::kFileSystemTypeNativeLocal,
      FileSystemMountOption(),
      base::FilePath(DRIVE FPL("/test/sys/"))));

  FileSystemURL cracked_isolated = file_system_context->CrackURL(
      CreateRawFileSystemURL("isolated", isolated_id));

  ExpectFileSystemURLMatches(
      cracked_isolated,
      GURL(kTestOrigin),
      storage::kFileSystemTypeIsolated,
      storage::kFileSystemTypeNativeLocal,
      base::FilePath(DRIVE FPL("/test/isolated/root/file"))
          .NormalizePathSeparators(),
      base::FilePath::FromUTF8Unsafe(isolated_id)
          .Append(FPL("root/file"))
          .NormalizePathSeparators(),
      isolated_id);

  FileSystemURL cracked_external = file_system_context->CrackURL(
      CreateRawFileSystemURL("external", "system"));

  ExpectFileSystemURLMatches(
      cracked_external,
      GURL(kTestOrigin),
      storage::kFileSystemTypeExternal,
      storage::kFileSystemTypeNativeLocal,
      base::FilePath(DRIVE FPL("/test/sys/root/file"))
          .NormalizePathSeparators(),
      base::FilePath(FPL("system/root/file")).NormalizePathSeparators(),
      "system");

  IsolatedContext::GetInstance()->RevokeFileSystem(isolated_id);
  ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system");
}
#endif  // !defiend(OS_CHROMEOS)

TEST_F(FileSystemContextTest, FileSystemContextKeepsMountPointsAlive) {
  scoped_refptr<ExternalMountPoints> mount_points =
      ExternalMountPoints::CreateRefCounted();

  // Register system external mount point.
  ASSERT_TRUE(mount_points->RegisterFileSystem(
      "system",
      storage::kFileSystemTypeNativeLocal,
      FileSystemMountOption(),
      base::FilePath(DRIVE FPL("/test/sys/"))));

  scoped_refptr<FileSystemContext> file_system_context(
      CreateFileSystemContextForTest(mount_points.get()));

  // Release a MountPoints reference created in the test.
  mount_points = NULL;

  // FileSystemContext should keep a reference to the |mount_points|, so it
  // should be able to resolve the URL.
  FileSystemURL cracked_external = file_system_context->CrackURL(
      CreateRawFileSystemURL("external", "system"));

  ExpectFileSystemURLMatches(
      cracked_external,
      GURL(kTestOrigin),
      storage::kFileSystemTypeExternal,
      storage::kFileSystemTypeNativeLocal,
      base::FilePath(DRIVE FPL("/test/sys/root/file"))
          .NormalizePathSeparators(),
      base::FilePath(FPL("system/root/file")).NormalizePathSeparators(),
      "system");

  // No need to revoke the registered filesystem since |mount_points| lifetime
  // is bound to this test.
}

TEST_F(FileSystemContextTest, CrackFileSystemURL) {
  scoped_refptr<ExternalMountPoints> external_mount_points(
      ExternalMountPoints::CreateRefCounted());
  scoped_refptr<FileSystemContext> file_system_context(
      CreateFileSystemContextForTest(external_mount_points.get()));

  // Register an isolated mount point.
  std::string isolated_file_system_name = "root";
  const std::string kIsolatedFileSystemID =
      IsolatedContext::GetInstance()->RegisterFileSystemForPath(
          storage::kFileSystemTypeNativeLocal,
          std::string(),
          base::FilePath(DRIVE FPL("/test/isolated/root")),
          &isolated_file_system_name);
  // Register system external mount point.
  ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
      "system",
      storage::kFileSystemTypeDrive,
      FileSystemMountOption(),
      base::FilePath(DRIVE FPL("/test/sys/"))));
  ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
      "ext",
      storage::kFileSystemTypeNativeLocal,
      FileSystemMountOption(),
      base::FilePath(DRIVE FPL("/test/ext"))));
  // Register a system external mount point with the same name/id as the
  // registered isolated mount point.
  ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
      kIsolatedFileSystemID,
      storage::kFileSystemTypeRestrictedNativeLocal,
      FileSystemMountOption(),
      base::FilePath(DRIVE FPL("/test/system/isolated"))));
  // Add a mount points with the same name as a system mount point to
  // FileSystemContext's external mount points.
  ASSERT_TRUE(external_mount_points->RegisterFileSystem(
      "ext",
      storage::kFileSystemTypeNativeLocal,
      FileSystemMountOption(),
      base::FilePath(DRIVE FPL("/test/local/ext/"))));

  const GURL kTestOrigin = GURL("http://chromium.org/");
  const base::FilePath kVirtualPathNoRoot = base::FilePath(FPL("root/file"));

  struct TestCase {
    // Test case values.
    std::string root;
    std::string type_str;

    // Expected test results.
    bool expect_is_valid;
    storage::FileSystemType expect_mount_type;
    storage::FileSystemType expect_type;
    const base::FilePath::CharType* expect_path;
    std::string expect_filesystem_id;
  };

  const TestCase kTestCases[] = {
      // Following should not be handled by the url crackers:
      {
       "pers_mount", "persistent", true /* is_valid */,
       storage::kFileSystemTypePersistent, storage::kFileSystemTypePersistent,
       FPL("pers_mount/root/file"), std::string() /* filesystem id */
      },
      {
       "temp_mount", "temporary", true /* is_valid */,
       storage::kFileSystemTypeTemporary, storage::kFileSystemTypeTemporary,
       FPL("temp_mount/root/file"), std::string() /* filesystem id */
      },
      // Should be cracked by isolated mount points:
      {kIsolatedFileSystemID, "isolated", true /* is_valid */,
       storage::kFileSystemTypeIsolated, storage::kFileSystemTypeNativeLocal,
       DRIVE FPL("/test/isolated/root/file"), kIsolatedFileSystemID},
      // Should be cracked by system mount points:
      {"system", "external", true /* is_valid */,
       storage::kFileSystemTypeExternal, storage::kFileSystemTypeDrive,
       DRIVE FPL("/test/sys/root/file"), "system"},
      {kIsolatedFileSystemID, "external", true /* is_valid */,
       storage::kFileSystemTypeExternal,
       storage::kFileSystemTypeRestrictedNativeLocal,
       DRIVE FPL("/test/system/isolated/root/file"), kIsolatedFileSystemID},
      // Should be cracked by FileSystemContext's ExternalMountPoints.
      {"ext", "external", true /* is_valid */, storage::kFileSystemTypeExternal,
       storage::kFileSystemTypeNativeLocal,
       DRIVE FPL("/test/local/ext/root/file"), "ext"},
      // Test for invalid filesystem url (made invalid by adding invalid
      // filesystem type).
      {"sytem", "external", false /* is_valid */,
       // The rest of values will be ignored.
       storage::kFileSystemTypeUnknown, storage::kFileSystemTypeUnknown,
       FPL(""), std::string()},
      // Test for URL with non-existing filesystem id.
      {"invalid", "external", false /* is_valid */,
       // The rest of values will be ignored.
       storage::kFileSystemTypeUnknown, storage::kFileSystemTypeUnknown,
       FPL(""), std::string()},
  };

  for (size_t i = 0; i < arraysize(kTestCases); ++i) {
    const base::FilePath virtual_path =
        base::FilePath::FromUTF8Unsafe(
            kTestCases[i].root).Append(kVirtualPathNoRoot);

    GURL raw_url =
        CreateRawFileSystemURL(kTestCases[i].type_str, kTestCases[i].root);
    FileSystemURL cracked_url = file_system_context->CrackURL(raw_url);

    SCOPED_TRACE(testing::Message() << "Test case " << i << ": "
                                    << "Cracking URL: " << raw_url);

    EXPECT_EQ(kTestCases[i].expect_is_valid, cracked_url.is_valid());
    if (!kTestCases[i].expect_is_valid)
      continue;

    ExpectFileSystemURLMatches(
        cracked_url,
        GURL(kTestOrigin),
        kTestCases[i].expect_mount_type,
        kTestCases[i].expect_type,
        base::FilePath(kTestCases[i].expect_path).NormalizePathSeparators(),
        virtual_path.NormalizePathSeparators(),
        kTestCases[i].expect_filesystem_id);
  }

  IsolatedContext::GetInstance()->RevokeFileSystemByPath(
      base::FilePath(DRIVE FPL("/test/isolated/root")));
  ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system");
  ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("ext");
  ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
      kIsolatedFileSystemID);
}

TEST_F(FileSystemContextTest, CanServeURLRequest) {
  scoped_refptr<ExternalMountPoints> external_mount_points(
      ExternalMountPoints::CreateRefCounted());
  scoped_refptr<FileSystemContext> context(
      CreateFileSystemContextForTest(external_mount_points.get()));

  // A request for a sandbox mount point should be served.
  FileSystemURL cracked_url =
      context->CrackURL(CreateRawFileSystemURL("persistent", "pers_mount"));
  EXPECT_EQ(storage::kFileSystemTypePersistent, cracked_url.mount_type());
  EXPECT_TRUE(context->CanServeURLRequest(cracked_url));

  // A request for an isolated mount point should NOT be served.
  std::string isolated_fs_name = "root";
  std::string isolated_fs_id =
      IsolatedContext::GetInstance()->RegisterFileSystemForPath(
          storage::kFileSystemTypeNativeLocal,
          std::string(),
          base::FilePath(DRIVE FPL("/test/isolated/root")),
          &isolated_fs_name);
  cracked_url = context->CrackURL(
      CreateRawFileSystemURL("isolated", isolated_fs_id));
  EXPECT_EQ(storage::kFileSystemTypeIsolated, cracked_url.mount_type());
  EXPECT_FALSE(context->CanServeURLRequest(cracked_url));

  // A request for an external mount point should be served.
  const std::string kExternalMountName = "ext_mount";
  ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
      kExternalMountName,
      storage::kFileSystemTypeDrive,
      FileSystemMountOption(),
      base::FilePath()));
  cracked_url = context->CrackURL(
      CreateRawFileSystemURL("external", kExternalMountName));
  EXPECT_EQ(storage::kFileSystemTypeExternal, cracked_url.mount_type());
  EXPECT_TRUE(context->CanServeURLRequest(cracked_url));

  ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(
      kExternalMountName);
  IsolatedContext::GetInstance()->RevokeFileSystem(isolated_fs_id);
}

// Ensures that a backend exists for each common isolated file system type.
// See http://crbug.com/447027
TEST_F(FileSystemContextTest, IsolatedFileSystemsTypesHandled) {
  // This does not provide any "additional" file system handlers. In particular,
  // on Chrome OS it does not provide chromeos::FileSystemBackend.
  scoped_refptr<FileSystemContext> file_system_context(
      CreateFileSystemContextForTest(nullptr));

  // Isolated file system types are handled.
  EXPECT_TRUE(file_system_context->GetFileSystemBackend(
      storage::kFileSystemTypeIsolated));
  EXPECT_TRUE(file_system_context->GetFileSystemBackend(
      storage::kFileSystemTypeDragged));
  EXPECT_TRUE(file_system_context->GetFileSystemBackend(
      storage::kFileSystemTypeForTransientFile));
  EXPECT_TRUE(file_system_context->GetFileSystemBackend(
      storage::kFileSystemTypeNativeLocal));
  EXPECT_TRUE(file_system_context->GetFileSystemBackend(
      storage::kFileSystemTypeNativeForPlatformApp));
}

}  // namespace

}  // namespace content
