// 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 <set>

#include "base/file_util.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/fileapi/native_file_util.h"

using fileapi::FileSystemFileUtil;
using fileapi::FileSystemOperation;
using fileapi::NativeFileUtil;

namespace content {

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

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

 protected:
  base::FilePath Path() {
    return data_dir_.path();
  }

  base::FilePath Path(const char* file_name) {
    return data_dir_.path().AppendASCII(file_name);
  }

  bool FileExists(const base::FilePath& path) {
    return base::PathExists(path) &&
           !base::DirectoryExists(path);
  }

  int64 GetSize(const base::FilePath& path) {
    base::File::Info info;
    base::GetFileInfo(path, &info);
    return info.size;
  }

 private:
  base::ScopedTempDir data_dir_;

  DISALLOW_COPY_AND_ASSIGN(NativeFileUtilTest);
};

TEST_F(NativeFileUtilTest, CreateCloseAndDeleteFile) {
  base::FilePath file_name = Path("test_file");
  int flags = base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
  base::File file =
      NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_CREATE | flags);
  ASSERT_TRUE(file.IsValid());
  ASSERT_TRUE(file.created());

  EXPECT_TRUE(base::PathExists(file_name));
  EXPECT_TRUE(NativeFileUtil::PathExists(file_name));
  EXPECT_EQ(0, GetSize(file_name));
  file.Close();

  file = NativeFileUtil::CreateOrOpen(file_name, base::File::FLAG_OPEN | flags);
  ASSERT_TRUE(file.IsValid());
  ASSERT_FALSE(file.created());
  file.Close();

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::DeleteFile(file_name));
  EXPECT_FALSE(base::PathExists(file_name));
  EXPECT_FALSE(NativeFileUtil::PathExists(file_name));
}

TEST_F(NativeFileUtilTest, EnsureFileExists) {
  base::FilePath file_name = Path("foobar");
  bool created = false;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(file_name, &created));
  ASSERT_TRUE(created);

  EXPECT_TRUE(FileExists(file_name));
  EXPECT_EQ(0, GetSize(file_name));

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(file_name, &created));
  EXPECT_FALSE(created);
}

TEST_F(NativeFileUtilTest, CreateAndDeleteDirectory) {
  base::FilePath dir_name = Path("test_dir");
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CreateDirectory(dir_name,
                                            false /* exclusive */,
                                            false /* recursive */));

  EXPECT_TRUE(NativeFileUtil::DirectoryExists(dir_name));
  EXPECT_TRUE(base::DirectoryExists(dir_name));

  ASSERT_EQ(base::File::FILE_ERROR_EXISTS,
            NativeFileUtil::CreateDirectory(dir_name,
                                            true /* exclusive */,
                                            false /* recursive */));

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::DeleteDirectory(dir_name));
  EXPECT_FALSE(base::DirectoryExists(dir_name));
  EXPECT_FALSE(NativeFileUtil::DirectoryExists(dir_name));
}

TEST_F(NativeFileUtilTest, TouchFileAndGetFileInfo) {
  base::FilePath file_name = Path("test_file");
  base::File::Info native_info;
  ASSERT_EQ(base::File::FILE_ERROR_NOT_FOUND,
            NativeFileUtil::GetFileInfo(file_name, &native_info));

  bool created = false;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(file_name, &created));
  ASSERT_TRUE(created);

  base::File::Info info;
  ASSERT_TRUE(base::GetFileInfo(file_name, &info));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::GetFileInfo(file_name, &native_info));
  ASSERT_EQ(info.size, native_info.size);
  ASSERT_EQ(info.is_directory, native_info.is_directory);
  ASSERT_EQ(info.is_symbolic_link, native_info.is_symbolic_link);
  ASSERT_EQ(info.last_modified, native_info.last_modified);
  ASSERT_EQ(info.last_accessed, native_info.last_accessed);
  ASSERT_EQ(info.creation_time, native_info.creation_time);

  const base::Time new_accessed =
      info.last_accessed + base::TimeDelta::FromHours(10);
  const base::Time new_modified =
      info.last_modified + base::TimeDelta::FromHours(5);

  EXPECT_EQ(base::File::FILE_OK,
            NativeFileUtil::Touch(file_name,
                                  new_accessed, new_modified));

  ASSERT_TRUE(base::GetFileInfo(file_name, &info));
  EXPECT_EQ(new_accessed, info.last_accessed);
  EXPECT_EQ(new_modified, info.last_modified);
}

