// 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 <stddef.h>

#include <string>

#include "base/logging.h"
#include "base/macros.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/fileapi/isolated_context.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::FileSystemMountOption;
using storage::FileSystemURL;
using storage::IsolatedContext;
using storage::kFileSystemTypeDragged;
using storage::kFileSystemTypeIsolated;
using storage::kFileSystemTypeNativeLocal;

namespace content {

typedef IsolatedContext::MountPointInfo FileInfo;

namespace {

const base::FilePath kTestPaths[] = {
  base::FilePath(DRIVE FPL("/a/b.txt")),
  base::FilePath(DRIVE FPL("/c/d/e")),
  base::FilePath(DRIVE FPL("/h/")),
  base::FilePath(DRIVE FPL("/")),
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
  base::FilePath(DRIVE FPL("\\foo\\bar")),
  base::FilePath(DRIVE FPL("\\")),
#endif
  // For duplicated base name test.
  base::FilePath(DRIVE FPL("/")),
  base::FilePath(DRIVE FPL("/f/e")),
  base::FilePath(DRIVE FPL("/f/b.txt")),
};

}  // namespace

class IsolatedContextTest : public testing::Test {
 public:
  IsolatedContextTest() {
    for (size_t i = 0; i < arraysize(kTestPaths); ++i)
      fileset_.insert(kTestPaths[i].NormalizePathSeparators());
  }

  void SetUp() override {
    IsolatedContext::FileInfoSet files;
    for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
      std::string name;
      ASSERT_TRUE(
          files.AddPath(kTestPaths[i].NormalizePathSeparators(), &name));
      names_.push_back(name);
    }
    id_ = IsolatedContext::GetInstance()->RegisterDraggedFileSystem(files);
    IsolatedContext::GetInstance()->AddReference(id_);
    ASSERT_FALSE(id_.empty());
  }

  void TearDown() override {
    IsolatedContext::GetInstance()->RemoveReference(id_);
  }

  IsolatedContext* isolated_context() const {
    return IsolatedContext::GetInstance();
  }

 protected:
  std::string id_;
  std::multiset<base::FilePath> fileset_;
  std::vector<std::string> names_;

 private:
  DISALLOW_COPY_AND_ASSIGN(IsolatedContextTest);
};

TEST_F(IsolatedContextTest, RegisterAndRevokeTest) {
  // See if the returned top-level entries match with what we registered.
  std::vector<FileInfo> toplevels;
  ASSERT_TRUE(isolated_context()->GetDraggedFileInfo(id_, &toplevels));
  ASSERT_EQ(fileset_.size(), toplevels.size());
  for (size_t i = 0; i < toplevels.size(); ++i) {
    ASSERT_TRUE(fileset_.find(toplevels[i].path) != fileset_.end());
  }

  // See if the name of each registered kTestPaths (that is what we
  // register in SetUp() by RegisterDraggedFileSystem) is properly cracked as
  // a valid virtual path in the isolated filesystem.
  for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
    base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_)
        .AppendASCII(names_[i]);
    std::string cracked_id;
    base::FilePath cracked_path;
    std::string cracked_inner_id;
    storage::FileSystemType cracked_type;
    FileSystemMountOption cracked_option;
    ASSERT_TRUE(isolated_context()->CrackVirtualPath(
        virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
        &cracked_path, &cracked_option));
    ASSERT_EQ(kTestPaths[i].NormalizePathSeparators().value(),
              cracked_path.value());
    ASSERT_EQ(id_, cracked_id);
    ASSERT_EQ(kFileSystemTypeDragged, cracked_type);
    EXPECT_TRUE(cracked_inner_id.empty());
  }

  // Make sure GetRegisteredPath returns false for id_ since it is
  // registered for dragged files.
  base::FilePath path;
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id_, &path));

  // Deref the current one and registering a new one.
  isolated_context()->RemoveReference(id_);

  std::string id2 = isolated_context()->RegisterFileSystemForPath(
      kFileSystemTypeNativeLocal, std::string(),
      base::FilePath(DRIVE FPL("/foo")), NULL);

  // Make sure the GetDraggedFileInfo returns false for both ones.
  ASSERT_FALSE(isolated_context()->GetDraggedFileInfo(id2, &toplevels));
  ASSERT_FALSE(isolated_context()->GetDraggedFileInfo(id_, &toplevels));

  // Make sure the GetRegisteredPath returns true only for the new one.
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id_, &path));
  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path));

  // Try registering three more file systems for the same path as id2.
  std::string id3 = isolated_context()->RegisterFileSystemForPath(
      kFileSystemTypeNativeLocal, std::string(), path, NULL);
  std::string id4 = isolated_context()->RegisterFileSystemForPath(
      kFileSystemTypeNativeLocal, std::string(), path, NULL);
  std::string id5 = isolated_context()->RegisterFileSystemForPath(
      kFileSystemTypeNativeLocal, std::string(), path, NULL);

  // Remove file system for id4.
  isolated_context()->AddReference(id4);
  isolated_context()->RemoveReference(id4);

  // Only id4 should become invalid now.
  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path));
  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id3, &path));
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path));
  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id5, &path));

  // Revoke file system id5, after adding multiple references.
  isolated_context()->AddReference(id5);
  isolated_context()->AddReference(id5);
  isolated_context()->AddReference(id5);
  isolated_context()->RevokeFileSystem(id5);

  // No matter how many references we add id5 must be invalid now.
  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path));
  ASSERT_TRUE(isolated_context()->GetRegisteredPath(id3, &path));
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path));
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id5, &path));

  // Revoke the file systems by path.
  isolated_context()->RevokeFileSystemByPath(path);

  // Now all the file systems associated to the path must be invalid.
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id2, &path));
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id3, &path));
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path));
  ASSERT_FALSE(isolated_context()->GetRegisteredPath(id5, &path));
}

