/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */
#ifndef LIBMINIFI_INCLUDE_UTILS_FILE_FILEUTILS_H_
#define LIBMINIFI_INCLUDE_UTILS_FILE_FILEUTILS_H_

#include <fstream>
#include <memory>
#include <sstream>
#include <tuple>
#include <utility>
#include <vector>

#ifdef USE_BOOST
#include <dirent.h>
#include <boost/filesystem.hpp>
#include <boost/system/error_code.hpp>

#else
#include <errno.h>

#include <cstdlib>
#include <cstring>

#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
  #define WIN32_LEAN_AND_MEAN
#endif
#include <Windows.h>
#include <WinSock2.h>
#include <WS2tcpip.h>

#pragma comment(lib, "Ws2_32.lib")
#else
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <utime.h>

#endif
#endif
#include <cstdio>

#ifndef WIN32
#include <unistd.h>

#endif
#include <fcntl.h>

#ifdef WIN32
#include <direct.h>
#include <sys/stat.h>  // stat // NOLINT
#include <sys/types.h> // NOLINT
#include <sys/utime.h>  // _utime64
#include <tchar.h>  // _tcscpy,_tcscat,_tcscmp
#include <windows.h>  // winapi

#include <algorithm>  // replace
#include <string>  // string

#include "properties/Properties.h"
#include "utils/Id.h"

#endif
#ifdef __APPLE__
#include <mach-o/dyld.h>

#endif

#include "core/logging/LoggerConfiguration.h"
#include "utils/StringUtils.h"

#ifndef S_ISDIR
#define S_ISDIR(mode)  (((mode) & S_IFMT) == S_IFDIR)
#endif


