/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtNetwork module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qlocalsocket_p.h"

#include <private/qthread_p.h>
#include <qcoreapplication.h>
#include <qdebug.h>

QT_BEGIN_NAMESPACE

void QLocalSocketPrivate::init()
{
    Q_Q(QLocalSocket);
    memset(&overlapped, 0, sizeof(overlapped));
    overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
    dataReadNotifier = new QWinEventNotifier(overlapped.hEvent, q);
    q->connect(dataReadNotifier, SIGNAL(activated(HANDLE)), q, SLOT(_q_notified()));
}

void QLocalSocketPrivate::setErrorString(const QString &function)
{
    Q_Q(QLocalSocket);
    BOOL windowsError = GetLastError();
    QLocalSocket::LocalSocketState currentState = state;

    // If the connectToServer fails due to WaitNamedPipe() time-out, assume ConnectionError  
    if (state == QLocalSocket::ConnectingState && windowsError == ERROR_SEM_TIMEOUT)
        windowsError = ERROR_NO_DATA;

    switch (windowsError) {
    case ERROR_PIPE_NOT_CONNECTED:
    case ERROR_BROKEN_PIPE:
    case ERROR_NO_DATA:
        error = QLocalSocket::ConnectionError;
        errorString = QLocalSocket::tr("%1: Connection error").arg(function);
        state = QLocalSocket::UnconnectedState;
        break;
    case ERROR_FILE_NOT_FOUND:
        error = QLocalSocket::ServerNotFoundError;
        errorString = QLocalSocket::tr("%1: Invalid name").arg(function);
        state = QLocalSocket::UnconnectedState;
        break;
    default:
        error = QLocalSocket::UnknownSocketError;
        errorString = QLocalSocket::tr("%1: Unknown error %2").arg(function).arg(windowsError);
#if defined QLOCALSOCKET_DEBUG
        qWarning() << "QLocalSocket error not handled:" << errorString;
#endif
        state = QLocalSocket::UnconnectedState;
    }

    if (currentState != state) {
        q->emit stateChanged(state);
        if (state == QLocalSocket::UnconnectedState)
            q->emit disconnected();
    }
    emit q->error(error);
}

QLocalSocketPrivate::QLocalSocketPrivate() : QIODevicePrivate(),
       handle(INVALID_HANDLE_VALUE),
       pipeWriter(0),
       readBufferMaxSize(0),
       actualReadBufferSize(0),
       error(QLocalSocket::UnknownSocketError),
       readSequenceStarted(false),
       pendingReadyRead(false),
       pipeClosed(false),
       state(QLocalSocket::UnconnectedState)
{
}

QLocalSocketPrivate::~QLocalSocketPrivate()
{
    destroyPipeHandles();
    CloseHandle(overlapped.hEvent);
}

void QLocalSocketPrivate::destroyPipeHandles()
{
    if (handle != INVALID_HANDLE_VALUE) {
        DisconnectNamedPipe(handle);
        CloseHandle(handle);
    }
}

void QLocalSocket::connectToServer(const QString &name, OpenMode openMode)
{
    Q_D(QLocalSocket);
    if (state() == ConnectedState || state() == ConnectingState)
        return;

    d->error = QLocalSocket::UnknownSocketError;
    d->errorString = QString();
    d->state = ConnectingState;
    emit stateChanged(d->state);
    if (name.isEmpty()) {
        d->error = QLocalSocket::ServerNotFoundError;
        setErrorString(QLocalSocket::tr("%1: Invalid name").arg(QLatin1String("QLocalSocket::connectToServer")));
        d->state = UnconnectedState;
        emit error(d->error);
        emit stateChanged(d->state);
        return;
    }

    QString pipePath = QLatin1String("\\\\.\\pipe\\");
    if (name.startsWith(pipePath))
        d->fullServerName = name;
    else
        d->fullServerName = pipePath + name;
    // Try to open a named pipe
    HANDLE localSocket;
    forever {
        DWORD permissions = (openMode & QIODevice::ReadOnly) ? GENERIC_READ : 0;
        permissions |= (openMode & QIODevice::WriteOnly) ? GENERIC_WRITE : 0;
        localSocket = CreateFile((const wchar_t *)d->fullServerName.utf16(),   // pipe name
                                 permissions,
                                 0,              // no sharing
                                 NULL,           // default security attributes
                                 OPEN_EXISTING,  // opens existing pipe
                                 FILE_FLAG_OVERLAPPED,
                                 NULL);          // no template file

        if (localSocket != INVALID_HANDLE_VALUE)
            break;
        DWORD error = GetLastError();
        // It is really an error only if it is not ERROR_PIPE_BUSY
        if (ERROR_PIPE_BUSY != error) {
            break;
        }

        // All pipe instances are busy, so wait until connected or up to 5 seconds.
        if (!WaitNamedPipe((const wchar_t *)d->fullServerName.utf16(), 5000))
            break;
    }

    if (localSocket == INVALID_HANDLE_VALUE) {
        d->setErrorString(QLatin1String("QLocalSocket::connectToServer"));
        d->fullServerName = QString();
        return;
    }

    // we have a valid handle
    d->serverName = name;
    if (setSocketDescriptor((quintptr)localSocket, ConnectedState, openMode)) {
        d->handle = localSocket;
        emit connected();
    }
}

