/*
 * This code is derived from uClibc (original license follows).
 * https://git.uclibc.org/uClibc/tree/utils/mmap-windows.c
 */
 /* mmap() replacement for Windows
 *
 * Author: Mike Frysinger <vapier@gentoo.org>
 * Placed into the public domain
 */

/* References:
 * CreateFileMapping: http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
 * CloseHandle:       http://msdn.microsoft.com/en-us/library/ms724211(VS.85).aspx
 * MapViewOfFile:     http://msdn.microsoft.com/en-us/library/aa366761(VS.85).aspx
 * UnmapViewOfFile:   http://msdn.microsoft.com/en-us/library/aa366882(VS.85).aspx
 */

#if defined(_WIN32)

#include "WindowsMMap.h"

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#include "InstrProfiling.h"

COMPILER_RT_VISIBILITY
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset)
{
  if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
    return MAP_FAILED;
  if (fd == -1) {
    if (!(flags & MAP_ANON) || offset)
      return MAP_FAILED;
  } else if (flags & MAP_ANON)
    return MAP_FAILED;

  DWORD flProtect;
  if (prot & PROT_WRITE) {
    if (prot & PROT_EXEC)
      flProtect = PAGE_EXECUTE_READWRITE;
    else
      flProtect = PAGE_READWRITE;
  } else if (prot & PROT_EXEC) {
    if (prot & PROT_READ)
      flProtect = PAGE_EXECUTE_READ;
    else if (prot & PROT_EXEC)
      flProtect = PAGE_EXECUTE;
  } else
    flProtect = PAGE_READONLY;

  off_t end = length + offset;
  HANDLE mmap_fd, h;
  if (fd == -1)
    mmap_fd = INVALID_HANDLE_VALUE;
  else
    mmap_fd = (HANDLE)_get_osfhandle(fd);
  h = CreateFileMapping(mmap_fd, NULL, flProtect, DWORD_HI(end), DWORD_LO(end), NULL);
  if (h == NULL)
    return MAP_FAILED;

  DWORD dwDesiredAccess;
  if (prot & PROT_WRITE)
    dwDesiredAccess = FILE_MAP_WRITE;
  else
    dwDesiredAccess = FILE_MAP_READ;
  if (prot & PROT_EXEC)
    dwDesiredAccess |= FILE_MAP_EXECUTE;
  if (flags & MAP_PRIVATE)
    dwDesiredAccess |= FILE_MAP_COPY;
  void *ret = MapViewOfFile(h, dwDesiredAccess, DWORD_HI(offset), DWORD_LO(offset), length);
  if (ret == NULL) {
    CloseHandle(h);
    ret = MAP_FAILED;
  }
  return ret;
}

COMPILER_RT_VISIBILITY
void munmap(void *addr, size_t length)
{
  UnmapViewOfFile(addr);
  /* ruh-ro, we leaked handle from CreateFileMapping() ... */
}

COMPILER_RT_VISIBILITY
int msync(void *addr, size_t length, int flags)
{
  if (flags & MS_INVALIDATE)
    return -1; /* Not supported. */

  /* Exactly one of MS_ASYNC or MS_SYNC must be specified. */
  switch (flags & (MS_ASYNC | MS_SYNC)) {
    case MS_SYNC:
    case MS_ASYNC:
      break;
    default:
      return -1;
  }

  if (!FlushViewOfFile(addr, length))
    return -1;

  if (flags & MS_SYNC) {
    /* FIXME: No longer have access to handle from CreateFileMapping(). */
    /*
     * if (!FlushFileBuffers(h))
     *   return -1;
     */
  }

  return 0;
}

COMPILER_RT_VISIBILITY
int lock(HANDLE handle, DWORD lockType, BOOL blocking) {
  DWORD flags = lockType;
  if (!blocking)
    flags |= LOCKFILE_FAIL_IMMEDIATELY;

  OVERLAPPED overlapped;
  ZeroMemory(&overlapped, sizeof(OVERLAPPED));
  overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
  BOOL result = LockFileEx(handle, flags, 0, MAXDWORD, MAXDWORD, &overlapped);
  if (!result) {
    DWORD dw = GetLastError();

    // In non-blocking mode, return an error if the file is locked.
    if (!blocking && dw == ERROR_LOCK_VIOLATION)
      return -1; // EWOULDBLOCK

    // If the error is ERROR_IO_PENDING, we need to wait until the operation
    // finishes. Otherwise, we return an error.
    if (dw != ERROR_IO_PENDING)
      return -1;

    DWORD dwNumBytes;
    if (!GetOverlappedResult(handle, &overlapped, &dwNumBytes, TRUE))
      return -1;
  }

  return 0;
}

COMPILER_RT_VISIBILITY
int flock(int fd, int operation) {
  HANDLE handle = (HANDLE)_get_osfhandle(fd);
  if (handle == INVALID_HANDLE_VALUE)
    return -1;

  BOOL blocking = (operation & LOCK_NB) == 0;
  int op = operation & ~LOCK_NB;

  switch (op) {
  case LOCK_EX:
    return lock(handle, LOCKFILE_EXCLUSIVE_LOCK, blocking);

  case LOCK_SH:
    return lock(handle, 0, blocking);

  case LOCK_UN:
    if (!UnlockFile(handle, 0, 0, MAXDWORD, MAXDWORD))
      return -1;
    break;

  default:
    return -1;
  }

  return 0;
}

#undef DWORD_HI
#undef DWORD_LO

#endif /* _WIN32 */