namespace org {
namespace apache {
namespace nifi {
namespace minifi {
namespace utils {
namespace file {

namespace FileUtils = ::org::apache::nifi::minifi::utils::file;

namespace detail {
static inline int platform_create_dir(const std::string& path) {
#ifdef WIN32
  return _mkdir(path.c_str());
#else
  return mkdir(path.c_str(), 0777);
#endif
}
}  // namespace detail

/*
 * Get the platform-specific path separator.
 * @param force_posix returns the posix path separator ('/'), even when not on posix. Useful when dealing with remote posix paths.
 * @return the path separator character
 */
inline char get_separator(bool force_posix = false) {
#ifdef WIN32
  if (!force_posix) {
    return '\\';
  }
#endif
  return '/';
}

inline std::string normalize_path_separators(std::string path, bool force_posix = false) {
  const auto normalize_separators = [force_posix](const char c) {
    if (c == '\\' || c == '/') { return get_separator(force_posix); }
    return c;
  };
  std::transform(std::begin(path), std::end(path), std::begin(path), normalize_separators);
  return path;
}

inline std::string get_temp_directory() {
#ifdef WIN32
  char tempBuffer[MAX_PATH];
  const auto ret = GetTempPath(MAX_PATH, tempBuffer);
  if (ret > MAX_PATH || ret == 0)
    throw std::runtime_error("Couldn't locate temporary directory path");
  return tempBuffer;
#else
  return "/tmp";
#endif
}

inline int64_t delete_dir(const std::string &path, bool delete_files_recursively = true) {
#ifdef USE_BOOST
  try {
    if (boost::filesystem::exists(path)) {
      if (delete_files_recursively) {
        boost::filesystem::remove_all(path);
      } else {
        boost::filesystem::remove(path);
      }
    }
  } catch(boost::filesystem::filesystem_error const & e) {
    return -1;
    // display error message
  }
  return 0;
#elif defined(WIN32)
  WIN32_FIND_DATA FindFileData;
  HANDLE hFind;
  DWORD Attributes;
  std::string str;


  std::stringstream pathstr;
  pathstr << path << "\\*";
  str = pathstr.str();
  // List files
  hFind = FindFirstFile(str.c_str(), &FindFileData);
  if (hFind != INVALID_HANDLE_VALUE) {
    do {
      if (strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0) {
        std::stringstream strs;
        strs << path << "\\" << FindFileData.cFileName;
        str = strs.str();

        Attributes = GetFileAttributes(str.c_str());
        if (Attributes & FILE_ATTRIBUTE_DIRECTORY) {
          // is directory
          delete_dir(str, delete_files_recursively);
        } else {
          remove(str.c_str());
          // not directory
        }
      }
    }while (FindNextFile(hFind, &FindFileData));
    FindClose(hFind);

    RemoveDirectory(path.c_str());
  }
  return 0;
#else
  DIR *current_directory = opendir(path.c_str());
  int r = -1;
  if (current_directory) {
    struct dirent *p;
    r = 0;
    while (!r && (p = readdir(current_directory))) {
      int r2 = -1;
      std::stringstream newpath;
      if (!strcmp(p->d_name, ".") || !strcmp(p->d_name, "..")) {
        continue;
      }
      struct stat statbuf;

      newpath << path << "/" << p->d_name;

      if (!stat(newpath.str().c_str(), &statbuf)) {
        if (S_ISDIR(statbuf.st_mode)) {
          if (delete_files_recursively) {
            r2 = delete_dir(newpath.str(), delete_files_recursively);
          }
        } else {
          r2 = unlink(newpath.str().c_str());
        }
      }
      r = r2;
    }
    closedir(current_directory);
  }

  if (!r) {
    return rmdir(path.c_str());
  }

  return 0;
#endif
}

inline uint64_t last_write_time(const std::string &path) {
#ifdef USE_BOOST
  boost::system::error_code ec;
  auto result = boost::filesystem::last_write_time(path, ec);
  if (ec.value() == 0) {
    return result;
  }
#else
#ifdef WIN32
  struct _stat result;
  if (_stat(path.c_str(), &result) == 0) {
    return result.st_mtime;
  }
#else
  struct stat result;
  if (stat(path.c_str(), &result) == 0) {
    return result.st_mtime;
  }
#endif
#endif
  return 0;
}

inline std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds> last_write_time_point(const std::string &path) {
  return std::chrono::time_point<std::chrono::system_clock, std::chrono::seconds>{std::chrono::seconds{last_write_time(path)}};
}

inline uint64_t file_size(const std::string &path) {
#ifdef WIN32
  struct _stat result;
  if (_stat(path.c_str(), &result) == 0) {
    return result.st_size;
  }
#else
  struct stat result;
  if (stat(path.c_str(), &result) == 0) {
    return result.st_size;
  }
#endif
  return 0;
}

inline bool set_last_write_time(const std::string &path, uint64_t write_time) {
#ifdef USE_BOOST
  boost::filesystem::last_write_time(path, write_time);
  return true;
#elif defined(WIN32)
  struct __utimbuf64 utim;
  utim.actime = write_time;
  utim.modtime = write_time;
  return _utime64(path.c_str(), &utim) == 0U;
#else
  struct utimbuf utim;
  utim.actime = write_time;
  utim.modtime = write_time;
  return utime(path.c_str(), &utim) == 0U;
#endif
}

#ifndef WIN32
inline bool get_permissions(const std::string &path, uint32_t &permissions) {
  struct stat result;
  if (stat(path.c_str(), &result) == 0) {
    permissions = result.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO);
    return true;
  }
  return false;
}

inline int set_permissions(const std::string &path, const uint32_t permissions) {
#ifdef USE_BOOST
  boost::system::error_code ec;
  boost::filesystem::permissions(path, static_cast<boost::filesystem::perms>(permissions), ec);
  return ec.value();
#else
  return chmod(path.c_str(), permissions);
#endif
}
#endif

#ifndef WIN32
inline bool get_uid_gid(const std::string &path, uint64_t &uid, uint64_t &gid) {
  struct stat result;
  if (stat(path.c_str(), &result) == 0) {
    uid = result.st_uid;
    gid = result.st_gid;
    return true;
  }
  return false;
}
#endif

inline bool is_directory(const char * path) {
  struct stat dir_stat;
  if (stat(path, &dir_stat) < 0) {
      return false;
  }
  return S_ISDIR(dir_stat.st_mode) != 0;
}

inline bool exists(const std::string& path) {
#ifdef USE_BOOST
  return boost::filesystem::exists(path);
#else
#ifdef WIN32
  struct _stat statbuf;
  return _stat(path.c_str(), &statbuf) == 0;
#else
  struct stat statbuf;
  return stat(path.c_str(), &statbuf) == 0;
#endif
#endif
}

inline int create_dir(const std::string& path, bool recursive = true) {
#ifdef USE_BOOST
  boost::filesystem::path dir(path);
  boost::system::error_code ec;
  if (!recursive) {
    boost::filesystem::create_directory(dir, ec);
  } else {
    boost::filesystem::create_directories(dir, ec);
  }
  if (ec.value() == 0 || (ec.value() == EEXIST && is_directory(path.c_str()))) {
    return 0;
  }
  return ec.value();
#else
  if (!recursive) {
    if (detail::platform_create_dir(path) != 0 && errno != EEXIST) {
      return -1;
    }
    return 0;
  }
  if (detail::platform_create_dir(path) == 0) {
    return 0;
  }

  switch (errno) {
  case ENOENT: {
    size_t found = path.find_last_of(get_separator());

    if (found == std::string::npos) {
      return -1;
    }

    const std::string dir = path.substr(0, found);
    int res = create_dir(dir, recursive);
    if (res < 0) {
      return -1;
    }
    return detail::platform_create_dir(path);
  }
  case EEXIST: {
    if (is_directory(path.c_str())) {
      return 0;
    }
    return -1;
  }
  default:
    return -1;
  }
  return -1;
#endif
}

inline int copy_file(const std::string &path_from, const std::string dest_path) {
  std::ifstream src(path_from, std::ios::binary);
  if (!src.is_open())
    return -1;
  std::ofstream dest(dest_path, std::ios::binary);
  dest << src.rdbuf();
  return 0;
}

inline void addFilesMatchingExtension(const std::shared_ptr<logging::Logger> &logger, const std::string &originalPath, const std::string &extension, std::vector<std::string> &accruedFiles) {
#ifndef WIN32

  struct stat s;
  if (stat(originalPath.c_str(), &s) == 0) {
    if (s.st_mode & S_IFDIR) {
      DIR *d;
      d = opendir(originalPath.c_str());
      if (!d) {
        return;
      }
      // only perform a listing while we are not empty
      logger->log_debug("Performing file listing on %s", originalPath);

      struct dirent *entry;
      entry = readdir(d);
      while (entry != nullptr) {
        std::string d_name = entry->d_name;
        std::string path = originalPath + "/" + d_name;
        struct stat statbuf { };
        if (stat(path.c_str(), &statbuf) != 0) {
          logger->log_warn("Failed to stat %s", path);
          return;
        }
        if (S_ISDIR(statbuf.st_mode)) {
          // if this is a directory
          if (d_name != ".." && d_name != ".") {
            addFilesMatchingExtension(logger, path, extension, accruedFiles);
          }
        } else {
          if (utils::StringUtils::endsWith(path, extension)) {
            logger->log_info("Adding %s to paths", path);
            accruedFiles.push_back(path);
          }
        }
        entry = readdir(d);
      }
      closedir(d);
    } else if (s.st_mode & S_IFREG) {
      if (utils::StringUtils::endsWith(originalPath, extension)) {
        logger->log_info("Adding %s to paths", originalPath);
        accruedFiles.push_back(originalPath);
      }
    } else {
      logger->log_error("Could not stat", originalPath);
    }

  } else {
    logger->log_error("Could not access %s", originalPath);
  }
#else
  HANDLE hFind;
  WIN32_FIND_DATA FindFileData;

  std::string pathToSearch = originalPath + "\\*" + extension;
  if ((hFind = FindFirstFileA(pathToSearch.c_str(), &FindFileData)) != INVALID_HANDLE_VALUE) {
    do {
      struct _stat statbuf {};

      std::string path = originalPath + "\\" + FindFileData.cFileName;
      logger->log_info("Adding %s to paths", path);
      if (_stat(path.c_str(), &statbuf) != 0) {
        logger->log_warn("Failed to stat %s", path);
        break;
      }
      logger->log_info("Adding %s to paths", path);
      if (S_ISDIR(statbuf.st_mode)) {
        addFilesMatchingExtension(logger, path, extension, accruedFiles);
      } else {
        if (utils::StringUtils::endsWith(path, extension)) {
          logger->log_info("Adding %s to paths", path);
          accruedFiles.push_back(path);
        }
      }
    }while (FindNextFileA(hFind, &FindFileData));
    FindClose(hFind);
  }
#endif
}

/*
 * Provides a platform-independent function to list a directory
 * Callback is called for every file found: first argument is the path of the directory, second is the filename
 * Return value of the callback is used to continue (true) or stop (false) listing
 */
inline void list_dir(const std::string& dir, std::function<bool(const std::string&, const std::string&)> callback,
                     const std::shared_ptr<logging::Logger> &logger, bool recursive = true) {
  logger->log_debug("Performing file listing against %s", dir);
#ifndef WIN32
  DIR *d = opendir(dir.c_str());
  if (!d) {
    logger->log_warn("Failed to open directory: %s", dir.c_str());
    return;
  }

  struct dirent *entry;
  while ((entry = readdir(d)) != NULL) {
    std::string d_name = entry->d_name;
    std::string path = dir + get_separator() + d_name;

    struct stat statbuf;
    if (stat(path.c_str(), &statbuf) != 0) {
      logger->log_warn("Failed to stat %s", path);
      continue;
    }

    if (S_ISDIR(statbuf.st_mode)) {
      // if this is a directory
      if (recursive && strcmp(d_name.c_str(), "..") != 0 && strcmp(d_name.c_str(), ".") != 0) {
        list_dir(path, callback, logger, recursive);
      }
    } else {
      if (!callback(dir, d_name)) {
        break;
      }
    }
  }
  closedir(d);
#else
  HANDLE hFind;
  WIN32_FIND_DATA FindFileData;

  std::string pathToSearch = dir + "\\*.*";
  hFind = FindFirstFileA(pathToSearch.c_str(), &FindFileData);

  if (hFind == INVALID_HANDLE_VALUE) {
    logger->log_warn("Failed to open directory: %s", dir.c_str());
    return;
  }

  do {
    struct _stat statbuf {};
    if (strcmp(FindFileData.cFileName, ".") != 0 && strcmp(FindFileData.cFileName, "..") != 0) {
      std::string path = dir + get_separator() + FindFileData.cFileName;
      if (_stat(path.c_str(), &statbuf) != 0) {
        logger->log_warn("Failed to stat %s", path);
        continue;
      }
      if (S_ISDIR(statbuf.st_mode)) {
        if (recursive) {
          list_dir(path, callback, logger, recursive);
        }
      } else {
        if (!callback(dir, FindFileData.cFileName)) {
          break;
        }
      }
    }
  } while (FindNextFileA(hFind, &FindFileData));
  FindClose(hFind);
#endif
}

inline std::vector<std::pair<std::string, std::string>> list_dir_all(const std::string& dir, const std::shared_ptr<logging::Logger> &logger,
    bool recursive = true)  {
  std::vector<std::pair<std::string, std::string>> fileList;
  auto lambda = [&fileList] (const std::string &path, const std::string &filename) {
    fileList.push_back(make_pair(path, filename));
    return true;
  };

  list_dir(dir, lambda, logger, recursive);

  return fileList;
}

inline std::string concat_path(const std::string& root, const std::string& child, bool force_posix = false) {
  if (root.empty()) {
    return child;
  }
  std::stringstream new_path;
  if (root.back() == get_separator(force_posix)) {
    new_path << root << child;
  } else {
    new_path << root << get_separator(force_posix) << child;
  }
  return new_path.str();
}

inline std::string create_temp_directory(char* format) {
#ifdef WIN32
  const std::string tempDirectory = concat_path(get_temp_directory(),
      minifi::utils::IdGenerator::getIdGenerator()->generate().to_string());
  create_dir(tempDirectory);
  return tempDirectory;
#else
  if (mkdtemp(format) == nullptr) { return ""; }
  return format;
#endif
}

inline std::tuple<std::string /*parent_path*/, std::string /*child_path*/> split_path(const std::string& path, bool force_posix = false) {
  if (path.empty()) {
    /* Empty path has no parent and no child*/
    return std::make_tuple("", "");
  }
  bool absolute = false;
  size_t root_pos = 0U;
#ifdef WIN32
  if (!force_posix) {
      if (path[0] == '\\') {
        absolute = true;
        if (path.size() < 2U) {
          return std::make_tuple("", "");
        }
        if (path[1] == '\\') {
          if (path.size() >= 4U &&
             (path[2] == '?' || path[2] == '.') &&
              path[3] == '\\') {
            /* Probably an UNC path */
            root_pos = 4U;
          } else {
            /* Probably a \\server\-type path */
            root_pos = 2U;
          }
          root_pos = path.find_first_of("\\", root_pos);
          if (root_pos == std::string::npos) {
            return std::make_tuple("", "");
          }
        }
      } else if (path.size() >= 3U &&
                 toupper(path[0]) >= 'A' &&
                 toupper(path[0]) <= 'Z' &&
                 path[1] == ':' &&
                 path[2] == '\\') {
        absolute = true;
        root_pos = 2U;
      }
    } else {
#else
  if (true) {
#endif
    if (path[0] == '/') {
      absolute = true;
      root_pos = 0U;
    }
  }
  /* Maybe we are just a single relative child */
  if (!absolute && path.find(get_separator(force_posix)) == std::string::npos) {
    return std::make_tuple("", path);
  }
  /* Ignore trailing separators */
  size_t last_pos = path.size() - 1;
  while (last_pos > root_pos && path[last_pos] == get_separator(force_posix)) {
    last_pos--;
  }
  if (absolute && last_pos == root_pos) {
    /* This means we are only a root */
    return std::make_tuple("", "");
  }
  /* Find parent-child separator */
  size_t last_separator = path.find_last_of(get_separator(force_posix), last_pos);
  if (last_separator == std::string::npos || last_separator < root_pos) {
    return std::make_tuple("", "");
  }
  std::string parent = path.substr(0, last_separator + 1);
  std::string child = path.substr(last_separator + 1);

  return std::make_tuple(std::move(parent), std::move(child));
}

inline std::string get_parent_path(const std::string& path, bool force_posix = false) {
  std::string parent_path;
  std::tie(parent_path, std::ignore) = split_path(path, force_posix);
  return parent_path;
}

inline std::string get_child_path(const std::string& path, bool force_posix = false) {
  std::string child_path;
  std::tie(std::ignore, child_path) = split_path(path, force_posix);
  return child_path;
}

inline bool is_hidden(const std::string& path) {
#ifdef WIN32
  DWORD attributes = GetFileAttributesA(path.c_str());
    return ((attributes != INVALID_FILE_ATTRIBUTES)  && ((attributes & FILE_ATTRIBUTE_HIDDEN) != 0));
#else
  return std::get<1>(split_path(path)).rfind(".", 0) == 0;
#endif
}

/*
 * Returns the absolute path of the current executable
 */
inline std::string get_executable_path() {
#if defined(__linux__)
  std::vector<char> buf(1024U);
  while (true) {
    ssize_t ret = readlink("/proc/self/exe", buf.data(), buf.size());
    if (ret < 0) {
      return "";
    }
    if (static_cast<size_t>(ret) == buf.size()) {
      /* It may have been truncated */
      buf.resize(buf.size() * 2);
      continue;
    }
    return std::string(buf.data(), ret);
  }
#elif defined(__APPLE__)
  std::vector<char> buf(PATH_MAX);
    uint32_t buf_size = buf.size();
    while (_NSGetExecutablePath(buf.data(), &buf_size) != 0) {
      buf.resize(buf_size);
    }
    std::vector<char> resolved_name(PATH_MAX);
    if (realpath(buf.data(), resolved_name.data()) == nullptr) {
      return "";
    }
    return std::string(resolved_name.data());
#elif defined(WIN32)
    HMODULE hModule = GetModuleHandleA(nullptr);
    if (hModule == nullptr) {
      return "";
    }
    std::vector<char> buf(1024U);
    while (true) {
      size_t ret = GetModuleFileNameA(hModule, buf.data(), buf.size());
      if (ret == 0U) {
        return "";
      }
      if (ret == buf.size() && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
        /* It has been truncated */
        buf.resize(buf.size() * 2);
        continue;
      }
      return std::string(buf.data());
    }
#else
    return "";
#endif
}

/*
 * Returns the absolute path to the directory containing the current executable
 */
inline std::string get_executable_dir() {
  auto executable_path = get_executable_path();
  if (executable_path.empty()) {
    return "";
  }
  return get_parent_path(executable_path);
}

inline int close(int file_descriptor) {
#ifdef WIN32
  return _close(file_descriptor);
#else
  return ::close(file_descriptor);
#endif
}

inline int access(const char *path_name, int mode) {
#ifdef WIN32
  return _access(path_name, mode);
#else
  return ::access(path_name, mode);
#endif
}

#ifdef WIN32
inline std::error_code hide_file(const char* const file_name) {
    const bool success = SetFileAttributesA(file_name, FILE_ATTRIBUTE_HIDDEN);
    if (!success) {
      // note: All possible documented error codes from GetLastError are in [0;15999] at the time of writing.
      // The below casting is safe in [0;std::numeric_limits<int>::max()], int max is guaranteed to be at least 32767
      return { static_cast<int>(GetLastError()), std::system_category() };
    }
    return {};
  }
#endif /* WIN32 */

uint64_t computeChecksum(const std::string &file_name, uint64_t up_to_position);

}  // namespace file
}  // namespace utils
}  // namespace minifi
}  // namespace nifi
}  // namespace apache
}  // namespace org

#endif  // LIBMINIFI_INCLUDE_UTILS_FILE_FILEUTILS_H_
