// Copyright 2014 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 <dirent.h>  // DIR, dirent, opendir, closedir
#include <errno.h>
#include <fcntl.h>   // O_RDONLY
#include <limits.h>  // PATH_MAX
#include <stdlib.h>  // getenv
#include <string.h>  // strncmp
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>  // access, open, close, fsync
#include <utime.h>   // utime

#include <string>

#include "src/main/cpp/util/errors.h"
#include "src/main/cpp/util/exit_code.h"
#include "src/main/cpp/util/file.h"
#include "src/main/cpp/util/file_platform.h"
#include "src/main/cpp/util/logging.h"
#include "src/main/cpp/util/path.h"
#include "src/main/cpp/util/path_platform.h"

namespace blaze_util {

using std::string;

// Runs "stat" on `path`. Returns -1 and sets errno if stat fails or
// `path` isn't a directory. If check_perms is true, this will also
// make sure that `path` is owned by the current user and has `mode`
// permissions (observing the umask). It attempts to run chmod to
// correct the mode if necessary. If `path` is a symlink, this will
// check ownership of the link, not the underlying directory.
static bool GetDirectoryStat(const string &path, mode_t mode,
                             bool check_perms) {
  struct stat filestat = {};
  if (stat(path.c_str(), &filestat) == -1) {
    return false;
  }

  if (!S_ISDIR(filestat.st_mode)) {
    errno = ENOTDIR;
    return false;
  }

  if (check_perms) {
    // If this is a symlink, run checks on the link. (If we did lstat above
    // then it would return false for ISDIR).
    struct stat linkstat = {};
    if (lstat(path.c_str(), &linkstat) != 0) {
      return false;
    }
    if (linkstat.st_uid != geteuid()) {
      // The directory isn't owned by me.
      errno = EACCES;
      return false;
    }

    mode_t mask = umask(022);
    umask(mask);
    mode = (mode & ~mask);
    if ((filestat.st_mode & 0777) != mode && chmod(path.c_str(), mode) == -1) {
      // errno set by chmod.
      return false;
    }
  }
  return true;
}

static bool MakeDirectories(const string &path, mode_t mode, bool childmost) {
  if (path.empty() || IsRootDirectory(path)) {
    errno = EACCES;
    return false;
  }

  bool stat_succeeded = GetDirectoryStat(path, mode, childmost);
  if (stat_succeeded) {
    return true;
  }

  if (errno == ENOENT) {
    // Path does not exist, attempt to create its parents, then it.
    string parent = Dirname(path);
    if (!MakeDirectories(parent, mode, false)) {
      // errno set by stat.
      return false;
    }

    if (mkdir(path.c_str(), mode) == -1) {
      if (errno == EEXIST) {
        if (childmost) {
          // If there are multiple bazel calls at the same time then the
          // directory could be created between the MakeDirectories and mkdir
          // calls. This is okay, but we still have to check the permissions.
          return GetDirectoryStat(path, mode, childmost);
        } else {
          // If this isn't the childmost directory, we don't care what the
          // permissions were. If it's not even a directory then that error will
          // get caught when we attempt to create the next directory down the
          // chain.
          return true;
        }
      }
      // errno set by mkdir.
      return false;
    }
    return true;
  }

  return stat_succeeded;
}


string CreateTempDir(const std::string &prefix) {
  std::string parent = Dirname(prefix);
  // Need parent to exist first.
  if (!blaze_util::PathExists(parent) &&
      !blaze_util::MakeDirectories(parent, 0777)) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "couldn't create '" << parent << "': "
        << blaze_util::GetLastErrorString();
  }

  std::string result(prefix + "XXXXXX");
  if (mkdtemp(&result[0]) == nullptr) {
    std::string err = GetLastErrorString();
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "could not create temporary directory under " << parent
        << " to extract install base into (" << err << ")";
  }

  // There's no better way to get the current umask than to set and reset it.
  const mode_t um = umask(0);
  umask(um);
  chmod(result.c_str(), 0777 & ~um);

  return result;
}