TEST_F(IsolatedContextTest, CrackWithRelativePaths) {
  const struct {
    base::FilePath::StringType path;
    bool valid;
  } relatives[] = {
    { FPL("foo"), true },
    { FPL("foo/bar"), true },
    { FPL(".."), false },
    { FPL("foo/.."), false },
    { FPL("foo/../bar"), false },
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
# define SHOULD_FAIL_WITH_WIN_SEPARATORS false
#else
# define SHOULD_FAIL_WITH_WIN_SEPARATORS true
#endif
    { FPL("foo\\..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
    { FPL("foo/..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
  };

  for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
    for (size_t j = 0; j < arraysize(relatives); ++j) {
      SCOPED_TRACE(testing::Message() << "Testing "
                   << kTestPaths[i].value() << " " << relatives[j].path);
      base::FilePath virtual_path =
          isolated_context()->CreateVirtualRootPath(id_).AppendASCII(
              names_[i]).Append(relatives[j].path);
      std::string cracked_id;
      base::FilePath cracked_path;
      storage::FileSystemType cracked_type;
      std::string cracked_inner_id;
      FileSystemMountOption cracked_option;
      if (!relatives[j].valid) {
        ASSERT_FALSE(isolated_context()->CrackVirtualPath(
            virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
            &cracked_path, &cracked_option));
        continue;
      }
      ASSERT_TRUE(isolated_context()->CrackVirtualPath(
          virtual_path, &cracked_id, &cracked_type, &cracked_inner_id,
          &cracked_path, &cracked_option));
      ASSERT_EQ(kTestPaths[i].Append(relatives[j].path)
                    .NormalizePathSeparators().value(),
                cracked_path.value());
      ASSERT_EQ(id_, cracked_id);
      ASSERT_EQ(kFileSystemTypeDragged, cracked_type);
      EXPECT_TRUE(cracked_inner_id.empty());
    }
  }
}

TEST_F(IsolatedContextTest, CrackURLWithRelativePaths) {
  const struct {
    base::FilePath::StringType path;
    bool valid;
  } relatives[] = {
    { FPL("foo"), true },
    { FPL("foo/bar"), true },
    { FPL(".."), false },
    { FPL("foo/.."), false },
    { FPL("foo/../bar"), false },
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
# define SHOULD_FAIL_WITH_WIN_SEPARATORS false
#else
# define SHOULD_FAIL_WITH_WIN_SEPARATORS true
#endif
    { FPL("foo\\..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
    { FPL("foo/..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS },
  };

  for (size_t i = 0; i < arraysize(kTestPaths); ++i) {
    for (size_t j = 0; j < arraysize(relatives); ++j) {
      SCOPED_TRACE(testing::Message() << "Testing "
                   << kTestPaths[i].value() << " " << relatives[j].path);
      base::FilePath virtual_path =
          isolated_context()->CreateVirtualRootPath(id_).AppendASCII(
              names_[i]).Append(relatives[j].path);

      FileSystemURL cracked = isolated_context()->CreateCrackedFileSystemURL(
          GURL("http://chromium.org"), kFileSystemTypeIsolated, virtual_path);

      ASSERT_EQ(relatives[j].valid, cracked.is_valid());

      if (!relatives[j].valid)
        continue;
      ASSERT_EQ(GURL("http://chromium.org"), cracked.origin());
      ASSERT_EQ(kTestPaths[i].Append(relatives[j].path)
                    .NormalizePathSeparators().value(),
                cracked.path().value());
      ASSERT_EQ(virtual_path.NormalizePathSeparators(), cracked.virtual_path());
      ASSERT_EQ(id_, cracked.filesystem_id());
      ASSERT_EQ(kFileSystemTypeDragged, cracked.type());
      ASSERT_EQ(kFileSystemTypeIsolated, cracked.mount_type());
    }
  }
}

TEST_F(IsolatedContextTest, TestWithVirtualRoot) {
  std::string cracked_id;
  base::FilePath cracked_path;
  FileSystemMountOption cracked_option;

  // Trying to crack virtual root "/" returns true but with empty cracked path
  // as "/" of the isolated filesystem is a pure virtual directory
  // that has no corresponding platform directory.
  base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_);
  ASSERT_TRUE(isolated_context()->CrackVirtualPath(
      virtual_path, &cracked_id, NULL, NULL, &cracked_path, &cracked_option));
  ASSERT_EQ(FPL(""), cracked_path.value());
  ASSERT_EQ(id_, cracked_id);

  // Trying to crack "/foo" should fail (because "foo" is not the one
  // included in the kTestPaths).
  virtual_path = isolated_context()->CreateVirtualRootPath(
      id_).AppendASCII("foo");
  ASSERT_FALSE(isolated_context()->CrackVirtualPath(
      virtual_path, &cracked_id, NULL, NULL, &cracked_path, &cracked_option));
}

TEST_F(IsolatedContextTest, CanHandleURL) {
  const GURL test_origin("http://chromium.org");
  const base::FilePath test_path(FPL("/mount"));

  // Should handle isolated file system.
  EXPECT_TRUE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeIsolated));

  // Shouldn't handle the rest.
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeExternal));
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeTemporary));
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypePersistent));
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeTest));
  // Not even if it's isolated subtype.
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeNativeLocal));
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeDragged));
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeNativeMedia));
  EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType(
      storage::kFileSystemTypeDeviceMedia));
}