// This is reading from the buffer
qint64 QLocalSocket::readData(char *data, qint64 maxSize)
{
    Q_D(QLocalSocket);

    if (d->pipeClosed && d->actualReadBufferSize == 0)
        return -1;  // signal EOF

    qint64 readSoFar;
    // If startAsyncRead() read data, copy it to its destination.
    if (maxSize == 1 && d->actualReadBufferSize > 0) {
        *data = d->readBuffer.getChar();
        d->actualReadBufferSize--;
        readSoFar = 1;
    } else {
        qint64 bytesToRead = qMin(qint64(d->actualReadBufferSize), maxSize);
        readSoFar = 0;
        while (readSoFar < bytesToRead) {
            const char *ptr = d->readBuffer.readPointer();
            int bytesToReadFromThisBlock = qMin(bytesToRead - readSoFar,
                                                qint64(d->readBuffer.nextDataBlockSize()));
            memcpy(data + readSoFar, ptr, bytesToReadFromThisBlock);
            readSoFar += bytesToReadFromThisBlock;
            d->readBuffer.free(bytesToReadFromThisBlock);
            d->actualReadBufferSize -= bytesToReadFromThisBlock;
        }
    }

    if (d->pipeClosed) {
        if (d->actualReadBufferSize == 0)
            QTimer::singleShot(0, this, SLOT(_q_pipeClosed()));
    } else {
        if (!d->readSequenceStarted)
            d->startAsyncRead();
        d->checkReadyRead();
    }

    return readSoFar;
}

/*!
    \internal
    Schedules or cancels a readyRead() emission depending on actual data availability
 */
void QLocalSocketPrivate::checkReadyRead()
{
    if (actualReadBufferSize > 0) {
        if (!pendingReadyRead) {
            Q_Q(QLocalSocket);
            QTimer::singleShot(0, q, SLOT(_q_emitReadyRead()));
            pendingReadyRead = true;
        }
    } else {
        pendingReadyRead = false;
    }
}

/*!
    \internal
    Reads data from the socket into the readbuffer
 */
void QLocalSocketPrivate::startAsyncRead()
{
    do {
        DWORD bytesToRead = checkPipeState();
        if (pipeClosed)
            return;

        if (bytesToRead == 0) {
            // There are no bytes in the pipe but we need to
            // start the overlapped read with some buffer size.
            bytesToRead = initialReadBufferSize;
        }

        if (readBufferMaxSize && bytesToRead > (readBufferMaxSize - readBuffer.size())) {
            bytesToRead = readBufferMaxSize - readBuffer.size();
            if (bytesToRead == 0) {
                // Buffer is full. User must read data from the buffer
                // before we can read more from the pipe.
                return;
            }
        }

        char *ptr = readBuffer.reserve(bytesToRead);

        readSequenceStarted = true;
        if (ReadFile(handle, ptr, bytesToRead, NULL, &overlapped)) {
            completeAsyncRead();
        } else {
            switch (GetLastError()) {
                case ERROR_IO_PENDING:
                    // This is not an error. We're getting notified, when data arrives.
                    return;
                case ERROR_MORE_DATA:
                    // This is not an error. The synchronous read succeeded.
                    // We're connected to a message mode pipe and the message
                    // didn't fit into the pipe's system buffer.
                    completeAsyncRead();
                    break;
                case ERROR_PIPE_NOT_CONNECTED:
                    {
                        // It may happen, that the other side closes the connection directly
                        // after writing data. Then we must set the appropriate socket state.
                        pipeClosed = true;
                        Q_Q(QLocalSocket);
                        emit q->readChannelFinished();
                        return;
                    }
                default:
                    setErrorString(QLatin1String("QLocalSocketPrivate::startAsyncRead"));
                    return;
            }
        }
    } while (!readSequenceStarted);
}

