// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "platform/globals.h"
#if defined(TARGET_OS_WINDOWS)

#include "bin/file.h"

#include <fcntl.h>  // NOLINT
#include <io.h>  // NOLINT
#include <stdio.h>  // NOLINT
#include <string.h>  // NOLINT
#include <sys/stat.h>  // NOLINT

#include "bin/builtin.h"
#include "bin/log.h"

class FileHandle {
 public:
  explicit FileHandle(int fd) : fd_(fd) { }
  ~FileHandle() { }
  int fd() const { return fd_; }
  void set_fd(int fd) { fd_ = fd; }

 private:
  int fd_;

  DISALLOW_COPY_AND_ASSIGN(FileHandle);
};


File::~File() {
  // Close the file (unless it's a standard stream).
  if (handle_->fd() > 2) {
    Close();
  }
  delete handle_;
}


void File::Close() {
  ASSERT(handle_->fd() >= 0);
  int err = close(handle_->fd());
  if (err != 0) {
    Log::PrintErr("%s\n", strerror(errno));
  }
  handle_->set_fd(kClosedFd);
}


bool File::IsClosed() {
  return handle_->fd() == kClosedFd;
}


int64_t File::Read(void* buffer, int64_t num_bytes) {
  ASSERT(handle_->fd() >= 0);
  return read(handle_->fd(), buffer, num_bytes);
}


int64_t File::Write(const void* buffer, int64_t num_bytes) {
  ASSERT(handle_->fd() >= 0);
  return write(handle_->fd(), buffer, num_bytes);
}


off_t File::Position() {
  ASSERT(handle_->fd() >= 0);
  return lseek(handle_->fd(), 0, SEEK_CUR);
}


bool File::SetPosition(int64_t position) {
  ASSERT(handle_->fd() >= 0);
  return (lseek(handle_->fd(), position, SEEK_SET) != -1);
}


bool File::Truncate(int64_t length) {
  ASSERT(handle_->fd() >= 0);
  return (chsize(handle_->fd(), length) != -1);
}


bool File::Flush() {
  ASSERT(handle_->fd());
  return _commit(handle_->fd()) != -1;
}


off_t File::Length() {
  ASSERT(handle_->fd() >= 0);
  struct stat st;
  if (fstat(handle_->fd(), &st) == 0) {
    return st.st_size;
  }
  return -1;
}


File* File::Open(const char* name, FileOpenMode mode) {
  int flags = O_RDONLY | O_BINARY | O_NOINHERIT;
  if ((mode & kWrite) != 0) {
    flags = (O_RDWR | O_CREAT | O_BINARY | O_NOINHERIT);
  }
  if ((mode & kTruncate) != 0) {
    flags = flags | O_TRUNC;
  }
  const wchar_t* system_name = StringUtils::Utf8ToWide(name);
  int fd = _wopen(system_name, flags, 0666);
  free(const_cast<wchar_t*>(system_name));
  if (fd < 0) {
    return NULL;
  }
  if (((mode & kWrite) != 0) && ((mode & kTruncate) == 0)) {
    int position = lseek(fd, 0, SEEK_END);
    if (position < 0) {
      return NULL;
    }
  }
  return new File(new FileHandle(fd));
}


File* File::OpenStdio(int fd) {
  UNREACHABLE();
  return NULL;
}


bool File::Exists(const char* name) {
  struct _stat st;
  const wchar_t* system_name = StringUtils::Utf8ToWide(name);
  bool stat_status = _wstat(system_name, &st);
  free(const_cast<wchar_t*>(system_name));
  if (stat_status == 0) {
    return ((st.st_mode & S_IFMT) == S_IFREG);
  } else {
    return false;
  }
}


bool File::Create(const char* name) {
  const wchar_t* system_name = StringUtils::Utf8ToWide(name);
  int fd = _wopen(system_name, O_RDONLY | O_CREAT, 0666);
  free(const_cast<wchar_t*>(system_name));
  if (fd < 0) {
    return false;
  }
  return (close(fd) == 0);
}


bool File::Delete(const char* name) {
  const wchar_t* system_name = StringUtils::Utf8ToWide(name);
  int status = _wremove(system_name);
  free(const_cast<wchar_t*>(system_name));
  if (status == -1) {
    return false;
  }
  return true;
}


off_t File::LengthFromPath(const char* name) {
  struct _stat st;
  const wchar_t* system_name = StringUtils::Utf8ToWide(name);
  int stat_status = _wstat(system_name, &st);
  free(const_cast<wchar_t*>(system_name));
  if (stat_status == 0) {
    return st.st_size;
  }
  return -1;
}


time_t File::LastModified(const char* name) {
  struct _stat st;
  const wchar_t* system_name = StringUtils::Utf8ToWide(name);
  int stat_status = _wstat(system_name, &st);
  free(const_cast<wchar_t*>(system_name));
  if (stat_status == 0) {
    return st.st_mtime;
  }
  return -1;
}


bool File::IsAbsolutePath(const char* pathname) {
  // Should we consider network paths?
  if (pathname == NULL) return false;
  return (strlen(pathname) > 2) &&
      (pathname[1] == ':') &&
      (pathname[2] == '\\' || pathname[2] == '/');
}


char* File::GetCanonicalPath(const char* pathname) {
  struct _stat st;
  const wchar_t* system_name = StringUtils::Utf8ToWide(pathname);
  int stat_status = _wstat(system_name, &st);
  if (stat_status != 0) {
    SetLastError(ERROR_FILE_NOT_FOUND);
    free(const_cast<wchar_t*>(system_name));
    return NULL;
  }
  int required_size = GetFullPathNameW(system_name, 0, NULL, NULL);
  wchar_t* path =
      static_cast<wchar_t*>(malloc(required_size * sizeof(wchar_t)));
  int written = GetFullPathNameW(system_name, required_size, path, NULL);
  free(const_cast<wchar_t*>(system_name));
  ASSERT(written <= (required_size - 1));
  char* result = StringUtils::WideToUtf8(path);
  free(path);
  return result;
}


char* File::GetContainingDirectory(char* pathname) {
  struct _stat st;
  wchar_t* system_name = StringUtils::Utf8ToWide(pathname);
  int stat_status = _wstat(system_name, &st);
  if (stat_status == 0) {
    if ((st.st_mode & S_IFMT) != S_IFREG) {
      SetLastError(ERROR_FILE_NOT_FOUND);
      free(system_name);
      return NULL;
    }
  } else {
    SetLastError(ERROR_FILE_NOT_FOUND);
    free(system_name);
    return NULL;
  }
  int required_size = GetFullPathNameW(system_name, 0, NULL, NULL);
  wchar_t* path =
      static_cast<wchar_t*>(malloc(required_size * sizeof(wchar_t)));
  wchar_t* file_part = NULL;
  int written =
    GetFullPathNameW(system_name, required_size, path, &file_part);
  free(system_name);
  ASSERT(written == (required_size - 1));
  ASSERT(file_part != NULL);
  ASSERT(file_part > path);
  ASSERT(file_part[-1] == L'\\');
  file_part[-1] = '\0';
  char* result = StringUtils::WideToUtf8(path);
  free(path);
  return result;
}


const char* File::PathSeparator() {
  // This is already UTF-8 encoded.
  return "\\";
}


const char* File::StringEscapedPathSeparator() {
  // This is already UTF-8 encoded.
  return "\\\\";
}


File::StdioHandleType File::GetStdioHandleType(int fd) {
  // Treat all stdio handles as pipes. The Windows event handler and
  // socket code will handle the different handle types.
  return kPipe;
}

#endif  // defined(TARGET_OS_WINDOWS)
