// Copyright 2016 The Fuchsia 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 "src/lib/files/directory.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <sys/stat.h>
#include <unistd.h>

#include <string>
#include <vector>

#include "src/lib/files/path.h"
#include "src/lib/fxl/logging.h"

namespace files {

std::string GetCurrentDirectory() {
  char buffer[PATH_MAX];
  FX_CHECK(getcwd(buffer, sizeof(buffer)));
  return std::string(buffer);
}

bool IsDirectory(const std::string& path) { return IsDirectoryAt(AT_FDCWD, path); }

bool IsDirectoryAt(int root_fd, const std::string& path) {
  struct stat buf;
  if (fstatat(root_fd, path.c_str(), &buf, 0) != 0)
    return false;
  return S_ISDIR(buf.st_mode);
}

bool CreateDirectory(const std::string& full_path) {
  return CreateDirectoryAt(AT_FDCWD, full_path);
}

bool CreateDirectoryAt(int root_fd, const std::string& full_path) {
  std::vector<std::string> subpaths;

  // Collect a list of all parent directories.
  std::string last_path = full_path;
  subpaths.push_back(full_path);
  for (std::string path = GetDirectoryName(full_path); !path.empty() && path != last_path;
       path = GetDirectoryName(path)) {
    subpaths.push_back(path);
    last_path = path;
  }

  // Iterate through the parents and create the missing ones.
  for (auto it = subpaths.rbegin(); it != subpaths.rend(); ++it) {
    if (IsDirectoryAt(root_fd, *it))
      continue;
    if (mkdirat(root_fd, it->c_str(), 0700) == 0)
      continue;
    // Mkdir failed, but it might be due to the directory appearing out of thin
    // air. This can occur if two processes are trying to create the same file
    // system tree at the same time. Check to see if it exists and make sure it
    // is a directory.
    if (!IsDirectoryAt(root_fd, *it))
      return false;
  }
  return true;
}

bool ReadDirContents(const std::string& path, std::vector<std::string>* out) {
  return ReadDirContentsAt(AT_FDCWD, path, out);
}

bool ReadDirContentsAt(int root_fd, const std::string& path, std::vector<std::string>* out) {
  out->clear();
  int fd = openat(root_fd, path.c_str(), O_RDONLY | O_DIRECTORY);
  if (fd < 0) {
    return false;
  }
  DIR* dir = fdopendir(fd);
  if (!dir) {
    close(fd);
    return false;
  }
  struct dirent* de;
  errno = 0;
  while ((de = readdir(dir)) != nullptr) {
    out->push_back(de->d_name);
  }
  closedir(dir);
  return !errno;
}

}  // namespace files
