//===-- ConnectionGenericFileWindows.cpp ------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "lldb/Host/windows/ConnectionGenericFileWindows.h"
#include "lldb/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/TimeValue.h"

#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/ConvertUTF.h"

using namespace lldb;
using namespace lldb_private;

namespace {
// This is a simple helper class to package up the information needed to return
// from a Read/Write
// operation function.  Since there is a lot of code to be run before exit
// regardless of whether the
// operation succeeded or failed, combined with many possible return paths, this
// is the cleanest
// way to represent it.
class ReturnInfo {
public:
  void Set(size_t bytes, ConnectionStatus status, DWORD error_code) {
    m_error.SetError(error_code, eErrorTypeWin32);
    m_bytes = bytes;
    m_status = status;
  }

  void Set(size_t bytes, ConnectionStatus status, llvm::StringRef error_msg) {
    m_error.SetErrorString(error_msg.data());
    m_bytes = bytes;
    m_status = status;
  }

  size_t GetBytes() const { return m_bytes; }
  ConnectionStatus GetStatus() const { return m_status; }
  const Error &GetError() const { return m_error; }

private:
  Error m_error;
  size_t m_bytes;
  ConnectionStatus m_status;
};
}

ConnectionGenericFile::ConnectionGenericFile()
    : m_file(INVALID_HANDLE_VALUE), m_owns_file(false) {
  ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));
  ::ZeroMemory(&m_file_position, sizeof(m_file_position));
  InitializeEventHandles();
}

ConnectionGenericFile::ConnectionGenericFile(lldb::file_t file, bool owns_file)
    : m_file(file), m_owns_file(owns_file) {
  ::ZeroMemory(&m_overlapped, sizeof(m_overlapped));
  ::ZeroMemory(&m_file_position, sizeof(m_file_position));
  InitializeEventHandles();
}

ConnectionGenericFile::~ConnectionGenericFile() {
  if (m_owns_file && IsConnected())
    ::CloseHandle(m_file);

  ::CloseHandle(m_event_handles[kBytesAvailableEvent]);
  ::CloseHandle(m_event_handles[kInterruptEvent]);
}

void ConnectionGenericFile::InitializeEventHandles() {
  m_event_handles[kInterruptEvent] = CreateEvent(NULL, FALSE, FALSE, NULL);

  // Note, we should use a manual reset event for the hEvent argument of the
  // OVERLAPPED.  This
  // is because both WaitForMultipleObjects and GetOverlappedResult (if you set
  // the bWait
  // argument to TRUE) will wait for the event to be signalled.  If we use an
  // auto-reset event,
  // WaitForMultipleObjects will reset the event, return successfully, and then
  // GetOverlappedResult will block since the event is no longer signalled.
  m_event_handles[kBytesAvailableEvent] =
      ::CreateEvent(NULL, TRUE, FALSE, NULL);
}

bool ConnectionGenericFile::IsConnected() const {
  return m_file && (m_file != INVALID_HANDLE_VALUE);
}

lldb::ConnectionStatus ConnectionGenericFile::Connect(const char *s,
                                                      Error *error_ptr) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  if (log)
    log->Printf("%p ConnectionGenericFile::Connect (url = '%s')",
                static_cast<void *>(this), s);

  if (strstr(s, "file://") != s) {
    if (error_ptr)
      error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'",
                                          s);
    return eConnectionStatusError;
  }

  if (IsConnected()) {
    ConnectionStatus status = Disconnect(error_ptr);
    if (status != eConnectionStatusSuccess)
      return status;
  }

  // file://PATH
  const char *path = s + strlen("file://");
  // Open the file for overlapped access.  If it does not exist, create it.  We
  // open it overlapped
  // so that we can issue asynchronous reads and then use WaitForMultipleObjects
  // to allow the read
  // to be interrupted by an event object.
  std::wstring wpath;
  if (!llvm::ConvertUTF8toWide(path, wpath)) {
    if (error_ptr)
      error_ptr->SetError(1, eErrorTypeGeneric);
    return eConnectionStatusError;
  }
  m_file = ::CreateFileW(wpath.c_str(), GENERIC_READ | GENERIC_WRITE,
                         FILE_SHARE_READ, NULL, OPEN_ALWAYS,
                         FILE_FLAG_OVERLAPPED, NULL);
  if (m_file == INVALID_HANDLE_VALUE) {
    if (error_ptr)
      error_ptr->SetError(::GetLastError(), eErrorTypeWin32);
    return eConnectionStatusError;
  }

  m_owns_file = true;
  m_uri.assign(s);
  return eConnectionStatusSuccess;
}

lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Error *error_ptr) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  if (log)
    log->Printf("%p ConnectionGenericFile::Disconnect ()",
                static_cast<void *>(this));

  if (!IsConnected())
    return eConnectionStatusSuccess;

  // Reset the handle so that after we unblock any pending reads, subsequent
  // calls to Read() will
  // see a disconnected state.
  HANDLE old_file = m_file;
  m_file = INVALID_HANDLE_VALUE;

  // Set the disconnect event so that any blocking reads unblock, then cancel
  // any pending IO operations.
  ::CancelIoEx(old_file, &m_overlapped);

  // Close the file handle if we owned it, but don't close the event handles.
  // We could always
  // reconnect with the same Connection instance.
  if (m_owns_file)
    ::CloseHandle(old_file);

  ::ZeroMemory(&m_file_position, sizeof(m_file_position));
  m_owns_file = false;
  m_uri.clear();
  return eConnectionStatusSuccess;
}

size_t ConnectionGenericFile::Read(void *dst, size_t dst_len,
                                   uint32_t timeout_usec,
                                   lldb::ConnectionStatus &status,
                                   Error *error_ptr) {
  ReturnInfo return_info;
  BOOL result = 0;
  DWORD bytes_read = 0;

  if (error_ptr)
    error_ptr->Clear();

  if (!IsConnected()) {
    return_info.Set(0, eConnectionStatusNoConnection, ERROR_INVALID_HANDLE);
    goto finish;
  }

  m_overlapped.hEvent = m_event_handles[kBytesAvailableEvent];

  result = ::ReadFile(m_file, dst, dst_len, NULL, &m_overlapped);
  if (result || ::GetLastError() == ERROR_IO_PENDING) {
    if (!result) {
      // The expected return path.  The operation is pending.  Wait for the
      // operation to complete
      // or be interrupted.
      TimeValue time_value;
      time_value.OffsetWithMicroSeconds(timeout_usec);
      DWORD milliseconds = time_value.milliseconds();
      DWORD wait_result =
          ::WaitForMultipleObjects(llvm::array_lengthof(m_event_handles),
                                   m_event_handles, FALSE, milliseconds);
      // All of the events are manual reset events, so make sure we reset them
      // to non-signalled.
      switch (wait_result) {
      case WAIT_OBJECT_0 + kBytesAvailableEvent:
        break;
      case WAIT_OBJECT_0 + kInterruptEvent:
        return_info.Set(0, eConnectionStatusInterrupted, 0);
        goto finish;
      case WAIT_TIMEOUT:
        return_info.Set(0, eConnectionStatusTimedOut, 0);
        goto finish;
      case WAIT_FAILED:
        return_info.Set(0, eConnectionStatusError, ::GetLastError());
        goto finish;
      }
    }
    // The data is ready.  Figure out how much was read and return;
    if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_read, FALSE)) {
      DWORD result_error = ::GetLastError();
      // ERROR_OPERATION_ABORTED occurs when someone calls Disconnect() during a
      // blocking read.
      // This triggers a call to CancelIoEx, which causes the operation to
      // complete and the
      // result to be ERROR_OPERATION_ABORTED.
      if (result_error == ERROR_HANDLE_EOF ||
          result_error == ERROR_OPERATION_ABORTED ||
          result_error == ERROR_BROKEN_PIPE)
        return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);
      else
        return_info.Set(bytes_read, eConnectionStatusError, result_error);
    } else if (bytes_read == 0)
      return_info.Set(bytes_read, eConnectionStatusEndOfFile, 0);
    else
      return_info.Set(bytes_read, eConnectionStatusSuccess, 0);

    goto finish;
  } else if (::GetLastError() == ERROR_BROKEN_PIPE) {
    // The write end of a pipe was closed.  This is equivalent to EOF.
    return_info.Set(0, eConnectionStatusEndOfFile, 0);
  } else {
    // An unknown error occurred.  Fail out.
    return_info.Set(0, eConnectionStatusError, ::GetLastError());
  }
  goto finish;

