// 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/path.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <lib/fit/function.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <functional>
#include <list>
#include <memory>

#include <fbl/auto_call.h>

#include "src/lib/files/directory.h"

namespace files {
namespace {

size_t ResolveParentDirectoryTraversal(const std::string& path, size_t put) {
  if (put >= 2) {
    size_t previous_separator = path.rfind('/', put - 2);
    if (previous_separator != std::string::npos)
      return previous_separator + 1;
  }
  if (put == 1 && path[0] == '/') {
    return put;
  }
  return 0;
}

void SafeCloseDir(DIR* dir) {
  if (dir)
    closedir(dir);
}

bool ForEachEntry(int root_fd, const std::string& path,
                  fit::function<bool(const std::string& path)> callback) {
  int dir_fd = openat(root_fd, path.c_str(), O_RDONLY);
  if (dir_fd == -1) {
    return false;
  }
  std::unique_ptr<DIR, decltype(&SafeCloseDir)> dir(fdopendir(dir_fd), SafeCloseDir);
  if (!dir.get())
    return false;
  for (struct dirent* entry = readdir(dir.get()); entry != nullptr; entry = readdir(dir.get())) {
    char* name = entry->d_name;
    if (name[0]) {
      if (name[0] == '.') {
        if (!name[1] || (name[1] == '.' && !name[2])) {
          // . or ..
          continue;
        }
      }
      if (!callback(path + "/" + name)) {
        return false;
      }
    }
  }
  return true;
}

}  // namespace

std::string SimplifyPath(std::string path) {
  if (path.empty())
    return ".";

  size_t put = 0;
  size_t get = 0;
  size_t traversal_root = 0;
  size_t component_start = 0;

  if (path[0] == '/') {
    put = 1;
    get = 1;
    component_start = 1;
  }

  while (get < path.size()) {
    char c = path[get];

    if (c == '.' && (get == component_start || get == component_start + 1)) {
      // We've seen "." or ".." so far in this component. We need to continue
      // searching.
      ++get;
      continue;
    }

    if (c == '/') {
      if (get == component_start || get == component_start + 1) {
        // We've found a "/" or a "./", which we can elide.
        ++get;
        component_start = get;
        continue;
      }
      if (get == component_start + 2) {
        // We've found a "../", which means we need to remove the previous
        // component.
        if (put == traversal_root) {
          path[put++] = '.';
          path[put++] = '.';
          path[put++] = '/';
          traversal_root = put;
        } else {
          put = ResolveParentDirectoryTraversal(path, put);
        }
        ++get;
        component_start = get;
        continue;
      }
    }

    size_t next_separator = path.find('/', get);
    if (next_separator == std::string::npos) {
      // We've reached the last component.
      break;
    }
    size_t next_component_start = next_separator + 1;
    ++next_separator;
    size_t component_size = next_component_start - component_start;
    if (put != component_start && component_size > 0) {
      path.replace(put, component_size, path.substr(component_start, component_size));
    }
    put += component_size;
    get = next_component_start;
    component_start = next_component_start;
  }

  size_t last_component_size = path.size() - component_start;
  if (last_component_size == 1 && path[component_start] == '.') {
    // The last component is ".", which we can elide.
  } else if (last_component_size == 2 && path[component_start] == '.' &&
             path[component_start + 1] == '.') {
    // The last component is "..", which means we need to remove the previous
    // component.
    if (put == traversal_root) {
      path[put++] = '.';
      path[put++] = '.';
      path[put++] = '/';
      traversal_root = put;
    } else {
      put = ResolveParentDirectoryTraversal(path, put);
    }
  } else {
    // Otherwise, we need to copy over the last component.
    if (put != component_start && last_component_size > 0) {
      path.replace(put, last_component_size, path.substr(component_start, last_component_size));
    }
    put += last_component_size;
  }

  if (put >= 2 && path[put - 1] == '/')
    --put;  // Trim trailing /
  else if (put == 0)
    return ".";  // Use . for otherwise empty paths to treat them as relative.

  path.resize(put);
  return path;
}

std::string AbsolutePath(const std::string& path) {
  if (path.size() > 0) {
    if (path[0] == '/') {
      // Path is already absolute.
      return path;
    }
    auto current_directory = GetCurrentDirectory();
    if (current_directory == "/") {
      // No need to prepend "/" if we are relative to the root directory.
      current_directory = "";
    }
    return current_directory + "/" + path;
  } else {
    // Path is empty.
    return GetCurrentDirectory();
  }
}

std::string GetDirectoryName(const std::string& path) {
  size_t separator = path.rfind('/');
  if (separator == 0u)
    return "/";
  if (separator == std::string::npos)
    return std::string();
  return path.substr(0, separator);
}

std::string GetBaseName(const std::string& path) {
  size_t separator = path.rfind('/');
  if (separator == std::string::npos)
    return path;
  return path.substr(separator + 1);
}

bool DeletePath(const std::string& path, bool recursive) {
  return DeletePathAt(AT_FDCWD, path, recursive);
}

bool DeletePathAt(int root_fd, const std::string& path, bool recursive) {
  struct stat stat_buffer;
  if (fstatat(root_fd, path.c_str(), &stat_buffer, AT_SYMLINK_NOFOLLOW) != 0)
    return (errno == ENOENT || errno == ENOTDIR);
  if (!S_ISDIR(stat_buffer.st_mode))
    return (unlinkat(root_fd, path.c_str(), 0) == 0);
  if (!recursive)
    return (unlinkat(root_fd, path.c_str(), AT_REMOVEDIR) == 0);

  // Use std::list, as ForEachEntry callback will modify the container. If the
  // container is a vector, this will invalidate the reference to the content.
  std::list<std::string> directories;
  directories.push_back(path);
  for (auto it = directories.begin(); it != directories.end(); ++it) {
    if (!ForEachEntry(root_fd, *it, [root_fd, &directories](const std::string& child) {
          if (IsDirectoryAt(root_fd, child)) {
            directories.push_back(child);
          } else {
            if (unlinkat(root_fd, child.c_str(), 0) != 0)
              return false;
          }
          return true;
        })) {
      return false;
    }
  }
  for (auto it = directories.rbegin(); it != directories.rend(); ++it) {
    if (unlinkat(root_fd, it->c_str(), AT_REMOVEDIR) != 0)
      return false;
  }
  return true;
}

std::string JoinPath(const std::string& path1, const std::string& path2) {
  if (path1.empty()) {
    return path2;
  }
  if (path2.empty()) {
    return path1;
  }
  if (path1.back() == '/') {
    if (path2.front() == '/') {
      return path1 + path2.substr(1);
    }
  } else {
    if (path2.front() != '/') {
      return path1 + "/" + path2;
    }
  }
  return path1 + path2;
}

}  // namespace files
