//===-- 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/Core/Error.h"
#include "lldb/Core/Log.h"
#include "lldb/Host/TimeValue.h"
#include "lldb/Host/windows/ConnectionGenericFileWindows.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;
}