static bool RemoveDirRecursively(const std::string &path) {
  DIR *dir;
  if ((dir = opendir(path.c_str())) == nullptr) {
    return false;
  }

  struct dirent *ent;
  while ((ent = readdir(dir)) != nullptr) {
    if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
      continue;
    }

    if (!RemoveRecursively(blaze_util::JoinPath(path, ent->d_name))) {
      closedir(dir);
      return false;
    }
  }

  if (closedir(dir) != 0) {
    return false;
  }

  return rmdir(path.c_str()) == 0;
}

bool RemoveRecursively(const std::string &path) {
  struct stat stat_buf;
  if (lstat(path.c_str(), &stat_buf) == -1) {
    // Non-existent is good enough.
    return errno == ENOENT;
  }

  if (S_ISDIR(stat_buf.st_mode) && !S_ISLNK(stat_buf.st_mode)) {
    return RemoveDirRecursively(path);
  } else {
    return UnlinkPath(path);
  }
}

class PosixPipe : public IPipe {
 public:
  PosixPipe(int recv_socket, int send_socket)
      : _recv_socket(recv_socket), _send_socket(send_socket) {}

  PosixPipe() = delete;

  virtual ~PosixPipe() {
    close(_recv_socket);
    close(_send_socket);
  }

  bool Send(const void *buffer, int size) override {
    return size >= 0 && write(_send_socket, buffer, size) == size;
  }

  int Receive(void *buffer, int size, int *error) override {
    if (size < 0) {
      if (error != nullptr) {
        *error = IPipe::OTHER_ERROR;
      }
      return -1;
    }
    int result = read(_recv_socket, buffer, size);
    if (error != nullptr) {
      *error = result >= 0 ? IPipe::SUCCESS
                           : ((errno == EINTR) ? IPipe::INTERRUPTED
                                               : IPipe::OTHER_ERROR);
    }
    return result;
  }

 private:
  int _recv_socket;
  int _send_socket;
};

IPipe* CreatePipe() {
  int fd[2];
  if (pipe(fd) < 0) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "pipe() failed: " << GetLastErrorString();
  }

  if (fcntl(fd[0], F_SETFD, FD_CLOEXEC) == -1) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "fcntl(F_SETFD, FD_CLOEXEC) failed: " << GetLastErrorString();
  }

  if (fcntl(fd[1], F_SETFD, FD_CLOEXEC) == -1) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "fcntl(F_SETFD, FD_CLOEXEC) failed: " << GetLastErrorString();
  }

  return new PosixPipe(fd[0], fd[1]);
}

int ReadFromHandle(file_handle_type fd, void *data, size_t size, int *error) {
  int result = read(fd, data, size);
  if (error != nullptr) {
    if (result >= 0) {
      *error = ReadFileResult::SUCCESS;
    } else {
      if (errno == EINTR) {
        *error = ReadFileResult::INTERRUPTED;
      } else if (errno == EAGAIN) {
        *error = ReadFileResult::AGAIN;
      } else {
        *error = ReadFileResult::OTHER_ERROR;
      }
    }
  }
  return result;
}

bool ReadFile(const string &filename, string *content, string *error_message,
              int max_size) {
  int fd = open(filename.c_str(), O_RDONLY);
  if (fd == -1) {
    if (error_message != nullptr) {
      *error_message = blaze_util::GetLastErrorString();
    }
    return false;
  }
  bool result = ReadFrom(fd, content, max_size);
  close(fd);
  return result;
}

bool ReadFile(const string &filename, string *content, int max_size) {
  return ReadFile(filename, content, /* error_message= */nullptr, max_size);
}

bool ReadFile(const Path &path, std::string *content, int max_size) {
  return ReadFile(
    path.AsNativePath(), content, /* error_message= */nullptr, max_size);
}

bool ReadFile(const string &filename, void *data, size_t size) {
  int fd = open(filename.c_str(), O_RDONLY);
  if (fd == -1) return false;
  bool result = ReadFrom(fd, data, size);
  close(fd);
  return result;
}

bool ReadFile(const Path &filename, void *data, size_t size) {
  return ReadFile(filename.AsNativePath(), data, size);
}

