/*
 * Copyright 2010 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Author: jmarantz@google.com (Joshua Marantz)

#include "pagespeed/kernel/base/file_system_test_base.h"

#include <cstddef>
#include <algorithm>
#include <vector>

#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/file_system.h"
#include "pagespeed/kernel/base/google_message_handler.h"
#include "pagespeed/kernel/base/gtest.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/timer.h"

namespace net_instaweb {

// TODO(huibao): Rename FileSystemTest to FileSystemTestBase.

FileSystemTest::FileSystemTest()
    : test_tmpdir_(StrCat(GTestTempDir(), "/file_system_test_base")) {}
FileSystemTest::~FileSystemTest() {}

// Used by TestDirInfo to make sure vector of FileInfos can be compared
// consistently
struct CompareByName {
 public:
  bool operator()(const FileSystem::FileInfo& one,
                  const FileSystem::FileInfo& two) const {
    return one.name < two.name;
  }
};

GoogleString FileSystemTest::WriteNewFile(const StringPiece& suffix,
                                          const GoogleString& content) {
  GoogleString filename = StrCat(test_tmpdir(), suffix);

  // Make sure we don't read an old file.
  DeleteRecursively(filename);
  EXPECT_TRUE(file_system()->WriteFile(filename.c_str(), content, &handler_));

  return filename;
}

// Check that a file has been read.
void FileSystemTest::CheckRead(const GoogleString& filename,
                               const GoogleString& expected_contents) {
  GoogleString buffer;
  ASSERT_TRUE(file_system()->ReadFile(filename.c_str(), &buffer, &handler_));
  EXPECT_EQ(buffer, expected_contents);
}

// Check that a file has been read.
void FileSystemTest::CheckInputFileRead(const GoogleString& filename,
                                        const GoogleString& expected_contents) {
  FileSystem::InputFile* file =
      file_system()->OpenInputFile(filename.c_str(), &handler_);
  ASSERT_TRUE(file != NULL);
  GoogleString buffer;
  ASSERT_TRUE(file_system()->ReadFile(file, &buffer, &handler_));
  EXPECT_EQ(buffer, expected_contents);
}

// Make sure we can no longer read the file by the old name.  Note
// that this will spew some error messages into the log file, and
// we can add a null_message_handler implementation to
// swallow them, if they become annoying.
void FileSystemTest::CheckDoesNotExist(const GoogleString& filename) {
  GoogleString read_buffer;
  EXPECT_FALSE(file_system()->ReadFile(filename.c_str(), &read_buffer,
                                       &handler_));
  EXPECT_TRUE(file_system()->Exists(filename.c_str(), &handler_).is_false());
}

// Write a named file, then read it.
void FileSystemTest::TestWriteRead() {
  GoogleString filename = StrCat(test_tmpdir(), "/write.txt");
  GoogleString msg("Hello, world!");

  DeleteRecursively(filename);
  FileSystem::OutputFile* ofile = file_system()->OpenOutputFile(
      filename.c_str(), &handler_);
  ASSERT_TRUE(ofile != NULL);
  EXPECT_TRUE(ofile->Write(msg, &handler_));
  EXPECT_TRUE(file_system()->Close(ofile, &handler_));
  CheckRead(filename, msg);
  CheckInputFileRead(filename, msg);
}

// Write a temp file, then read it.
void FileSystemTest::TestTemp() {
  GoogleString prefix = StrCat(test_tmpdir(), "/temp_prefix");
  FileSystem::OutputFile* ofile = file_system()->OpenTempFile(
      prefix, &handler_);
  ASSERT_TRUE(ofile != NULL);
  GoogleString filename(ofile->filename());
  GoogleString msg("Hello, world!");
  EXPECT_TRUE(ofile->Write(msg, &handler_));
  EXPECT_TRUE(file_system()->Close(ofile, &handler_));

  CheckRead(filename, msg);
}

// Write a temp file, close it, append to it, then read it.
void FileSystemTest::TestAppend() {
  GoogleString prefix = StrCat(test_tmpdir(), "/temp_prefix");
  FileSystem::OutputFile* ofile = file_system()->OpenTempFile(
      prefix, &handler_);
  ASSERT_TRUE(ofile != NULL);
  const GoogleString filename(ofile->filename());
  EXPECT_TRUE(ofile->Write("Hello", &handler_));
  EXPECT_TRUE(file_system()->Close(ofile, &handler_));
  ofile = file_system()->OpenOutputFileForAppend(filename.c_str(), &handler_);
  EXPECT_TRUE(ofile->Write(" world!", &handler_));
  EXPECT_TRUE(file_system()->Close(ofile, &handler_));

  CheckRead(filename, "Hello world!");
}

// Write a temp file, rename it, then read it.
void FileSystemTest::TestRename() {
  GoogleString from_text = "Now is time time";
  GoogleString to_file = StrCat(test_tmpdir(), "/to.txt");
  DeleteRecursively(to_file);

  GoogleString from_file = WriteNewFile("/from.txt", from_text);
  ASSERT_TRUE(file_system()->RenameFile(from_file.c_str(), to_file.c_str(),
                                        &handler_));

  CheckDoesNotExist(from_file);
  CheckRead(to_file, from_text);
}

// Write a file and successfully delete it.
void FileSystemTest::TestRemove() {
  GoogleString filename = WriteNewFile("/remove.txt", "Goodbye, world!");
  ASSERT_TRUE(file_system()->RemoveFile(filename.c_str(), &handler_));
  CheckDoesNotExist(filename);
}

// Write a file and check that it exists.
void FileSystemTest::TestExists() {
  GoogleString filename = WriteNewFile("/exists.txt", "I'm here.");
  ASSERT_TRUE(file_system()->Exists(filename.c_str(), &handler_).is_true());
}

// Create a file along with its directory which does not exist.
void FileSystemTest::TestCreateFileInDir() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  GoogleString filename = dir_name + "/file-in-dir.txt";

  FileSystem::OutputFile* file =
      file_system()->OpenOutputFile(filename.c_str(), &handler_);
  ASSERT_TRUE(file != NULL);
  file_system()->Close(file, &handler_);
}


// Make a directory and check that files may be placed in it.
void FileSystemTest::TestMakeDir() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  GoogleString filename = dir_name + "/file-in-dir.txt";

  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  // ... but we can open a file after we've created the directory.
  FileSystem::OutputFile* file =
      file_system()->OpenOutputFile(filename.c_str(), &handler_);
  ASSERT_TRUE(file != NULL);
  file_system()->Close(file, &handler_);
}

// Make a directory and then remove it.
void FileSystemTest::TestRemoveDir() {
  // mem_file_system depends on dir_names ending with a '/'
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir/");
  DeleteRecursively(dir_name);
  GoogleString filename = dir_name + "file-in-dir.txt";

  EXPECT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  EXPECT_TRUE(file_system()->Exists(dir_name.c_str(), &handler_).is_true());

  // First test that non-empty directories don't get deleted
  FileSystem::OutputFile* file =
      file_system()->OpenOutputFile(filename.c_str(), &handler_);
  EXPECT_TRUE(file != NULL);
  file_system()->Close(file, &handler_);
  EXPECT_FALSE(file_system()->RemoveDir(dir_name.c_str(), &handler_));
  EXPECT_TRUE(file_system()->Exists(filename.c_str(), &handler_).is_true());
  EXPECT_TRUE(file_system()->Exists(dir_name.c_str(), &handler_).is_true());

  // Then test that empty directories do get deleted
  EXPECT_TRUE(file_system()->RemoveFile(filename.c_str(), &handler_));
  EXPECT_TRUE(file_system()->RemoveDir(dir_name.c_str(), &handler_));
  EXPECT_TRUE(file_system()->Exists(filename.c_str(), &handler_).is_false());
  EXPECT_TRUE(file_system()->Exists(dir_name.c_str(), &handler_).is_false());
}

// Make a directory and check that it is a directory.
void FileSystemTest::TestIsDir() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/this_is_a_dir");
  DeleteRecursively(dir_name);

  // Make sure we don't think the directory is there when it isn't ...
  ASSERT_TRUE(file_system()->IsDir(dir_name.c_str(), &handler_).is_false());
  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  // ... and that we do think it's there when it is.
  ASSERT_TRUE(file_system()->IsDir(dir_name.c_str(), &handler_).is_true());

  // Make sure that we don't think a regular file is a directory.
  GoogleString filename = dir_name + "/this_is_a_file.txt";
  GoogleString content = "I'm not a directory.";
  ASSERT_TRUE(file_system()->WriteFile(filename.c_str(), content, &handler_));
  ASSERT_TRUE(file_system()->IsDir(filename.c_str(), &handler_).is_false());
}

// Recursively make directories and check that it worked.
void FileSystemTest::TestRecursivelyMakeDir() {
  GoogleString base = StrCat(test_tmpdir(), "/base");
  GoogleString long_path = base + "/dir/of/a/really/deep/hierarchy";
  DeleteRecursively(base);

  // Make sure we don't think the directory is there when it isn't ...
  ASSERT_TRUE(file_system()->IsDir(long_path.c_str(), &handler_).is_false());
  ASSERT_TRUE(file_system()->RecursivelyMakeDir(long_path, &handler_));
  // ... and that we do think it's there when it is.
  ASSERT_TRUE(file_system()->IsDir(long_path.c_str(), &handler_).is_true());
}

// Check that we cannot create a directory we do not have permissions for.
// Note: depends upon root dir not being writable.
void FileSystemTest::TestRecursivelyMakeDir_NoPermission() {
  GoogleString base = "/bogus-dir";
  GoogleString path = base + "/no/permission/to/make/this/dir";

  // Make sure the bogus bottom level directory is not there.
  ASSERT_TRUE(file_system()->Exists(base.c_str(), &handler_).is_false());
  // We do not have permission to create it.
  ASSERT_FALSE(file_system()->RecursivelyMakeDir(path, &handler_));
}

// Check that we cannot create a directory below a file.
void FileSystemTest::TestRecursivelyMakeDir_FileInPath() {
  GoogleString base = StrCat(test_tmpdir(), "/file-in-path");
  GoogleString filename = base + "/this-is-a-file";
  GoogleString bad_path = filename + "/some/more/path";
  DeleteRecursively(base);
  GoogleString content = "Your path must end here. You shall not pass!";

  ASSERT_TRUE(file_system()->MakeDir(base.c_str(), &handler_));
  ASSERT_TRUE(file_system()->WriteFile(filename.c_str(), content, &handler_));
  ASSERT_FALSE(file_system()->RecursivelyMakeDir(bad_path, &handler_));
}

void FileSystemTest::TestListContents() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  GoogleString filename1 = dir_name + "/file-in-dir.txt";
  GoogleString filename2 = dir_name + "/another-file-in-dir.txt";
  GoogleString content = "Lorem ipsum dolor sit amet";

  StringVector mylist;

  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  ASSERT_TRUE(file_system()->WriteFile(filename1.c_str(), content, &handler_));
  ASSERT_TRUE(file_system()->WriteFile(filename2.c_str(), content, &handler_));
  EXPECT_TRUE(file_system()->ListContents(dir_name, &mylist, &handler_));
  EXPECT_EQ(size_t(2), mylist.size());
  // Make sure our filenames are in there
  EXPECT_FALSE(filename1.compare(mylist.at(0))
               && filename1.compare(mylist.at(1)));
  EXPECT_FALSE(filename2.compare(mylist.at(0))
               && filename2.compare(mylist.at(1)));
}

void FileSystemTest::TestAtime() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  GoogleString filename1 = "file-in-dir.txt";
  GoogleString filename2 = "another-file-in-dir.txt";
  GoogleString full_path1 = dir_name + "/" + filename1;
  GoogleString full_path2 = dir_name + "/" + filename2;
  GoogleString content = "Lorem ipsum dolor sit amet";
  // We need to sleep a bit between accessing files so that the
  // difference shows up in in atimes which are measured in seconds.
  unsigned int sleep_us = 1500000;

  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  ASSERT_TRUE(file_system()->WriteFile(full_path1.c_str(), content, &handler_));
  ASSERT_TRUE(file_system()->WriteFile(full_path2.c_str(), content, &handler_));

  int64 atime1, atime2;
  CheckRead(full_path1, content);
  timer()->SleepUs(sleep_us);
  CheckRead(full_path2, content);
  ASSERT_TRUE(file_system()->Atime(full_path1, &atime1, &handler_));
  ASSERT_TRUE(file_system()->Atime(full_path2, &atime2, &handler_));
  EXPECT_LT(atime1, atime2);

  CheckRead(full_path2, content);
  timer()->SleepUs(sleep_us);
  CheckRead(full_path1, content);
  ASSERT_TRUE(file_system()->Atime(full_path1, &atime1, &handler_));
  ASSERT_TRUE(file_system()->Atime(full_path2, &atime2, &handler_));
  EXPECT_LT(atime2, atime1);
}

void FileSystemTest::TestMtime() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  GoogleString filename1 = "file-in-dir.txt";
  GoogleString filename2 = "another-file-in-dir.txt";
  GoogleString full_path1 = dir_name + "/" + filename1;
  GoogleString full_path2 = dir_name + "/" + filename2;
  GoogleString content = "Lorem ipsum dolor sit amet";
  // We need to sleep a bit between accessing files so that the
  // difference shows up in in atimes which are measured in seconds.
  unsigned int sleep_us = 1500000;

  // Setup directory to play in.
  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));

  // Write two files with pause between
  ASSERT_TRUE(file_system()->WriteFile(full_path1.c_str(), content, &handler_));
  timer()->SleepUs(sleep_us);
  ASSERT_TRUE(file_system()->WriteFile(full_path2.c_str(), content, &handler_));

  int64 mtime1_orig, mtime2_orig;
  // Check that File1 was created before File2.
  ASSERT_TRUE(file_system()->Mtime(full_path1, &mtime1_orig, &handler_));
  ASSERT_TRUE(file_system()->Mtime(full_path2, &mtime2_orig, &handler_));
  EXPECT_LT(mtime1_orig, mtime2_orig);

  int64 mtime1_read, mtime2_read;
  // And that even if you read from File1 later, the C-time is still preserved.
  timer()->SleepUs(sleep_us);
  CheckRead(full_path1, content);
  ASSERT_TRUE(file_system()->Mtime(full_path1, &mtime1_read, &handler_));
  ASSERT_TRUE(file_system()->Mtime(full_path2, &mtime2_read, &handler_));
  EXPECT_EQ(mtime1_orig, mtime1_read);
  EXPECT_EQ(mtime2_orig, mtime2_read);

  int64 mtime1_recreate, mtime2_recreate;
  // But if we delete File1 and re-create it, the C-time is updated.
  timer()->SleepUs(sleep_us);
  ASSERT_TRUE(file_system()->RemoveFile(full_path1.c_str(), &handler_));
  ASSERT_TRUE(file_system()->WriteFile(full_path1.c_str(), content, &handler_));
  ASSERT_TRUE(file_system()->Mtime(full_path1, &mtime1_recreate, &handler_));
  ASSERT_TRUE(file_system()->Mtime(full_path2, &mtime2_recreate, &handler_));
  EXPECT_LT(mtime1_orig, mtime1_recreate);
  EXPECT_EQ(mtime2_orig, mtime2_recreate);

  EXPECT_GT(mtime1_recreate, mtime2_recreate);
}

void FileSystemTest::TestDirInfo() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  GoogleString dir_name2 = dir_name + "/make_dir2";
  GoogleString dir_name3 = dir_name + "/make_dir3/";
  GoogleString filename1 = "another-file-in-dir.txt";
  GoogleString filename2 = "file-in-dir.txt";
  GoogleString full_path1 = dir_name2 + "/" + filename1;
  GoogleString full_path2 = dir_name2 + "/" + filename2;
  GoogleString content1 = "12345";
  // Make content2 longer than the default block size of 4096 to make sure disk
  // based file systems are calculating the on-disk size, not just apparent size
  // of file. stdio and apr file systems should report 8192 as the size of
  // content2.
  GoogleString content2(4097, 'a');
  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  ASSERT_TRUE(file_system()->MakeDir(dir_name2.c_str(), &handler_));
  ASSERT_TRUE(file_system()->MakeDir(dir_name3.c_str(), &handler_));
  ASSERT_TRUE(file_system()->WriteFile(full_path1.c_str(),
                                       content1, &handler_));
  ASSERT_TRUE(file_system()->WriteFile(full_path2.c_str(),
                                       content2, &handler_));

  int64 size;
  EXPECT_TRUE(file_system()->Size(full_path1, &size, &handler_));
  EXPECT_EQ(FileSize(content1), size);
  EXPECT_TRUE(file_system()->Size(full_path2, &size, &handler_));
  EXPECT_EQ(FileSize(content2), size);

  FileSystem::DirInfo dir_info;
  FileSystem::DirInfo dir_info2;
  file_system()->GetDirInfo(dir_name2, &dir_info2, &handler_);
  EXPECT_EQ(FileSize(content1) + FileSize(content2), dir_info2.size_bytes);
  EXPECT_EQ(2, dir_info2.inode_count);
  EXPECT_EQ(static_cast<size_t>(2), dir_info2.files.size());
  // dir_info.files is not guaranteed to be in any particular order, and in fact
  // come back in different order for mem and apr filesystems, so sort it so
  // that the comparison is consistent.
  std::sort(dir_info2.files.begin(), dir_info2.files.end(), CompareByName());
  EXPECT_STREQ(full_path1, dir_info2.files[0].name);
  EXPECT_STREQ(full_path2, dir_info2.files[1].name);
  EXPECT_EQ(static_cast<size_t>(0), dir_info2.empty_dirs.size());

  file_system()->GetDirInfo(dir_name, &dir_info, &handler_);
  int dir_size = DefaultDirSize();
  EXPECT_EQ(dir_size * 2 + FileSize(content1) + FileSize(content2),
            dir_info.size_bytes);
  EXPECT_EQ(4, dir_info.inode_count);
  std::sort(dir_info.files.begin(), dir_info.files.end(), CompareByName());
  EXPECT_STREQ(full_path1, dir_info.files[0].name);
  EXPECT_STREQ(full_path2, dir_info.files[1].name);
  EXPECT_EQ(static_cast<size_t>(1), dir_info.empty_dirs.size());
}

void FileSystemTest::TestLock() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  GoogleString lock_name = dir_name + "/lock";
  // Acquire the lock
  EXPECT_TRUE(file_system()->TryLock(lock_name, &handler_).is_true());
  // Can't re-acquire the lock
  EXPECT_TRUE(file_system()->TryLock(lock_name, &handler_).is_false());
  // Release the lock
  EXPECT_TRUE(file_system()->Unlock(lock_name, &handler_));
  // Do it all again to make sure the release worked.
  EXPECT_TRUE(file_system()->TryLock(lock_name, &handler_).is_true());
  EXPECT_TRUE(file_system()->TryLock(lock_name, &handler_).is_false());
  EXPECT_TRUE(file_system()->Unlock(lock_name, &handler_));
}

// Test lock timeout; assumes the file system has at least 1-second creation
// granularity.
void FileSystemTest::TestLockTimeout() {
  GoogleString dir_name = StrCat(test_tmpdir(), "/make_dir");
  DeleteRecursively(dir_name);
  ASSERT_TRUE(file_system()->MakeDir(dir_name.c_str(), &handler_));
  GoogleString lock_name = dir_name + "/lock";
  // Acquire the lock
  EXPECT_TRUE(file_system()->TryLockWithTimeout(lock_name, Timer::kSecondMs,
                                                timer(), &handler_).is_true());
  // Immediate re-acquire should fail.  Steal time deliberately long so we don't
  // steal by mistake (since we're running in non-mock time).
  EXPECT_TRUE(file_system()->TryLockWithTimeout(lock_name, Timer::kMinuteMs,
                                                timer(), &handler_).is_false());
  // Wait 1 second so that we're definitely different from ctime.
  // Now we should seize lock.
  timer()->SleepMs(Timer::kSecondMs);
  EXPECT_TRUE(file_system()->TryLockWithTimeout(lock_name, Timer::kSecondMs,
                                                timer(), &handler_).is_true());
  // Lock should still be held.
  EXPECT_TRUE(file_system()->TryLock(lock_name, &handler_).is_false());
  EXPECT_TRUE(file_system()->Unlock(lock_name, &handler_));
  // The result of this second unlock is unknown, but it ought not to crash.
  file_system()->Unlock(lock_name, &handler_);
  // Lock should now be unambiguously unlocked.
  EXPECT_TRUE(file_system()->TryLock(lock_name, &handler_).is_true());
}

}  // namespace net_instaweb
