/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "Win32PipeStream.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <windows.h>

#ifndef _WIN32
#error ONLY BUILD THIS SOURCE FILE FOR WINDOWS!
#endif

/* The official documentation states that the name of a given named
 * pipe cannot be more than 256 characters long.
 */
#define NAMED_PIPE_MAX 256

Win32PipeStream::Win32PipeStream(size_t bufSize) :
    SocketStream(bufSize),
    m_pipe(INVALID_HANDLE_VALUE)
{
}

Win32PipeStream::Win32PipeStream(HANDLE pipe, size_t bufSize) :
    SocketStream(-1, bufSize),
    m_pipe(pipe)
{
}

Win32PipeStream::~Win32PipeStream()
{
    if (m_pipe != INVALID_HANDLE_VALUE) {
        CloseHandle(m_pipe);
        m_pipe = INVALID_HANDLE_VALUE;
    }
}

/* Initialize the pipe name corresponding to a given port
 */
static void
make_pipe_name(char *path, size_t  pathlen, int port_number)
{
    snprintf(path, pathlen, "\\\\.\\pipe\\qemu-gles-%d", port_number);
}


/* Technical note: Named pipes work differently from BSD Sockets.
 * One does not create/bind a pipe, and collect a new handle each
 * time a client connects with accept().
 *
 * Instead, the server creates a new pipe instance each time it wants
 * to get a new client connection, then calls ConnectNamedPipe() to
 * wait for a connection.
 *
 * So listen() is a no-op, and accept() really creates the pipe handle.
 *
 * Also, connect() must create a pipe handle with CreateFile() and
 * wait for a server instance with WaitNamedPipe()
 */
int Win32PipeStream::listen(char addrstr[MAX_ADDRSTR_LEN])
{
    m_port = GetCurrentProcessId();
    make_pipe_name(addrstr, MAX_ADDRSTR_LEN, m_port);
    return 0;
}

SocketStream * Win32PipeStream::accept()
{
    char path[NAMED_PIPE_MAX+1];
    SocketStream*  clientStream;
    HANDLE pipe;

    make_pipe_name(path, sizeof(path), m_port);

    pipe = ::CreateNamedPipe(
                path,                // pipe name
                PIPE_ACCESS_DUPLEX,  // read-write access
                PIPE_TYPE_BYTE |     // byte-oriented writes
                PIPE_READMODE_BYTE | // byte-oriented reads
                PIPE_WAIT,           // blocking operations
                PIPE_UNLIMITED_INSTANCES, // no limit on clients
                4096,                // input buffer size
                4096,                // output buffer size
                0,                   // client time-out
                NULL);               // default security attributes

    if (pipe == INVALID_HANDLE_VALUE) {
        ERR("%s: CreateNamedPipe failed %d\n", __FUNCTION__, (int)GetLastError());
        return NULL;
    }

    // Stupid Win32 API design: If a client is already connected, then
    // ConnectNamedPipe will return 0, and GetLastError() will return
    // ERROR_PIPE_CONNECTED. This is not an error! It just means that the
    // function didn't have to wait.
    //
    if (::ConnectNamedPipe(pipe, NULL) == 0 && GetLastError() != ERROR_PIPE_CONNECTED) {
        ERR("%s: ConnectNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
        CloseHandle(pipe);
        return NULL;
    }

    clientStream = new Win32PipeStream(pipe, m_bufsize);
    return clientStream;
}

int Win32PipeStream::connect(const char* addr)
{
    HANDLE pipe;
    int    tries = 10;

    /* We're going to loop in order to wait for the pipe server to
     * be setup properly.
     */
    for (; tries > 0; tries--) {
        pipe = ::CreateFile(
                    addr,                          // pipe name
                    GENERIC_READ | GENERIC_WRITE,  // read & write
                    0,                             // no sharing
                    NULL,                          // default security attrs
                    OPEN_EXISTING,                 // open existing pipe
                    0,                             // default attributes
                    NULL);                         // no template file

        /* If we have a valid pipe handle, break from the loop */
        if (pipe != INVALID_HANDLE_VALUE) {
            break;
        }

        /* We can get here if the pipe is busy, i.e. if the server hasn't
         * create a new pipe instance to service our request. In which case
         * GetLastError() will return ERROR_PIPE_BUSY.
         *
         * If so, then use WaitNamedPipe() to wait for a decent time
         * to try again.
         */
        if (GetLastError() != ERROR_PIPE_BUSY) {
            /* Not ERROR_PIPE_BUSY */
            ERR("%s: CreateFile failed: %d\n", __FUNCTION__, (int)GetLastError());
            errno = EINVAL;
            return -1;
        }

        /* Wait for 5 seconds */
        if ( !WaitNamedPipe(addr, 5000) ) {
            ERR("%s: WaitNamedPipe failed: %d\n", __FUNCTION__, (int)GetLastError());
            errno = EINVAL;
            return -1;
        }
    }

    m_pipe = pipe;
    return 0;
}

/* Special buffer methods, since we can't use socket functions here */

int Win32PipeStream::commitBuffer(size_t size)
{
    if (m_pipe == INVALID_HANDLE_VALUE)
        return -1;

    size_t res = size;
    int retval = 0;

    while (res > 0) {
        DWORD  written;
        if (! ::WriteFile(m_pipe, (const char *)m_buf + (size - res), res, &written, NULL)) {
            retval =  -1;
            ERR("%s: failed: %d\n", __FUNCTION__, (int)GetLastError());
            break;
        }
        res -= written;
    }
    return retval;
}

const unsigned char *Win32PipeStream::readFully(void *buf, size_t len)
{
    const unsigned char* ret = NULL;

    if (m_pipe == INVALID_HANDLE_VALUE)
        return NULL;

    if (!buf) {
        return NULL;  // do not allow NULL buf in that implementation
    }

    size_t res = len;
    while (res > 0) {
        DWORD  readcount = 0;
        if (! ::ReadFile(m_pipe, (char *)buf + (len - res), res, &readcount, NULL) || readcount == 0) {
            errno = (int)GetLastError();
            return NULL;
        }
        res -= readcount;
    }
    return (const unsigned char *)buf;
}

const unsigned char *Win32PipeStream::read( void *buf, size_t *inout_len)
{
    size_t len = *inout_len;
    DWORD  readcount;

    if (m_pipe == INVALID_HANDLE_VALUE)
        return NULL;

    if (!buf) {
        return NULL;  // do not allow NULL buf in that implementation
    }

    if (!::ReadFile(m_pipe, (char *)buf, len, &readcount, NULL)) {
        errno = (int)GetLastError();
        return NULL;
    }

    *inout_len = (size_t)readcount;
    return (const unsigned char *)buf;
}