bool WriteFile(const void *data, size_t size, const string &filename,
               unsigned int perm) {
  UnlinkPath(filename);  // We don't care about the success of this.
  int fd = open(filename.c_str(), O_CREAT | O_WRONLY | O_TRUNC, perm);
  if (fd == -1) {
    return false;
  }
  const char *const char_data = reinterpret_cast<const char *>(data);
  size_t written = 0;
  while (written < size) {
    // write fails with EINVAL on MacOs for count > INT32_MAX.
    auto result = write(fd, char_data + written,
                        std::min<size_t>(INT32_MAX, size - written));
    if (result == -1) {
      close(fd);
      return false;
    }
    written += result;
  }
  return close(fd) == 0;  // Can fail on NFS.
}

bool WriteFile(const void *data, size_t size, const Path &path,
               unsigned int perm) {
  return WriteFile(data, size, path.AsNativePath(), perm);
}

void InitializeStdOutErrForUtf8() {}

int WriteToStdOutErr(const void *data, size_t size, bool to_stdout) {
  size_t r = fwrite(data, 1, size, to_stdout ? stdout : stderr);
  return (r == size) ? WriteResult::SUCCESS
                     : ((errno == EPIPE) ? WriteResult::BROKEN_PIPE
                                         : WriteResult::OTHER_ERROR);
}

int RenameDirectory(const std::string &old_name, const std::string &new_name) {
  if (rename(old_name.c_str(), new_name.c_str()) == 0) {
    return kRenameDirectorySuccess;
  } else {
    if (errno == ENOTEMPTY || errno == EEXIST) {
      return kRenameDirectoryFailureNotEmpty;
    } else {
      return kRenameDirectoryFailureOtherError;
    }
  }
}

bool ReadDirectorySymlink(const blaze_util::Path &name, string *result) {
  char buf[PATH_MAX + 1];
  int len = readlink(name.AsNativePath().c_str(), buf, PATH_MAX);
  if (len < 0) {
    return false;
  }

  buf[len] = 0;
  *result = buf;
  return true;
}

bool UnlinkPath(const string &file_path) {
  return unlink(file_path.c_str()) == 0;
}

bool UnlinkPath(const Path &file_path) {
  return UnlinkPath(file_path.AsNativePath());
}

bool PathExists(const string& path) {
  return access(path.c_str(), F_OK) == 0;
}

bool PathExists(const Path &path) { return PathExists(path.AsNativePath()); }

string MakeCanonical(const char *path) {
  char *resolved_path = realpath(path, nullptr);
  if (resolved_path == nullptr) {
    return "";
  } else {
    string ret = resolved_path;
    free(resolved_path);
    return ret;
  }
}

static bool CanAccess(const string &path, bool read, bool write, bool exec) {
  int mode = 0;
  if (read) {
    mode |= R_OK;
  }
  if (write) {
    mode |= W_OK;
  }
  if (exec) {
    mode |= X_OK;
  }
  return access(path.c_str(), mode) == 0;
}

bool CanReadFile(const std::string &path) {
  return !IsDirectory(path) && CanAccess(path, true, false, false);
}

bool CanReadFile(const Path &path) {
  return CanReadFile(path.AsNativePath());
}

bool CanExecuteFile(const std::string &path) {
  return !IsDirectory(path) && CanAccess(path, false, false, true);
}

bool CanExecuteFile(const Path &path) {
  return CanExecuteFile(path.AsNativePath());
}

bool CanAccessDirectory(const std::string &path) {
  return IsDirectory(path) && CanAccess(path, true, true, true);
}

bool CanAccessDirectory(const Path &path) {
  return CanAccessDirectory(path.AsNativePath());
}

bool IsDirectory(const string& path) {
  struct stat buf;
  return stat(path.c_str(), &buf) == 0 && S_ISDIR(buf.st_mode);
}

bool IsDirectory(const Path &path) { return IsDirectory(path.AsNativePath()); }

