//===-- 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/Utility/Log.h"
#include "lldb/Utility/Status.h"
#include "lldb/Utility/Timeout.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 Status &GetError() const { return m_error; }

private:
  Status 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(llvm::StringRef path,
                                                      Status *error_ptr) {
  Log *log(lldb_private::GetLogIfAnyCategoriesSet(LIBLLDB_LOG_CONNECTION));
  if (log)
    log->Printf("%p ConnectionGenericFile::Connect (url = '%s')",
                static_cast<void *>(this), path.str().c_str());

  if (!path.consume_front("file://")) {
    if (error_ptr)
      error_ptr->SetErrorStringWithFormat("unsupported connection URL: '%s'",
                                          path.str().c_str());
    return eConnectionStatusError;
  }

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

  // 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(path);
  return eConnectionStatusSuccess;
}

lldb::ConnectionStatus ConnectionGenericFile::Disconnect(Status *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,
                                   const Timeout<std::micro> &timeout,
                                   lldb::ConnectionStatus &status,
                                   Status *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.
      DWORD milliseconds =
          timeout
              ? std::chrono::duration_cast<std::chrono::milliseconds>(*timeout)
                    .count()
              : INFINITE;
      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("%p ConnectionGenericFile::Read()  handle = %p, dst = %p, "
                "dst_len = %zu) => %zu, error = %s",
                this, m_file, dst, dst_len, 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,
                                    Status *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("%p ConnectionGenericFile::Write()  handle = %p, src = %p, "
                "src_len = %zu) => %zu, error = %s",
                this, m_file, src, src_len, 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;
}