/*!
    \internal
    Sets the correct size of the read buffer after a read operation.
    Returns false, if an error occurred or the connection dropped.
 */
bool QLocalSocketPrivate::completeAsyncRead()
{
    ResetEvent(overlapped.hEvent);
    readSequenceStarted = false;

    DWORD bytesRead;
    if (!GetOverlappedResult(handle, &overlapped, &bytesRead, TRUE)) {
        switch (GetLastError()) {
        case ERROR_MORE_DATA:
            // This is not an error. We're connected to a message mode
            // pipe and the message didn't fit into the pipe's system
            // buffer. We will read the remaining data in the next call.
            break;
        case ERROR_PIPE_NOT_CONNECTED:
            return false;
        default:
            setErrorString(QLatin1String("QLocalSocketPrivate::completeAsyncRead"));
            return false;
        }
    }

    actualReadBufferSize += bytesRead;
    readBuffer.truncate(actualReadBufferSize);
    return true;
}

qint64 QLocalSocket::writeData(const char *data, qint64 maxSize)
{
    Q_D(QLocalSocket);
    if (!d->pipeWriter) {
        d->pipeWriter = new QWindowsPipeWriter(d->handle, this);
        connect(d->pipeWriter, SIGNAL(canWrite()), this, SLOT(_q_canWrite()));
        connect(d->pipeWriter, SIGNAL(bytesWritten(qint64)), this, SIGNAL(bytesWritten(qint64)));
        d->pipeWriter->start();
    }
    return d->pipeWriter->write(data, maxSize);
}

void QLocalSocket::abort()
{
    close();
}

/*!
    \internal
    Returns the number of available bytes in the pipe.
    Sets QLocalSocketPrivate::pipeClosed to true if the connection is broken.
 */
DWORD QLocalSocketPrivate::checkPipeState()
{
    Q_Q(QLocalSocket);
    DWORD bytes;
    if (PeekNamedPipe(handle, NULL, 0, NULL, &bytes, NULL)) {
        return bytes;
    } else {
        if (!pipeClosed) {
            pipeClosed = true;
            emit q->readChannelFinished();
            if (actualReadBufferSize == 0)
                QTimer::singleShot(0, q, SLOT(_q_pipeClosed()));
        }
    }
    return 0;
}

void QLocalSocketPrivate::_q_pipeClosed()
{
    Q_Q(QLocalSocket);
    q->close();
}

qint64 QLocalSocket::bytesAvailable() const
{
    Q_D(const QLocalSocket);
    qint64 available = QIODevice::bytesAvailable();
    available += (qint64) d->actualReadBufferSize;
    return available;
}

qint64 QLocalSocket::bytesToWrite() const
{
    Q_D(const QLocalSocket);
    return (d->pipeWriter) ? d->pipeWriter->bytesToWrite() : 0;
}

bool QLocalSocket::canReadLine() const
{
    Q_D(const QLocalSocket);
    if (state() != ConnectedState)
        return false;
    return (QIODevice::canReadLine()
            || d->readBuffer.indexOf('\n', d->actualReadBufferSize) != -1);
}

void QLocalSocket::close()
{
    Q_D(QLocalSocket);
    if (state() == UnconnectedState)
        return;

    QIODevice::close();
    d->state = ClosingState;
    emit stateChanged(d->state);
    if (!d->pipeClosed)
        emit readChannelFinished();
    d->serverName = QString();
    d->fullServerName = QString();

    if (state() != UnconnectedState && bytesToWrite() > 0) {
        disconnectFromServer();
        return;
    }
    d->readSequenceStarted = false;
    d->pendingReadyRead = false;
    d->pipeClosed = false;
    d->destroyPipeHandles();
    d->handle = INVALID_HANDLE_VALUE;
    ResetEvent(d->overlapped.hEvent);
    d->state = UnconnectedState;
    emit stateChanged(d->state);
    emit disconnected();
    if (d->pipeWriter) {
        delete d->pipeWriter;
        d->pipeWriter = 0;
    }
}

bool QLocalSocket::flush()
{
    Q_D(QLocalSocket);
    if (d->pipeWriter)
        return d->pipeWriter->waitForWrite(0);
    return false;
}

void QLocalSocket::disconnectFromServer()
{
    Q_D(QLocalSocket);

    // Are we still connected?
    if (!isValid()) {
        // If we have unwritten data, the pipeWriter is still present.
        // It must be destroyed before close() to prevent an infinite loop.
        delete d->pipeWriter;
        d->pipeWriter = 0;
    }

    flush();
    if (d->pipeWriter && d->pipeWriter->bytesToWrite() != 0) {
        d->state = QLocalSocket::ClosingState;
        emit stateChanged(d->state);
    } else {
        close();
    }
}

