// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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.
#include <fcntl.h>
#include <limits.h>
#include <unistd.h>

#include <algorithm>

#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
#include "gtest/gtest.h"

namespace blaze_util {

using std::pair;
using std::string;
using std::vector;

static bool Symlink(const string& old_path, const string& new_path) {
  return symlink(old_path.c_str(), new_path.c_str()) == 0;
}

static bool CreateEmptyFile(const string& path) {
  // From the man page of open (man 2 open):
  // int open(const char *pathname, int flags, mode_t mode);
  //
  // mode specifies the permissions to use in case a new file is created.
  // This argument must be supplied when O_CREAT is specified in flags;
  // if O_CREAT is not specified, then mode is ignored.
  int fd = open(path.c_str(), O_CREAT | O_WRONLY, 0700);
  if (fd == -1) {
    return false;
  }
  return close(fd) == 0;
}

TEST(FilePosixTest, TestDirname) {
  // The Posix version of SplitPath (thus Dirname too, which is implemented on
  // top of it) is not aware of Windows paths.
  ASSERT_EQ("", Dirname(""));
  ASSERT_EQ("/", Dirname("/"));
  ASSERT_EQ("", Dirname("foo"));
  ASSERT_EQ("/", Dirname("/foo"));
  ASSERT_EQ("/foo", Dirname("/foo/"));
  ASSERT_EQ("foo", Dirname("foo/bar"));
  ASSERT_EQ("foo/bar", Dirname("foo/bar/baz"));
  ASSERT_EQ("", Dirname("\\foo"));
  ASSERT_EQ("", Dirname("\\foo\\"));
  ASSERT_EQ("", Dirname("foo\\bar"));
  ASSERT_EQ("", Dirname("foo\\bar\\baz"));
  ASSERT_EQ("foo\\bar", Dirname("foo\\bar/baz\\qux"));
  ASSERT_EQ("c:", Dirname("c:/"));
  ASSERT_EQ("", Dirname("c:\\"));
  ASSERT_EQ("c:", Dirname("c:/foo"));
  ASSERT_EQ("", Dirname("c:\\foo"));
  ASSERT_EQ("", Dirname("\\\\?\\c:\\"));
  ASSERT_EQ("", Dirname("\\\\?\\c:\\foo"));
}

TEST(FilePosixTest, TestBasename) {
  // The Posix version of SplitPath (thus Basename too, which is implemented on
  // top of it) is not aware of Windows paths.
  ASSERT_EQ("", Basename(""));
  ASSERT_EQ("", Basename("/"));
  ASSERT_EQ("foo", Basename("foo"));
  ASSERT_EQ("foo", Basename("/foo"));
  ASSERT_EQ("", Basename("/foo/"));
  ASSERT_EQ("bar", Basename("foo/bar"));
  ASSERT_EQ("baz", Basename("foo/bar/baz"));
  ASSERT_EQ("\\foo", Basename("\\foo"));
  ASSERT_EQ("\\foo\\", Basename("\\foo\\"));
  ASSERT_EQ("foo\\bar", Basename("foo\\bar"));
  ASSERT_EQ("foo\\bar\\baz", Basename("foo\\bar\\baz"));
  ASSERT_EQ("baz\\qux", Basename("foo\\bar/baz\\qux"));
  ASSERT_EQ("qux", Basename("qux"));
  ASSERT_EQ("", Basename("c:/"));
  ASSERT_EQ("c:\\", Basename("c:\\"));
  ASSERT_EQ("foo", Basename("c:/foo"));
  ASSERT_EQ("c:\\foo", Basename("c:\\foo"));
  ASSERT_EQ("\\\\?\\c:\\", Basename("\\\\?\\c:\\"));
  ASSERT_EQ("\\\\?\\c:\\foo", Basename("\\\\?\\c:\\foo"));
}

TEST(FilePosixTest, JoinPath) {
  std::string path = JoinPath("", "");
  ASSERT_EQ("", path);

  path = JoinPath("a", "b");
  ASSERT_EQ("a/b", path);

  path = JoinPath("a/", "b");
  ASSERT_EQ("a/b", path);

  path = JoinPath("a", "/b");
  ASSERT_EQ("a/b", path);

  path = JoinPath("a/", "/b");
  ASSERT_EQ("a/b", path);

  path = JoinPath("/", "/");
  ASSERT_EQ("/", path);
}

void MockDirectoryListingFunction(const string& path,
                                  DirectoryEntryConsumer* consume) {
  if (path == "root") {
    consume->Consume("root/file1", false);
    consume->Consume("root/dir2", true);
    consume->Consume("root/dir1", true);
  } else if (path == "root/dir1") {
    consume->Consume("root/dir1/dir3", true);
    consume->Consume("root/dir1/file2", false);
  } else if (path == "root/dir2") {
    consume->Consume("root/dir2/file3", false);
  } else if (path == "root/dir1/dir3") {
    consume->Consume("root/dir1/dir3/file4", false);
    consume->Consume("root/dir1/dir3/file5", false);
  } else {
    // Unexpected path
    GTEST_FAIL();
  }
}

TEST(FilePosixTest, GetAllFilesUnder) {
  vector<string> result;
  _GetAllFilesUnder("root", &result, &MockDirectoryListingFunction);
  std::sort(result.begin(), result.end());

  vector<string> expected({"root/dir1/dir3/file4", "root/dir1/dir3/file5",
                           "root/dir1/file2", "root/dir2/file3", "root/file1"});
  ASSERT_EQ(expected, result);
}

TEST(FilePosixTest, MakeDirectories) {
  const char* tmp_dir = getenv("TEST_TMPDIR");
  ASSERT_STRNE(tmp_dir, NULL);
  const char* test_src_dir = getenv("TEST_SRCDIR");
  ASSERT_STRNE(NULL, test_src_dir);

  string dir = JoinPath(tmp_dir, "x/y/z");
  bool ok = MakeDirectories(dir, 0755);
  ASSERT_TRUE(ok);

  // Changing permissions on an existing dir should work.
  ok = MakeDirectories(dir, 0750);
  ASSERT_TRUE(ok);
  struct stat filestat = {};
  ASSERT_EQ(0, stat(dir.c_str(), &filestat));
  ASSERT_EQ(0750, filestat.st_mode & 0777);

  // srcdir shouldn't be writable.
  // TODO(ulfjack): Fix this!
  //  string srcdir = JoinPath(test_src_dir, "x/y/z");
  //  ok = MakeDirectories(srcdir, 0755);
  //  ASSERT_FALSE(ok);
  //  ASSERT_EQ(EACCES, errno);

  // Can't make a dir out of a file.
  string non_dir = JoinPath(dir, "w");
  ASSERT_TRUE(CreateEmptyFile(non_dir));
  ok = MakeDirectories(non_dir, 0755);
  ASSERT_FALSE(ok);
  ASSERT_EQ(ENOTDIR, errno);

  // Valid symlink should work.
  string symlink = JoinPath(tmp_dir, "z");
  ASSERT_TRUE(Symlink(dir, symlink));
  ok = MakeDirectories(symlink, 0755);
  ASSERT_TRUE(ok);

  // Error: Symlink to a file.
  symlink = JoinPath(tmp_dir, "w");
  ASSERT_TRUE(Symlink(non_dir, symlink));
  ok = MakeDirectories(symlink, 0755);
  ASSERT_FALSE(ok);
  ASSERT_EQ(ENOTDIR, errno);

  // Error: Symlink to a dir with wrong perms.
  symlink = JoinPath(tmp_dir, "s");
  ASSERT_TRUE(Symlink("/", symlink));

  // These perms will force a chmod()
  // TODO(ulfjack): Fix this!
  //  ok = MakeDirectories(symlink, 0000);
  //  ASSERTFALSE(ok);
  //  ASSERT_EQ(EPERM, errno);

  // Edge cases.
  ASSERT_FALSE(MakeDirectories("", 0755));
  ASSERT_EQ(EACCES, errno);
  ASSERT_FALSE(MakeDirectories("/", 0755));
  ASSERT_EQ(EACCES, errno);
}

TEST(FilePosixTest, HammerMakeDirectories) {
  const char* tmp_dir = getenv("TEST_TMPDIR");
  ASSERT_STRNE(tmp_dir, NULL);

  string path = JoinPath(tmp_dir, "x/y/z");
  // TODO(ulfjack): Fix this!
  //  ASSERT_LE(0, fork());
  //  ASSERT_TRUE(MakeDirectories(path, 0755));
}

TEST(FilePosixTest, PathExists) {
  ASSERT_FALSE(PathExists("/this/should/not/exist/mkay"));
  ASSERT_FALSE(PathExists("non.existent"));
  ASSERT_FALSE(PathExists(""));

  // /usr/bin/yes exists on Linux, Darwin, and MSYS
  ASSERT_TRUE(PathExists("/"));
  ASSERT_TRUE(PathExists("/usr"));
  ASSERT_TRUE(PathExists("/usr/"));
  ASSERT_TRUE(PathExists("/usr/bin/yes"));
}

TEST(FilePosixTest, CanAccess) {
  ASSERT_FALSE(CanReadFile("/this/should/not/exist/mkay"));
  ASSERT_FALSE(CanExecuteFile("/this/should/not/exist/mkay"));
  ASSERT_FALSE(CanAccessDirectory("/this/should/not/exist/mkay"));

  ASSERT_FALSE(CanReadFile("non.existent"));
  ASSERT_FALSE(CanExecuteFile("non.existent"));
  ASSERT_FALSE(CanAccessDirectory("non.existent"));

  const char* tmpdir = getenv("TEST_TMPDIR");
  ASSERT_NE(nullptr, tmpdir);
  ASSERT_NE(0, *tmpdir);

  string dir(JoinPath(tmpdir, "canaccesstest"));
  ASSERT_EQ(0, mkdir(dir.c_str(), 0700));

  ASSERT_FALSE(CanReadFile(dir));
  ASSERT_FALSE(CanExecuteFile(dir));
  ASSERT_TRUE(CanAccessDirectory(dir));

  string file(JoinPath(dir, "foo.txt"));
  FILE* fh = fopen(file.c_str(), "wt");
  ASSERT_NE(nullptr, fh);
  ASSERT_LT(0, fprintf(fh, "hello"));
  fclose(fh);

  ASSERT_TRUE(CanReadFile(file));
  ASSERT_FALSE(CanExecuteFile(file));
  ASSERT_FALSE(CanAccessDirectory(file));

  ASSERT_EQ(0, chmod(file.c_str(), 0100));
  ASSERT_FALSE(CanReadFile(file));
  ASSERT_TRUE(CanExecuteFile(file));
  ASSERT_FALSE(CanAccessDirectory(file));

  ASSERT_EQ(0, chmod(dir.c_str(), 0500));
  ASSERT_FALSE(CanReadFile(dir));
  ASSERT_FALSE(CanExecuteFile(dir));
  ASSERT_FALSE(CanAccessDirectory(dir));
  ASSERT_EQ(0, chmod(dir.c_str(), 0700));

  ASSERT_EQ(0, unlink(file.c_str()));
  ASSERT_EQ(0, rmdir(dir.c_str()));
}

TEST(FilePosixTest, GetCwd) {
  char cwdbuf[PATH_MAX];
  ASSERT_EQ(cwdbuf, getcwd(cwdbuf, PATH_MAX));

  // Assert that GetCwd() and getcwd() return the same value.
  string cwd(cwdbuf);
  ASSERT_EQ(cwd, blaze_util::GetCwd());

  // Change to a different directory.
  ASSERT_EQ(0, chdir("/usr"));

  // Assert that GetCwd() returns the new CWD.
  ASSERT_EQ(string("/usr"), blaze_util::GetCwd());

  ASSERT_EQ(0, chdir(cwd.c_str()));
  ASSERT_EQ(cwd, blaze_util::GetCwd());
}

TEST(FilePosixTest, ChangeDirectory) {
  // Retrieve the current working directory.
  char old_wd[PATH_MAX];
  ASSERT_EQ(old_wd, getcwd(old_wd, PATH_MAX));

  // Change to a different directory and assert it was successful.
  ASSERT_FALSE(blaze_util::ChangeDirectory("/non/existent/path"));
  ASSERT_TRUE(blaze_util::ChangeDirectory("/usr"));
  char new_wd[PATH_MAX];
  ASSERT_EQ(new_wd, getcwd(new_wd, PATH_MAX));
  ASSERT_EQ(string("/usr"), string(new_wd));

  // Change back to the original CWD.
  ASSERT_TRUE(blaze_util::ChangeDirectory(old_wd));
  ASSERT_EQ(new_wd, getcwd(new_wd, PATH_MAX));
  ASSERT_EQ(string(old_wd), string(new_wd));
}

class MockDirectoryEntryConsumer : public DirectoryEntryConsumer {
 public:
  void Consume(const std::string &name, bool is_directory) override {
    entries.push_back(pair<string, bool>(name, is_directory));
  }