TEST_F(IsolatedContextTest, VirtualFileSystemTests) {
  // Should be able to register empty and non-absolute paths
  std::string empty_fsid = isolated_context()->RegisterFileSystemForVirtualPath(
      storage::kFileSystemTypeIsolated, "_", base::FilePath());
  std::string relative_fsid =
      isolated_context()->RegisterFileSystemForVirtualPath(
          storage::kFileSystemTypeIsolated,
          "_",
          base::FilePath(FPL("relpath")));
  ASSERT_FALSE(empty_fsid.empty());
  ASSERT_FALSE(relative_fsid.empty());

  // Make sure that filesystem root is not prepended to cracked virtual paths.
  base::FilePath database_root = base::FilePath(DRIVE FPL("/database_path"));
  std::string database_fsid =
      isolated_context()->RegisterFileSystemForVirtualPath(
          storage::kFileSystemTypeIsolated, "_", database_root);

  base::FilePath test_virtual_path =
      base::FilePath().AppendASCII("virtualdir").AppendASCII("virtualfile.txt");

  base::FilePath whole_virtual_path =
      isolated_context()->CreateVirtualRootPath(database_fsid)
          .AppendASCII("_").Append(test_virtual_path);

  std::string cracked_id;
  base::FilePath cracked_path;
  std::string cracked_inner_id;
  FileSystemMountOption cracked_option;
  ASSERT_TRUE(isolated_context()->CrackVirtualPath(
      whole_virtual_path, &cracked_id, NULL, &cracked_inner_id,
      &cracked_path, &cracked_option));
  ASSERT_EQ(database_fsid, cracked_id);
  ASSERT_EQ(test_virtual_path, cracked_path);
  EXPECT_TRUE(cracked_inner_id.empty());
}

}  // namespace content
