// 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 "src/main/cpp/util/file_platform.h"

#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 <unistd.h>  // access, open, close, fsync
#include <utime.h>   // utime

#include <string>
#include <vector>

#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/logging.h"
#include "src/main/cpp/util/path.h"
#include "src/main/cpp/util/path_platform.h"
#include "src/main/cpp/util/strings.h"

namespace blaze_util {

using std::pair;
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;
}

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, int max_size) {
  int fd = open(filename.c_str(), O_RDONLY);
  if (fd == -1) return false;
  bool result = ReadFrom(fd, content, max_size);
  close(fd);
  return result;
}

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 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;
  }
  int result = write(fd, data, size);
  if (close(fd)) {
    return false;  // Can fail on NFS.
  }
  return result == static_cast<int>(size);
}

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 {
    return errno == ENOTEMPTY ? kRenameDirectoryFailureNotEmpty
                              : kRenameDirectoryFailureOtherError;
  }
}

bool ReadDirectorySymlink(const string &name, string *result) {
  char buf[PATH_MAX + 1];
  int len = readlink(name.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 PathExists(const string& path) {
  return access(path.c_str(), F_OK) == 0;
}

string MakeCanonical(const char *path) {
  char *resolved_path = realpath(path, NULL);
  if (resolved_path == NULL) {
    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 CanExecuteFile(const std::string &path) {
  return !IsDirectory(path) && CanAccess(path, false, false, true);
}

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

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

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);
}

class PosixFileMtime : public IFileMtime {
 public:
  PosixFileMtime()
      : near_future_(GetFuture(9)),
        distant_future_({GetFuture(10), GetFuture(10)}) {}

  bool IsUntampered(const string &path) override;
  bool SetToNow(const string &path) override;
  bool SetToDistantFuture(const string &path) override;

 private:
  // 9 years in the future.
  const time_t near_future_;
  // 10 years in the future.
  const struct utimbuf distant_future_;

  static bool Set(const string &path, const struct utimbuf &mtime);
  static time_t GetNow();
  static time_t GetFuture(unsigned int years);
};

bool PosixFileMtime::IsUntampered(const string &path) {
  struct stat buf;
  if (stat(path.c_str(), &buf)) {
    return false;
  }

  // Compare the mtime with `near_future_`, not with `GetNow()` or
  // `distant_future_`.
  // This way we don't need to call GetNow() every time we want to compare and
  // we also don't need to worry about potentially unreliable time equality
  // check (in case it uses floats or something crazy).
  return S_ISDIR(buf.st_mode) || (buf.st_mtime > near_future_);
}

bool PosixFileMtime::SetToNow(const string &path) {
  time_t now(GetNow());
  struct utimbuf times = {now, now};
  return Set(path, times);
}

bool PosixFileMtime::SetToDistantFuture(const string &path) {
  return Set(path, distant_future_);
}

bool PosixFileMtime::Set(const string &path, const struct utimbuf &mtime) {
  return utime(path.c_str(), &mtime) == 0;
}

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

time_t PosixFileMtime::GetFuture(unsigned int years) {
  return GetNow() + 3600 * 24 * 365 * years;
}

IFileMtime *CreateFileMtime() { return new PosixFileMtime(); }

// 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);
}

string GetCwd() {
  char cwdbuf[PATH_MAX];
  if (getcwd(cwdbuf, sizeof cwdbuf) == NULL) {
    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())) == NULL) {
    // This is not a directory or it cannot be opened.
    return;
  }

  while ((ent = readdir(dir)) != NULL) {
    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
