/** @file

    Minimalist version of std::filesystem.

    @section license License

    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.
 */

#include "tscore/ts_file.h"
#include <fcntl.h>
#include <sys/types.h>
#include <dirent.h>

namespace ts
{
namespace file
{
  path &
  path::operator/=(std::string_view that)
  {
    if (!that.empty()) { // don't waste time appending nothing.
      if (that.front() == preferred_separator || _path.empty()) {
        _path.assign(that);
      } else {
        if (_path.back() == preferred_separator) {
          _path.reserve(_path.size() + that.size());
        } else {
          _path.reserve(_path.size() + that.size() + 1);
          _path.push_back(preferred_separator);
        }
        _path.append(that);
      }
    }
    return *this;
  }

  file_status
  status(const path &p, std::error_code &ec) noexcept
  {
    file_status zret;
    if (::stat(p.c_str(), &zret._stat) >= 0) {
      ec.clear();
    } else {
      ec = std::error_code(errno, std::system_category());
    }
    return zret;
  }

  path
  temp_directory_path()
  {
    /* ISO/IEC 9945 (POSIX): The path supplied by the first environment variable found in the list TMPDIR, TMP, TEMP, TEMPDIR.
     * If none of these are found, "/tmp" */
    char const *folder = nullptr;
    if ((nullptr == (folder = getenv("TMPDIR"))) && (nullptr == (folder = getenv("TMP"))) &&
        (nullptr == (folder = getenv("TEMPDIR")))) {
      folder = "/tmp";
    }
    return path(folder);
  }

  path
  current_path()
  {
    char cwd[PATH_MAX];
    if (::getcwd(cwd, sizeof(cwd)) != nullptr) {
      return path(cwd);
    }
    return path();
  }

  path
  canonical(const path &p, std::error_code &ec)
  {
    if (p.empty()) {
      ec = std::error_code(EINVAL, std::system_category());
      return path();
    }

    char buf[PATH_MAX + 1];
    char *res = ::realpath(p.c_str(), buf);
    if (res) {
      ec = std::error_code();
      return path(res);
    }

    ec = std::error_code(errno, std::system_category());
    return path();
  }

  path
  filename(const path &p)
  {
    const size_t last_slash_idx = p.string().find_last_of(p.preferred_separator);
    return p.string().substr(last_slash_idx + 1);
  }

  bool
  exists(const path &p)
  {
    std::error_code ec;
    status(p, ec);
    return !(ec && ENOENT == ec.value());
  }

  static bool
  do_mkdir(const path &p, std::error_code &ec, mode_t mode)
  {
    struct stat st;
    if (stat(p.c_str(), &st) != 0) {
      if (mkdir(p.c_str(), mode) != 0 && errno != EEXIST) {
        ec = std::error_code(errno, std::system_category());
        return false;
      }
    } else if (!S_ISDIR(st.st_mode)) {
      ec = std::error_code(ENOTDIR, std::system_category());
      return false;
    }
    return true;
  }

  bool
  create_directories(const path &p, std::error_code &ec, mode_t mode) noexcept
  {
    if (p.empty()) {
      ec = std::error_code(EINVAL, std::system_category());
      return false;
    }

    bool result = false;
    ec          = std::error_code();

    size_t pos = 0;
    std::string token;
    while ((pos = p.string().find_first_of(p.preferred_separator, pos)) != std::string::npos) {
      token = p.string().substr(0, pos);
      if (!token.empty()) {
        result = do_mkdir(path(token), ec, mode);
      }
      pos = pos + sizeof(p.preferred_separator);
    }

    if (result) {
      result = do_mkdir(p, ec, mode);
    }
    return result;
  }