  vector<pair<string, bool> > entries;
};

TEST(FilePosixTest, ForEachDirectoryEntry) {
  // Get the test's temp dir.
  char* tmpdir_cstr = getenv("TEST_TMPDIR");
  ASSERT_FALSE(tmpdir_cstr == NULL);
  string tempdir(tmpdir_cstr);
  ASSERT_FALSE(tempdir.empty());
  if (tempdir.back() == '/') {
    tempdir = tempdir.substr(0, tempdir.size() - 1);
  }

  // Create the root directory for the mock directory tree.
  string root = tempdir + "/FilePosixTest.ForEachDirectoryEntry.root";
  ASSERT_EQ(0, mkdir(root.c_str(), 0700));

  // Names of mock files and directories.
  string dir = root + "/dir";
  string file = root + "/file";
  string dir_sym = root + "/dir_sym";
  string file_sym = root + "/file_sym";
  string subfile = dir + "/subfile";
  string subfile_through_sym = dir_sym + "/subfile";

  // Create mock directory, file, and symlinks.
  int fd = open(file.c_str(), O_CREAT, 0700);
  ASSERT_GT(fd, 0);
  close(fd);
  ASSERT_EQ(0, mkdir(dir.c_str(), 0700));
  ASSERT_EQ(0, symlink("dir", dir_sym.c_str()));
  ASSERT_EQ(0, symlink("file", file_sym.c_str()));
  fd = open(subfile.c_str(), O_CREAT, 0700);
  ASSERT_GT(fd, 0);
  close(fd);

  // Assert that stat'ing the symlinks (with following them) point to the right
  // filesystem entry types.
  struct stat stat_buf;
  ASSERT_EQ(0, stat(dir_sym.c_str(), &stat_buf));
  ASSERT_TRUE(S_ISDIR(stat_buf.st_mode));
  ASSERT_EQ(0, stat(file_sym.c_str(), &stat_buf));
  ASSERT_FALSE(S_ISDIR(stat_buf.st_mode));

  // Actual test: list the directory.
  MockDirectoryEntryConsumer consumer;
  ForEachDirectoryEntry(root, &consumer);
  ASSERT_EQ(4, consumer.entries.size());

  // Sort the collected directory entries.
  struct {
    bool operator()(const pair<string, bool> &a, const pair<string, bool> &b) {
      return a.first < b.first;
    }
  } sort_pairs;

  std::sort(consumer.entries.begin(), consumer.entries.end(), sort_pairs);

  // Assert that the directory entries have the right name and type.
  pair<string, bool> expected;
  expected = pair<string, bool>(dir, true);
  ASSERT_EQ(expected, consumer.entries[0]);
  expected = pair<string, bool>(dir_sym, false);
  ASSERT_EQ(expected, consumer.entries[1]);
  expected = pair<string, bool>(file, false);
  ASSERT_EQ(expected, consumer.entries[2]);
  expected = pair<string, bool>(file_sym, false);
  ASSERT_EQ(expected, consumer.entries[3]);

  // Actual test: list a directory symlink.
  consumer.entries.clear();
  ForEachDirectoryEntry(dir_sym, &consumer);
  ASSERT_EQ(1, consumer.entries.size());
  expected = pair<string, bool>(subfile_through_sym, false);
  ASSERT_EQ(expected, consumer.entries[0]);

  // Actual test: list a path that's actually a file, not a directory.
  consumer.entries.clear();
  ForEachDirectoryEntry(file, &consumer);
  ASSERT_TRUE(consumer.entries.empty());

  // Cleanup: delete mock directory tree.
  rmdir(subfile.c_str());
  rmdir(dir.c_str());
  unlink(dir_sym.c_str());
  unlink(file.c_str());
  unlink(file_sym.c_str());
  rmdir(root.c_str());
}

TEST(FilePosixTest, IsAbsolute) {
  ASSERT_FALSE(IsAbsolute(""));
  ASSERT_TRUE(IsAbsolute("/"));
  ASSERT_TRUE(IsAbsolute("/foo"));
  ASSERT_FALSE(IsAbsolute("\\"));
  ASSERT_FALSE(IsAbsolute("\\foo"));
  ASSERT_FALSE(IsAbsolute("c:"));
  ASSERT_FALSE(IsAbsolute("c:/"));
  ASSERT_FALSE(IsAbsolute("c:\\"));
  ASSERT_FALSE(IsAbsolute("c:\\foo"));
  ASSERT_FALSE(IsAbsolute("\\\\?\\c:\\"));
  ASSERT_FALSE(IsAbsolute("\\\\?\\c:\\foo"));
}

TEST(FilePosixTest, IsRootDirectory) {
  ASSERT_FALSE(IsRootDirectory(""));
  ASSERT_TRUE(IsRootDirectory("/"));
  ASSERT_FALSE(IsRootDirectory("/foo"));
  ASSERT_FALSE(IsRootDirectory("\\"));
  ASSERT_FALSE(IsRootDirectory("\\foo"));
  ASSERT_FALSE(IsRootDirectory("c:"));
  ASSERT_FALSE(IsRootDirectory("c:/"));
  ASSERT_FALSE(IsRootDirectory("c:\\"));
  ASSERT_FALSE(IsRootDirectory("c:\\foo"));
  ASSERT_FALSE(IsRootDirectory("\\\\?\\c:\\"));
  ASSERT_FALSE(IsRootDirectory("\\\\?\\c:\\foo"));
}

}  // namespace blaze_util