TEST_F(NativeFileUtilTest, CreateFileEnumerator) {
  base::FilePath path_1 = Path("dir1");
  base::FilePath path_2 = Path("file1");
  base::FilePath path_11 = Path("dir1").AppendASCII("file11");
  base::FilePath path_12 = Path("dir1").AppendASCII("dir12");
  base::FilePath path_121 =
      Path("dir1").AppendASCII("dir12").AppendASCII("file121");
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CreateDirectory(path_1, false, false));
  bool created = false;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(path_2, &created));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(path_11, &created));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CreateDirectory(path_12, false, false));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(path_121, &created));

  {
    scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator =
        NativeFileUtil::CreateFileEnumerator(Path(), false);
    std::set<base::FilePath> set;
    set.insert(path_1);
    set.insert(path_2);
    for (base::FilePath path = enumerator->Next(); !path.empty();
         path = enumerator->Next())
      EXPECT_EQ(1U, set.erase(path));
    EXPECT_TRUE(set.empty());
  }

  {
    scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator =
        NativeFileUtil::CreateFileEnumerator(Path(), true);
        std::set<base::FilePath> set;
    set.insert(path_1);
    set.insert(path_2);
    set.insert(path_11);
    set.insert(path_12);
    set.insert(path_121);
    for (base::FilePath path = enumerator->Next(); !path.empty();
         path = enumerator->Next())
      EXPECT_EQ(1U, set.erase(path));
    EXPECT_TRUE(set.empty());
  }
}

TEST_F(NativeFileUtilTest, Truncate) {
  base::FilePath file_name = Path("truncated");
  bool created = false;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(file_name, &created));
  ASSERT_TRUE(created);

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::Truncate(file_name, 1020));

  EXPECT_TRUE(FileExists(file_name));
  EXPECT_EQ(1020, GetSize(file_name));
}

TEST_F(NativeFileUtilTest, CopyFile) {
  base::FilePath from_file = Path("fromfile");
  base::FilePath to_file1 = Path("tofile1");
  base::FilePath to_file2 = Path("tofile2");
  const NativeFileUtil::CopyOrMoveMode nosync = NativeFileUtil::COPY_NOSYNC;
  const NativeFileUtil::CopyOrMoveMode sync = NativeFileUtil::COPY_SYNC;
  bool created = false;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(from_file, &created));
  ASSERT_TRUE(created);

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::Truncate(from_file, 1020));

  EXPECT_TRUE(FileExists(from_file));
  EXPECT_EQ(1020, GetSize(from_file));

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_file1, FileSystemOperation::OPTION_NONE, nosync));

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_file2, FileSystemOperation::OPTION_NONE, sync));

  EXPECT_TRUE(FileExists(from_file));
  EXPECT_EQ(1020, GetSize(from_file));
  EXPECT_TRUE(FileExists(to_file1));
  EXPECT_EQ(1020, GetSize(to_file1));
  EXPECT_TRUE(FileExists(to_file2));
  EXPECT_EQ(1020, GetSize(to_file2));

  base::FilePath dir = Path("dir");
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CreateDirectory(dir, false, false));
  ASSERT_TRUE(base::DirectoryExists(dir));
  base::FilePath to_dir_file = dir.AppendASCII("file");
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_dir_file,
                FileSystemOperation::OPTION_NONE, nosync));
  EXPECT_TRUE(FileExists(to_dir_file));
  EXPECT_EQ(1020, GetSize(to_dir_file));

  // Following tests are error checking.
  // Source doesn't exist.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
            NativeFileUtil::CopyOrMoveFile(
                Path("nonexists"), Path("file"),
                FileSystemOperation::OPTION_NONE, nosync));

  // Source is not a file.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE,
            NativeFileUtil::CopyOrMoveFile(
                dir, Path("file"), FileSystemOperation::OPTION_NONE, nosync));
  // Destination is not a file.
  EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
            NativeFileUtil::CopyOrMoveFile(
                from_file, dir, FileSystemOperation::OPTION_NONE, nosync));
  // Destination's parent doesn't exist.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
            NativeFileUtil::CopyOrMoveFile(
                from_file, Path("nodir").AppendASCII("file"),
                FileSystemOperation::OPTION_NONE, nosync));
  // Destination's parent is a file.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
            NativeFileUtil::CopyOrMoveFile(
                from_file, Path("tofile1").AppendASCII("file"),
                FileSystemOperation::OPTION_NONE, nosync));
}