QLocalSocket::LocalSocketError QLocalSocket::error() const
{
    Q_D(const QLocalSocket);
    return d->error;
}

bool QLocalSocket::setSocketDescriptor(quintptr socketDescriptor,
              LocalSocketState socketState, OpenMode openMode)
{
    Q_D(QLocalSocket);
    d->readBuffer.clear();
    d->actualReadBufferSize = 0;
    QIODevice::open(openMode);
    d->handle = (int*)socketDescriptor;
    d->state = socketState;
    emit stateChanged(d->state);
    if (d->state == ConnectedState && openMode.testFlag(QIODevice::ReadOnly)) {
        d->startAsyncRead();
        d->checkReadyRead();
    }
    return true;
}

void QLocalSocketPrivate::_q_canWrite()
{
    Q_Q(QLocalSocket);
    if (state == QLocalSocket::ClosingState)
        q->close();
}

void QLocalSocketPrivate::_q_notified()
{
    Q_Q(QLocalSocket);
    if (!completeAsyncRead()) {
        pipeClosed = true;
        emit q->readChannelFinished();
        if (actualReadBufferSize == 0)
            QTimer::singleShot(0, q, SLOT(_q_pipeClosed()));
        return;
    }
    startAsyncRead();
    pendingReadyRead = false;
    emit q->readyRead();
}

void QLocalSocketPrivate::_q_emitReadyRead()
{
    if (pendingReadyRead) {
        Q_Q(QLocalSocket);
        pendingReadyRead = false;
        emit q->readyRead();
    }
}

quintptr QLocalSocket::socketDescriptor() const
{
    Q_D(const QLocalSocket);
    return (quintptr)d->handle;
}

qint64 QLocalSocket::readBufferSize() const
{
    Q_D(const QLocalSocket);
    return d->readBufferMaxSize;
}

void QLocalSocket::setReadBufferSize(qint64 size)
{
    Q_D(QLocalSocket);
    d->readBufferMaxSize = size;
}

bool QLocalSocket::waitForConnected(int msecs)
{
    Q_UNUSED(msecs);
    return (state() == ConnectedState);
}

bool QLocalSocket::waitForDisconnected(int msecs)
{
    Q_D(QLocalSocket);
    if (state() == UnconnectedState)
        return false;
    if (!openMode().testFlag(QIODevice::ReadOnly)) {
        qWarning("QLocalSocket::waitForDisconnected isn't supported for write only pipes.");
        return false;
    }
    QIncrementalSleepTimer timer(msecs);
    forever {
        d->checkPipeState();
        if (d->pipeClosed)
            close();
        if (state() == UnconnectedState)
            return true;
        Sleep(timer.nextSleepTime());
        if (timer.hasTimedOut())
            break;
    }

    return false;
}

bool QLocalSocket::isValid() const
{
    Q_D(const QLocalSocket);
    if (d->handle == INVALID_HANDLE_VALUE)
        return false;

    return PeekNamedPipe(d->handle, NULL, 0, NULL, NULL, NULL);
}

bool QLocalSocket::waitForReadyRead(int msecs)
{
    Q_D(QLocalSocket);

    if (bytesAvailable() > 0)
        return true;

    if (d->state != QLocalSocket::ConnectedState)
        return false;

    // We already know that the pipe is gone, but did not enter the event loop yet.
    if (d->pipeClosed) {
        close();
        return false;
    }

    Q_ASSERT(d->readSequenceStarted);
    DWORD result = WaitForSingleObject(d->overlapped.hEvent, msecs == -1 ? INFINITE : msecs);
    switch (result) {
        case WAIT_OBJECT_0:
            d->_q_notified();
            // We just noticed that the pipe is gone.
            if (d->pipeClosed) {
                close();
                return false;
            }
            return true;
        case WAIT_TIMEOUT:
            return false;
    }

    qWarning("QLocalSocket::waitForReadyRead WaitForSingleObject failed with error code %d.", int(GetLastError()));
    return false;
}

bool QLocalSocket::waitForBytesWritten(int msecs)
{
    Q_D(const QLocalSocket);
    if (!d->pipeWriter)
        return false;

    // Wait for the pipe writer to acknowledge that it has
    // written. This will succeed if either the pipe writer has
    // already written the data, or if it manages to write data
    // within the given timeout.
    return d->pipeWriter->waitForWrite(msecs);
}

QT_END_NAMESPACE
