//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

//
// POSIX-like portability helper functions.
//
// These generally behave like the proper posix functions, with these
// exceptions:
// On Windows, they take paths in wchar_t* form, instead of char* form.
// The symlink() function is split into two frontends, symlink_file()
// and symlink_dir().
//
// These are provided within an anonymous namespace within the detail
// namespace - callers need to include this header and call them as
// detail::function(), regardless of platform.
//

#ifndef POSIX_COMPAT_H
#define POSIX_COMPAT_H

#include <__assert>
#include <filesystem>

#include "filesystem_common.h"

#if defined(_LIBCPP_WIN32API)
# define WIN32_LEAN_AND_MEAN
# define NOMINMAX
# include <windows.h>
# include <io.h>
# include <winioctl.h>
#else
# include <unistd.h>
# include <sys/stat.h>
# include <sys/statvfs.h>
#endif
#include <time.h>

#if defined(_LIBCPP_WIN32API)
// This struct isn't defined in the normal Windows SDK, but only in the
// Windows Driver Kit.
struct LIBCPP_REPARSE_DATA_BUFFER {
  unsigned long  ReparseTag;
  unsigned short ReparseDataLength;
  unsigned short Reserved;
  union {
    struct {
      unsigned short SubstituteNameOffset;
      unsigned short SubstituteNameLength;
      unsigned short PrintNameOffset;
      unsigned short PrintNameLength;
      unsigned long  Flags;
      wchar_t        PathBuffer[1];
    } SymbolicLinkReparseBuffer;
    struct {
      unsigned short SubstituteNameOffset;
      unsigned short SubstituteNameLength;
      unsigned short PrintNameOffset;
      unsigned short PrintNameLength;
      wchar_t        PathBuffer[1];
    } MountPointReparseBuffer;
    struct {
      unsigned char DataBuffer[1];
    } GenericReparseBuffer;
  };
};
#endif

_LIBCPP_BEGIN_NAMESPACE_FILESYSTEM