finish:
  status = return_info.GetStatus();
  if (error_ptr)
    *error_ptr = return_info.GetError();

  // kBytesAvailableEvent is a manual reset event.  Make sure it gets reset here
  // so that any
  // subsequent operations don't immediately see bytes available.
  ResetEvent(m_event_handles[kBytesAvailableEvent]);

  IncrementFilePointer(return_info.GetBytes());
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  if (log) {
    log->Printf("%" PRIxPTR " ConnectionGenericFile::Read()  handle = %" PRIxPTR
                ", dst = %" PRIxPTR ", dst_len = %" PRIu64 ") => %" PRIu64
                ", error = %s",
                this, m_file, dst, static_cast<uint64_t>(dst_len),
                static_cast<uint64_t>(return_info.GetBytes()),
                return_info.GetError().AsCString());
  }

  return return_info.GetBytes();
}

size_t ConnectionGenericFile::Write(const void *src, size_t src_len,
                                    lldb::ConnectionStatus &status,
                                    Error *error_ptr) {
  ReturnInfo return_info;
  DWORD bytes_written = 0;
  BOOL result = 0;

  if (error_ptr)
    error_ptr->Clear();

  if (!IsConnected()) {
    return_info.Set(0, eConnectionStatusNoConnection, ERROR_INVALID_HANDLE);
    goto finish;
  }

  m_overlapped.hEvent = NULL;

  // Writes are not interruptible like reads are, so just block until it's done.
  result = ::WriteFile(m_file, src, src_len, NULL, &m_overlapped);
  if (!result && ::GetLastError() != ERROR_IO_PENDING) {
    return_info.Set(0, eConnectionStatusError, ::GetLastError());
    goto finish;
  }

  if (!::GetOverlappedResult(m_file, &m_overlapped, &bytes_written, TRUE)) {
    return_info.Set(bytes_written, eConnectionStatusError, ::GetLastError());
    goto finish;
  }

  return_info.Set(bytes_written, eConnectionStatusSuccess, 0);
  goto finish;

finish:
  status = return_info.GetStatus();
  if (error_ptr)
    *error_ptr = return_info.GetError();

  IncrementFilePointer(return_info.GetBytes());
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  if (log) {
    log->Printf("%" PRIxPTR
                " ConnectionGenericFile::Write()  handle = %" PRIxPTR
                ", src = %" PRIxPTR ", src_len = %" PRIu64 ") => %" PRIu64
                ", error = %s",
                this, m_file, src, static_cast<uint64_t>(src_len),
                static_cast<uint64_t>(return_info.GetBytes()),
                return_info.GetError().AsCString());
  }
  return return_info.GetBytes();
}

std::string ConnectionGenericFile::GetURI() { return m_uri; }

bool ConnectionGenericFile::InterruptRead() {
  return ::SetEvent(m_event_handles[kInterruptEvent]);
}

void ConnectionGenericFile::IncrementFilePointer(DWORD amount) {
  LARGE_INTEGER old_pos;
  old_pos.HighPart = m_overlapped.OffsetHigh;
  old_pos.LowPart = m_overlapped.Offset;
  old_pos.QuadPart += amount;
  m_overlapped.Offset = old_pos.LowPart;
  m_overlapped.OffsetHigh = old_pos.HighPart;
}