  bool
  copy(const path &from, const path &to, std::error_code &ec)
  {
    static int BUF_SIZE = 65536;
    FILE *src, *dst;
    char buf[BUF_SIZE];
    int bufsize = BUF_SIZE;

    if (from.empty() || to.empty()) {
      ec = std::error_code(EINVAL, std::system_category());
      return false;
    }

    ec = std::error_code();

    std::error_code err;
    path final_to;
    file_status s = status(to, err);
    if (!(err && ENOENT == err.value()) && is_dir(s)) {
      const auto file = filename(from);
      final_to        = to / file;
    } else {
      final_to = to;
    }

    if (nullptr == (src = fopen(from.c_str(), "r"))) {
      ec = std::error_code(errno, std::system_category());
      return false;
    }
    if (nullptr == (dst = fopen(final_to.c_str(), "w"))) {
      ec = std::error_code(errno, std::system_category());
      fclose(src);
      return false;
    }

    while (true) {
      size_t in = fread(buf, 1, bufsize, src);
      if (0 == in) {
        break;
      }
      size_t out = fwrite(buf, 1, in, dst);
      if (0 == out) {
        break;
      }
    }

    fclose(src);
    fclose(dst);

    return true;
  }

  static bool
  remove_path(const path &p, std::error_code &ec)
  {
    DIR *dir;
    struct dirent *entry;
    bool res = true;
    std::error_code err;

    file_status s = status(p, err);
    if (err && ENOENT == err.value()) {
      // file/dir does not exist
      return false;
    } else if (is_regular_file(s)) {
      // regular file, try to remove it!
      if (unlink(p.c_str()) != 0) {
        ec  = std::error_code(errno, std::system_category());
        res = false;
      }
      return res;
    } else if (!is_dir(s)) {
      // not a directory
      ec = std::error_code(ENOTDIR, std::system_category());
      return false;
    }

    // recursively remove nested files and directories
    if (nullptr == (dir = opendir(p.c_str()))) {
      ec = std::error_code(errno, std::system_category());
      return false;
    }

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

      remove_path(p / entry->d_name, ec);
    }

    if (0 != rmdir(p.c_str())) {
      ec = std::error_code(errno, std::system_category());
    }

    closedir(dir);
    return true;
  }

  bool
  remove(const path &p, std::error_code &ec)
  {
    if (p.empty()) {
      ec = std::error_code(EINVAL, std::system_category());
      return false;
    }

    ec = std::error_code();
    return remove_path(p, ec);
  } // namespace file

  int
  file_type(const file_status &fs)
  {
    return fs._stat.st_mode & S_IFMT;
  }

  time_t
  modification_time(const file_status &fs)
  {
    return fs._stat.st_mtime;
  }
  uintmax_t
  file_size(const file_status &fs)
  {
    return fs._stat.st_size;
  }

  bool
  is_char_device(const file_status &fs)
  {
    return file_type(fs) == S_IFCHR;
  }

  bool
  is_block_device(const file_status &fs)
  {
    return file_type(fs) == S_IFBLK;
  }

  bool
  is_regular_file(const file_status &fs)
  {
    return file_type(fs) == S_IFREG;
  }

  bool
  is_dir(const file_status &fs)
  {
    return file_type(fs) == S_IFDIR;
  }

  bool
  is_readable(const path &p)
  {
    return 0 == access(p.c_str(), R_OK);
  }

  std::string
  load(const path &p, std::error_code &ec)
  {
    std::string zret;
    ats_scoped_fd fd(::open(p.c_str(), O_RDONLY));
    ec.clear();
    if (fd < 0) {
      ec = std::error_code(errno, std::system_category());
    } else {
      struct stat info;
      if (0 != ::fstat(fd, &info)) {
        ec = std::error_code(errno, std::system_category());
      } else {
        int n = info.st_size;
        zret.resize(n);
        auto read_len = ::read(fd, const_cast<char *>(zret.data()), n);
        if (read_len < n) {
          ec = std::error_code(errno, std::system_category());
        }
      }
    }
    return zret;
  }

} // namespace file
} // namespace ts