TEST_F(NativeFileUtilTest, MoveFile) {
  base::FilePath from_file = Path("fromfile");
  base::FilePath to_file = Path("tofile");
  const NativeFileUtil::CopyOrMoveMode move = NativeFileUtil::MOVE;
  bool created = false;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(from_file, &created));
  ASSERT_TRUE(created);

  ASSERT_EQ(base::File::FILE_OK, NativeFileUtil::Truncate(from_file, 1020));

  EXPECT_TRUE(FileExists(from_file));
  EXPECT_EQ(1020, GetSize(from_file));

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_file, FileSystemOperation::OPTION_NONE, move));

  EXPECT_FALSE(FileExists(from_file));
  EXPECT_TRUE(FileExists(to_file));
  EXPECT_EQ(1020, GetSize(to_file));

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(from_file, &created));
  ASSERT_TRUE(FileExists(from_file));
  ASSERT_EQ(base::File::FILE_OK, NativeFileUtil::Truncate(from_file, 1020));

  base::FilePath dir = Path("dir");
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CreateDirectory(dir, false, false));
  ASSERT_TRUE(base::DirectoryExists(dir));
  base::FilePath to_dir_file = dir.AppendASCII("file");
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_dir_file,
                FileSystemOperation::OPTION_NONE, move));
  EXPECT_FALSE(FileExists(from_file));
  EXPECT_TRUE(FileExists(to_dir_file));
  EXPECT_EQ(1020, GetSize(to_dir_file));

  // Following is error checking.
  // Source doesn't exist.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
            NativeFileUtil::CopyOrMoveFile(
                Path("nonexists"), Path("file"),
                FileSystemOperation::OPTION_NONE, move));

  // Source is not a file.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_A_FILE,
            NativeFileUtil::CopyOrMoveFile(
                dir, Path("file"), FileSystemOperation::OPTION_NONE, move));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(from_file, &created));
  ASSERT_TRUE(FileExists(from_file));
  // Destination is not a file.
  EXPECT_EQ(base::File::FILE_ERROR_INVALID_OPERATION,
            NativeFileUtil::CopyOrMoveFile(
                from_file, dir, FileSystemOperation::OPTION_NONE, move));

  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(from_file, &created));
  ASSERT_TRUE(FileExists(from_file));
  // Destination's parent doesn't exist.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
            NativeFileUtil::CopyOrMoveFile(
                from_file, Path("nodir").AppendASCII("file"),
                FileSystemOperation::OPTION_NONE, move));
  // Destination's parent is a file.
  EXPECT_EQ(base::File::FILE_ERROR_NOT_FOUND,
            NativeFileUtil::CopyOrMoveFile(
                from_file, Path("tofile1").AppendASCII("file"),
                FileSystemOperation::OPTION_NONE, move));
}

TEST_F(NativeFileUtilTest, PreserveLastModified) {
  base::FilePath from_file = Path("fromfile");
  base::FilePath to_file1 = Path("tofile1");
  base::FilePath to_file2 = Path("tofile2");
  base::FilePath to_file3 = Path("tofile3");
  bool created = false;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::EnsureFileExists(from_file, &created));
  ASSERT_TRUE(created);
  EXPECT_TRUE(FileExists(from_file));

  base::File::Info file_info1;
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::GetFileInfo(from_file, &file_info1));

  // Test for copy (nosync).
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_file1,
                FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
                NativeFileUtil::COPY_NOSYNC));

  base::File::Info file_info2;
  ASSERT_TRUE(FileExists(to_file1));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::GetFileInfo(to_file1, &file_info2));
  EXPECT_EQ(file_info1.last_modified, file_info2.last_modified);

  // Test for copy (sync).
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_file2,
                FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
                NativeFileUtil::COPY_SYNC));

  ASSERT_TRUE(FileExists(to_file2));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::GetFileInfo(to_file1, &file_info2));
  EXPECT_EQ(file_info1.last_modified, file_info2.last_modified);

  // Test for move.
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::CopyOrMoveFile(
                from_file, to_file3,
                FileSystemOperation::OPTION_PRESERVE_LAST_MODIFIED,
                NativeFileUtil::MOVE));

  ASSERT_TRUE(FileExists(to_file3));
  ASSERT_EQ(base::File::FILE_OK,
            NativeFileUtil::GetFileInfo(to_file2, &file_info2));
  EXPECT_EQ(file_info1.last_modified, file_info2.last_modified);
}

}  // namespace content