namespace detail {
namespace {

#if defined(_LIBCPP_WIN32API)

// Various C runtime header sets provide more or less of these. As we
// provide our own implementation, undef all potential defines from the
// C runtime headers and provide a complete set of macros of our own.

#undef _S_IFMT
#undef _S_IFDIR
#undef _S_IFCHR
#undef _S_IFIFO
#undef _S_IFREG
#undef _S_IFBLK
#undef _S_IFLNK
#undef _S_IFSOCK

#define _S_IFMT   0xF000
#define _S_IFDIR  0x4000
#define _S_IFCHR  0x2000
#define _S_IFIFO  0x1000
#define _S_IFREG  0x8000
#define _S_IFBLK  0x6000
#define _S_IFLNK  0xA000
#define _S_IFSOCK 0xC000

#undef S_ISDIR
#undef S_ISFIFO
#undef S_ISCHR
#undef S_ISREG
#undef S_ISLNK
#undef S_ISBLK
#undef S_ISSOCK

#define S_ISDIR(m)      (((m) & _S_IFMT) == _S_IFDIR)
#define S_ISCHR(m)      (((m) & _S_IFMT) == _S_IFCHR)
#define S_ISFIFO(m)     (((m) & _S_IFMT) == _S_IFIFO)
#define S_ISREG(m)      (((m) & _S_IFMT) == _S_IFREG)
#define S_ISBLK(m)      (((m) & _S_IFMT) == _S_IFBLK)
#define S_ISLNK(m)      (((m) & _S_IFMT) == _S_IFLNK)
#define S_ISSOCK(m)     (((m) & _S_IFMT) == _S_IFSOCK)

#define O_NONBLOCK 0


// There were 369 years and 89 leap days from the Windows epoch
// (1601) to the Unix epoch (1970).
#define FILE_TIME_OFFSET_SECS (uint64_t(369 * 365 + 89) * (24 * 60 * 60))

TimeSpec filetime_to_timespec(LARGE_INTEGER li) {
  TimeSpec ret;
  ret.tv_sec = li.QuadPart / 10000000 - FILE_TIME_OFFSET_SECS;
  ret.tv_nsec = (li.QuadPart % 10000000) * 100;
  return ret;
}

TimeSpec filetime_to_timespec(FILETIME ft) {
  LARGE_INTEGER li;
  li.LowPart = ft.dwLowDateTime;
  li.HighPart = ft.dwHighDateTime;
  return filetime_to_timespec(li);
}

FILETIME timespec_to_filetime(TimeSpec ts) {
  LARGE_INTEGER li;
  li.QuadPart =
      ts.tv_nsec / 100 + (ts.tv_sec + FILE_TIME_OFFSET_SECS) * 10000000;
  FILETIME ft;
  ft.dwLowDateTime = li.LowPart;
  ft.dwHighDateTime = li.HighPart;
  return ft;
}

int set_errno(int e = GetLastError()) {
  errno = static_cast<int>(__win_err_to_errc(e));
  return -1;
}

class WinHandle {
public:
  WinHandle(const wchar_t *p, DWORD access, DWORD flags) {
    h = CreateFileW(
        p, access, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
        nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | flags, nullptr);
  }
  ~WinHandle() {
    if (h != INVALID_HANDLE_VALUE)
      CloseHandle(h);
  }
  operator HANDLE() const { return h; }
  operator bool() const { return h != INVALID_HANDLE_VALUE; }

private:
  HANDLE h;
};

int stat_handle(HANDLE h, StatT *buf) {
  FILE_BASIC_INFO basic;
  if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
    return set_errno();
  memset(buf, 0, sizeof(*buf));
  buf->st_mtim = filetime_to_timespec(basic.LastWriteTime);
  buf->st_atim = filetime_to_timespec(basic.LastAccessTime);
  buf->st_mode = 0555; // Read-only
  if (!(basic.FileAttributes & FILE_ATTRIBUTE_READONLY))
    buf->st_mode |= 0222; // Write
  if (basic.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
    buf->st_mode |= _S_IFDIR;
  } else {
    buf->st_mode |= _S_IFREG;
  }
  if (basic.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
    FILE_ATTRIBUTE_TAG_INFO tag;
    if (!GetFileInformationByHandleEx(h, FileAttributeTagInfo, &tag,
                                      sizeof(tag)))
      return set_errno();
    if (tag.ReparseTag == IO_REPARSE_TAG_SYMLINK)
      buf->st_mode = (buf->st_mode & ~_S_IFMT) | _S_IFLNK;
  }
  FILE_STANDARD_INFO standard;
  if (!GetFileInformationByHandleEx(h, FileStandardInfo, &standard,
                                    sizeof(standard)))
    return set_errno();
  buf->st_nlink = standard.NumberOfLinks;
  buf->st_size = standard.EndOfFile.QuadPart;
  BY_HANDLE_FILE_INFORMATION info;
  if (!GetFileInformationByHandle(h, &info))
    return set_errno();
  buf->st_dev = info.dwVolumeSerialNumber;
  memcpy(&buf->st_ino.id[0], &info.nFileIndexHigh, 4);
  memcpy(&buf->st_ino.id[4], &info.nFileIndexLow, 4);
  return 0;
}

int stat_file(const wchar_t *path, StatT *buf, DWORD flags) {
  WinHandle h(path, FILE_READ_ATTRIBUTES, flags);
  if (!h)
    return set_errno();
  int ret = stat_handle(h, buf);
  return ret;
}

int stat(const wchar_t *path, StatT *buf) { return stat_file(path, buf, 0); }

int lstat(const wchar_t *path, StatT *buf) {
  return stat_file(path, buf, FILE_FLAG_OPEN_REPARSE_POINT);
}

int fstat(int fd, StatT *buf) {
  HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
  return stat_handle(h, buf);
}

int mkdir(const wchar_t *path, int permissions) {
  (void)permissions;
  return _wmkdir(path);
}

int symlink_file_dir(const wchar_t *oldname, const wchar_t *newname,
                     bool is_dir) {
  path dest(oldname);
  dest.make_preferred();
  oldname = dest.c_str();
  DWORD flags = is_dir ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0;
  if (CreateSymbolicLinkW(newname, oldname,
                          flags | SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE))
    return 0;
  int e = GetLastError();
  if (e != ERROR_INVALID_PARAMETER)
    return set_errno(e);
  if (CreateSymbolicLinkW(newname, oldname, flags))
    return 0;
  return set_errno();
}

int symlink_file(const wchar_t *oldname, const wchar_t *newname) {
  return symlink_file_dir(oldname, newname, false);
}

int symlink_dir(const wchar_t *oldname, const wchar_t *newname) {
  return symlink_file_dir(oldname, newname, true);
}

int link(const wchar_t *oldname, const wchar_t *newname) {
  if (CreateHardLinkW(newname, oldname, nullptr))
    return 0;
  return set_errno();
}

int remove(const wchar_t *path) {
  detail::WinHandle h(path, DELETE, FILE_FLAG_OPEN_REPARSE_POINT);
  if (!h)
    return set_errno();
  FILE_DISPOSITION_INFO info;
  info.DeleteFile = TRUE;
  if (!SetFileInformationByHandle(h, FileDispositionInfo, &info, sizeof(info)))
    return set_errno();
  return 0;
}

int truncate_handle(HANDLE h, off_t length) {
  LARGE_INTEGER size_param;
  size_param.QuadPart = length;
  if (!SetFilePointerEx(h, size_param, 0, FILE_BEGIN))
    return set_errno();
  if (!SetEndOfFile(h))
    return set_errno();
  return 0;
}

int ftruncate(int fd, off_t length) {
  HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
  return truncate_handle(h, length);
}

int truncate(const wchar_t *path, off_t length) {
  detail::WinHandle h(path, GENERIC_WRITE, 0);
  if (!h)
    return set_errno();
  return truncate_handle(h, length);
}

int rename(const wchar_t *from, const wchar_t *to) {
  if (!(MoveFileExW(from, to,
                    MOVEFILE_COPY_ALLOWED | MOVEFILE_REPLACE_EXISTING |
                        MOVEFILE_WRITE_THROUGH)))
    return set_errno();
  return 0;
}

template <class... Args> int open(const wchar_t *filename, Args... args) {
  return _wopen(filename, args...);
}
int close(int fd) { return _close(fd); }
int chdir(const wchar_t *path) { return _wchdir(path); }

struct StatVFS {
  uint64_t f_frsize;
  uint64_t f_blocks;
  uint64_t f_bfree;
  uint64_t f_bavail;
};

int statvfs(const wchar_t *p, StatVFS *buf) {
  path dir = p;
  while (true) {
    error_code local_ec;
    const file_status st = status(dir, local_ec);
    if (!exists(st) || is_directory(st))
      break;
    path parent = dir.parent_path();
    if (parent == dir) {
      errno = ENOENT;
      return -1;
    }
    dir = parent;
  }
  ULARGE_INTEGER free_bytes_available_to_caller, total_number_of_bytes,
      total_number_of_free_bytes;
  if (!GetDiskFreeSpaceExW(dir.c_str(), &free_bytes_available_to_caller,
                           &total_number_of_bytes, &total_number_of_free_bytes))
    return set_errno();
  buf->f_frsize = 1;
  buf->f_blocks = total_number_of_bytes.QuadPart;
  buf->f_bfree = total_number_of_free_bytes.QuadPart;
  buf->f_bavail = free_bytes_available_to_caller.QuadPart;
  return 0;
}

wchar_t *getcwd(wchar_t *buff, size_t size) { return _wgetcwd(buff, size); }

wchar_t *realpath(const wchar_t *path, wchar_t *resolved_name) {
  // Only expected to be used with us allocating the buffer.
  _LIBCPP_ASSERT(resolved_name == nullptr,
                 "Windows realpath() assumes a null resolved_name");

  WinHandle h(path, FILE_READ_ATTRIBUTES, 0);
  if (!h) {
    set_errno();
    return nullptr;
  }
  size_t buff_size = MAX_PATH + 10;
  std::unique_ptr<wchar_t, decltype(&::free)> buff(
      static_cast<wchar_t *>(malloc(buff_size * sizeof(wchar_t))), &::free);
  DWORD retval = GetFinalPathNameByHandleW(
      h, buff.get(), buff_size, FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
  if (retval > buff_size) {
    buff_size = retval;
    buff.reset(static_cast<wchar_t *>(malloc(buff_size * sizeof(wchar_t))));
    retval = GetFinalPathNameByHandleW(h, buff.get(), buff_size,
                                       FILE_NAME_NORMALIZED | VOLUME_NAME_DOS);
  }
  if (!retval) {
    set_errno();
    return nullptr;
  }
  wchar_t *ptr = buff.get();
  if (!wcsncmp(ptr, L"\\\\?\\", 4)) {
    if (ptr[5] == ':') { // \\?\X: -> X:
      memmove(&ptr[0], &ptr[4], (wcslen(&ptr[4]) + 1) * sizeof(wchar_t));
    } else if (!wcsncmp(&ptr[4], L"UNC\\", 4)) { // \\?\UNC\server -> \\server
      wcscpy(&ptr[0], L"\\\\");
      memmove(&ptr[2], &ptr[8], (wcslen(&ptr[8]) + 1) * sizeof(wchar_t));
    }
  }
  return buff.release();
}

#define AT_FDCWD -1
#define AT_SYMLINK_NOFOLLOW 1
using ModeT = int;

int fchmod_handle(HANDLE h, int perms) {
  FILE_BASIC_INFO basic;
  if (!GetFileInformationByHandleEx(h, FileBasicInfo, &basic, sizeof(basic)))
    return set_errno();
  DWORD orig_attributes = basic.FileAttributes;
  basic.FileAttributes &= ~FILE_ATTRIBUTE_READONLY;
  if ((perms & 0222) == 0)
    basic.FileAttributes |= FILE_ATTRIBUTE_READONLY;
  if (basic.FileAttributes != orig_attributes &&
      !SetFileInformationByHandle(h, FileBasicInfo, &basic, sizeof(basic)))
    return set_errno();
  return 0;
}

int fchmodat(int fd, const wchar_t *path, int perms, int flag) {
  DWORD attributes = GetFileAttributesW(path);
  if (attributes == INVALID_FILE_ATTRIBUTES)
    return set_errno();
  if (attributes & FILE_ATTRIBUTE_REPARSE_POINT &&
      !(flag & AT_SYMLINK_NOFOLLOW)) {
    // If the file is a symlink, and we are supposed to operate on the target
    // of the symlink, we need to open a handle to it, without the
    // FILE_FLAG_OPEN_REPARSE_POINT flag, to open the destination of the
    // symlink, and operate on it via the handle.
    detail::WinHandle h(path, FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES, 0);
    if (!h)
      return set_errno();
    return fchmod_handle(h, perms);
  } else {
    // For a non-symlink, or if operating on the symlink itself instead of
    // its target, we can use SetFileAttributesW, saving a few calls.
    DWORD orig_attributes = attributes;
    attributes &= ~FILE_ATTRIBUTE_READONLY;
    if ((perms & 0222) == 0)
      attributes |= FILE_ATTRIBUTE_READONLY;
    if (attributes != orig_attributes && !SetFileAttributesW(path, attributes))
      return set_errno();
  }
  return 0;
}

int fchmod(int fd, int perms) {
  HANDLE h = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
  return fchmod_handle(h, perms);
}

#define MAX_SYMLINK_SIZE MAXIMUM_REPARSE_DATA_BUFFER_SIZE
using SSizeT = ::int64_t;

SSizeT readlink(const wchar_t *path, wchar_t *ret_buf, size_t bufsize) {
  uint8_t buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
  detail::WinHandle h(path, FILE_READ_ATTRIBUTES, FILE_FLAG_OPEN_REPARSE_POINT);
  if (!h)
    return set_errno();
  DWORD out;
  if (!DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, nullptr, 0, buf, sizeof(buf),
                       &out, 0))
    return set_errno();
  const auto *reparse = reinterpret_cast<LIBCPP_REPARSE_DATA_BUFFER *>(buf);
  size_t path_buf_offset = offsetof(LIBCPP_REPARSE_DATA_BUFFER,
                                    SymbolicLinkReparseBuffer.PathBuffer[0]);
  if (out < path_buf_offset) {
    errno = EINVAL;
    return -1;
  }
  if (reparse->ReparseTag != IO_REPARSE_TAG_SYMLINK) {
    errno = EINVAL;
    return -1;
  }
  const auto &symlink = reparse->SymbolicLinkReparseBuffer;
  unsigned short name_offset, name_length;
  if (symlink.PrintNameLength == 0) {
    name_offset = symlink.SubstituteNameOffset;
    name_length = symlink.SubstituteNameLength;
  } else {
    name_offset = symlink.PrintNameOffset;
    name_length = symlink.PrintNameLength;
  }
  // name_offset/length are expressed in bytes, not in wchar_t
  if (path_buf_offset + name_offset + name_length > out) {
    errno = EINVAL;
    return -1;
  }
  if (name_length / sizeof(wchar_t) > bufsize) {
    errno = ENOMEM;
    return -1;
  }
  memcpy(ret_buf, &symlink.PathBuffer[name_offset / sizeof(wchar_t)],
         name_length);
  return name_length / sizeof(wchar_t);
}

#else
int symlink_file(const char *oldname, const char *newname) {
  return ::symlink(oldname, newname);
}
int symlink_dir(const char *oldname, const char *newname) {
  return ::symlink(oldname, newname);
}
using ::chdir;
using ::close;
using ::fchmod;
#if defined(AT_SYMLINK_NOFOLLOW) && defined(AT_FDCWD)
using ::fchmodat;
#endif
using ::fstat;
using ::ftruncate;
using ::getcwd;
using ::link;
using ::lstat;
using ::mkdir;
using ::open;
using ::readlink;
using ::realpath;
using ::remove;
using ::rename;
using ::stat;
using ::statvfs;
using ::truncate;

#define O_BINARY 0

using StatVFS = struct statvfs;
using ModeT = ::mode_t;
using SSizeT = ::ssize_t;

#endif

} // namespace
} // end namespace detail

_LIBCPP_END_NAMESPACE_FILESYSTEM

#endif // POSIX_COMPAT_H