void SyncFile(const string& path) {
  const char* file_path = path.c_str();
  int fd = open(file_path, O_RDONLY);
  if (fd < 0) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "failed to open '" << file_path
        << "' for syncing: " << GetLastErrorString();
  }
  if (fsync(fd) < 0) {
    BAZEL_DIE(blaze_exit_code::LOCAL_ENVIRONMENTAL_ERROR)
        << "failed to sync '" << file_path << "': " << GetLastErrorString();
  }
  close(fd);
}

void SyncFile(const Path &path) { SyncFile(path.AsNativePath()); }

static time_t GetNow() {
  time_t result = time(nullptr);
  if (result == -1) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "time(nullptr) failed: " << GetLastErrorString();
  }
  return result;
}

static time_t GetYearsInFuture(int years) {
  return GetNow() + 3600 * 24 * 365 * years;
}

static bool SetMtime(const Path &path, time_t mtime) {
  struct utimbuf times = {mtime, mtime};
  return utime(path.AsNativePath().c_str(), &times) == 0;
}

static const time_t kNearFuture = GetYearsInFuture(9);
static const time_t kDistantFuture = GetYearsInFuture(10);

bool IsUntampered(const Path &path) {
  struct stat buf;
  if (stat(path.AsNativePath().c_str(), &buf)) {
    return false;
  }

  // Compare with kNearFuture, not kDistantFuture.
  // This way we don't need to worry about a potentially unreliable equality
  // check if precision isn't preserved.
  return S_ISDIR(buf.st_mode) || (buf.st_mtime > kNearFuture);
}

bool SetMtimeToNow(const Path &path) {
  time_t now = GetNow();
  return SetMtime(path, now);
}

bool SetMtimeToNowIfPossible(const Path &path) {
  bool okay = SetMtimeToNow(path);
  if (!okay) {
    // `SetToNow`/`Set` are backed by `utime(2)` which can return `EROFS` and
    // `EPERM` when there's a permissions issue:
    if (errno == EROFS || errno == EPERM) {
      okay = true;
    }
  }

  return okay;
}

bool SetMtimeToDistantFuture(const Path &path) {
  return SetMtime(path, kDistantFuture);
}

// mkdir -p path. Returns true if the path was created or already exists and
// could
// be chmod-ed to exactly the given permissions. If final part of the path is a
// symlink, this ensures that the destination of the symlink has the desired
// permissions. It also checks that the directory or symlink is owned by us.
// On failure, this returns false and sets errno.
bool MakeDirectories(const string &path, unsigned int mode) {
  return MakeDirectories(path, mode, true);
}

bool MakeDirectories(const Path &path, unsigned int mode) {
  return MakeDirectories(path.AsNativePath(), mode);
}

string GetCwd() {
  char cwdbuf[PATH_MAX];
  if (getcwd(cwdbuf, sizeof cwdbuf) == nullptr) {
    BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
        << "getcwd() failed: " << GetLastErrorString();
  }
  return string(cwdbuf);
}

bool ChangeDirectory(const string& path) {
  return chdir(path.c_str()) == 0;
}

void ForEachDirectoryEntry(const string &path,
                           DirectoryEntryConsumer *consume) {
  DIR *dir;
  struct dirent *ent;

  if ((dir = opendir(path.c_str())) == nullptr) {
    // This is not a directory or it cannot be opened.
    return;
  }

  while ((ent = readdir(dir)) != nullptr) {
    if (!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) {
      continue;
    }

    string filename(blaze_util::JoinPath(path, ent->d_name));
    bool is_directory;
// 'd_type' field isn't part of the POSIX spec.
#ifdef _DIRENT_HAVE_D_TYPE
    if (ent->d_type != DT_UNKNOWN) {
      is_directory = (ent->d_type == DT_DIR);
    } else  // NOLINT (the brace is on the next line)
#endif
      {
        struct stat buf;
        if (lstat(filename.c_str(), &buf) == -1) {
          BAZEL_DIE(blaze_exit_code::INTERNAL_ERROR)
              << "stat failed for filename '" << filename
              << "': " << GetLastErrorString();
        }
        is_directory = S_ISDIR(buf.st_mode);
      }

      consume->Consume(filename, is_directory);
  }

    closedir(dir);
  }

}  // namespace blaze_util
