/*
 * 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.
 */

/* This file implements the 'tcp:' goldfish pipe type which allows
 * guest clients to directly connect to a TCP port through /dev/qemu_pipe.
 */

#include "android/sockets.h"
#include "android/utils/assert.h"
#include "android/utils/panic.h"
#include "android/utils/system.h"
#include "android/async-utils.h"
#include "android/opengles.h"
#include "android/looper.h"
#include "hw/android/goldfish/pipe.h"

/* Implement the OpenGL fast-pipe */

/* Set to 1 or 2 for debug traces */
// #define  DEBUG  1

#if DEBUG >= 1
#  define D(...)   printf(__VA_ARGS__), printf("\n")
#else
#  define D(...)   ((void)0)
#endif

#if DEBUG >= 2
#  define DD(...)                       printf(__VA_ARGS__), printf("\n")
#  define DDASSERT(cond)                _ANDROID_ASSERT(cond, "Assertion failure: ", #cond)
#  define DDASSERT_INT_OP(cond,val,op)  _ANDROID_ASSERT_INT_OP(cond,val,op)
#else
#  define DD(...)                       ((void)0)
#  define DDASSERT(cond)                ((void)0)
#  define DDASSERT_INT_OP(cond,val,op)  ((void)0)
#endif

#define DDASSERT_INT_LT(cond,val)  DDASSERT_INT_OP(cond,val,<)
#define DDASSERT_INT_LTE(cond,val)  DDASSERT_INT_OP(cond,val,<=)
#define DDASSERT_INT_GT(cond,val)  DDASSERT_INT_OP(cond,val,>)
#define DDASSERT_INT_GTE(cond,val)  DDASSERT_INT_OP(cond,val,>=)
#define DDASSERT_INT_EQ(cond,val)  DDASSERT_INT_OP(cond,val,==)
#define DDASSERT_INT_NEQ(cond,val)  DDASSERT_INT_OP(cond,val,!=)

enum {
    STATE_INIT,
    STATE_CONNECTING,
    STATE_CONNECTED,
    STATE_CLOSING_GUEST,
    STATE_CLOSING_SOCKET
};

typedef struct {
    void*           hwpipe;
    int             state;
    int             wakeWanted;
    LoopIo          io[1];
    AsyncConnector  connector[1];
} NetPipe;

static void
netPipe_free( NetPipe*  pipe )
{
    int  fd;

    /* Close the socket */
    fd = pipe->io->fd;
    loopIo_done(pipe->io);
    socket_close(fd);

    /* Release the pipe object */
    AFREE(pipe);
}


static void
netPipe_resetState( NetPipe* pipe )
{
    if ((pipe->wakeWanted & PIPE_WAKE_WRITE) != 0) {
        loopIo_wantWrite(pipe->io);
    } else {
        loopIo_dontWantWrite(pipe->io);
    }

   if (pipe->state == STATE_CONNECTED && (pipe->wakeWanted & PIPE_WAKE_READ) != 0) {
        loopIo_wantRead(pipe->io);
    } else {
        loopIo_dontWantRead(pipe->io);
    }
}


/* This function is only called when the socket is disconnected.
 * See netPipe_closeFromGuest() for the case when the guest requires
 * the disconnection. */
static void
netPipe_closeFromSocket( void* opaque )
{
    NetPipe*  pipe = opaque;

    D("%s", __FUNCTION__);

    /* If the guest already ordered the pipe to be closed, delete immediately */
    if (pipe->state == STATE_CLOSING_GUEST) {
        netPipe_free(pipe);
        return;
    }

    /* Force the closure of the QEMUD channel - if a guest is blocked
     * waiting for a wake signal, it will receive an error. */
    if (pipe->hwpipe != NULL) {
        goldfish_pipe_close(pipe->hwpipe);
        pipe->hwpipe = NULL;
    }

    pipe->state = STATE_CLOSING_SOCKET;
    netPipe_resetState(pipe);
}


/* This is the function that gets called each time there is an asynchronous
 * event on the network pipe.
 */
static void
netPipe_io_func( void* opaque, int fd, unsigned events )
{
    NetPipe*  pipe = opaque;
    int         wakeFlags = 0;

    /* Run the connector if we are in the CONNECTING state     */
    /* TODO: Add some sort of time-out, to deal with the case */
    /*        when the server is wedged.                      */
    if (pipe->state == STATE_CONNECTING) {
        AsyncStatus  status = asyncConnector_run(pipe->connector);
        if (status == ASYNC_NEED_MORE) {
            return;
        }
        else if (status == ASYNC_ERROR) {
            /* Could not connect, tell our client by closing the channel. */

            netPipe_closeFromSocket(pipe);
            return;
        }
        pipe->state = STATE_CONNECTED;
        netPipe_resetState(pipe);
        return;
    }

    /* Otherwise, accept incoming data */
    if ((events & LOOP_IO_READ) != 0) {
        if ((pipe->wakeWanted & PIPE_WAKE_READ) != 0) {
            wakeFlags |= PIPE_WAKE_READ;
        }
    }

    if ((events & LOOP_IO_WRITE) != 0) {
        if ((pipe->wakeWanted & PIPE_WAKE_WRITE) != 0) {
            wakeFlags |= PIPE_WAKE_WRITE;
        }
    }

    /* Send wake signal to the guest if needed */
    if (wakeFlags != 0) {
        goldfish_pipe_wake(pipe->hwpipe, wakeFlags);
        pipe->wakeWanted &= ~wakeFlags;
    }

    /* Reset state */
    netPipe_resetState(pipe);
}


void*
netPipe_initFromAddress( void* hwpipe, const SockAddress*  address, Looper* looper )
{
    NetPipe*     pipe;

    ANEW0(pipe);

    pipe->hwpipe = hwpipe;
    pipe->state  = STATE_INIT;

    {
        AsyncStatus  status;

        int  fd = socket_create( sock_address_get_family(address), SOCKET_STREAM );
        if (fd < 0) {
            D("%s: Could create socket from address family!", __FUNCTION__);
            netPipe_free(pipe);
            return NULL;
        }

        loopIo_init(pipe->io, looper, fd, netPipe_io_func, pipe);
        status = asyncConnector_init(pipe->connector, address, pipe->io);
        pipe->state = STATE_CONNECTING;

        if (status == ASYNC_ERROR) {
            D("%s: Could not connect to socket: %s",
              __FUNCTION__, errno_str);
            netPipe_free(pipe);
            return NULL;
        }
        if (status == ASYNC_COMPLETE) {
            pipe->state = STATE_CONNECTED;
            netPipe_resetState(pipe);
        }
    }

    return pipe;
}


/* Called when the guest wants to close the channel. This is different
 * from netPipe_closeFromSocket() which is called when the socket is
 * disconnected. */
static void
netPipe_closeFromGuest( void* opaque )
{
    NetPipe*  pipe = opaque;
    netPipe_free(pipe);
}

static int netPipeReadySend(NetPipe *pipe)
{
    if (pipe->state == STATE_CONNECTED)
        return 0;
    else if (pipe->state == STATE_CONNECTING)
        return PIPE_ERROR_AGAIN;
    else if (pipe->hwpipe == NULL)
        return PIPE_ERROR_INVAL;
    else
        return PIPE_ERROR_IO;
}

static int
netPipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
{
    NetPipe*  pipe = opaque;
    int       count = 0;
    int       ret   = 0;
    int       buffStart = 0;
    const GoldfishPipeBuffer* buff = buffers;
    const GoldfishPipeBuffer* buffEnd = buff + numBuffers;

    ret = netPipeReadySend(pipe);
    if (ret != 0)
        return ret;

    for (; buff < buffEnd; buff++)
        count += buff->size;

    buff = buffers;
    while (count > 0) {
        int  avail = buff->size - buffStart;
        int  len = socket_send(pipe->io->fd, buff->data + buffStart, avail);

        /* the write succeeded */
        if (len > 0) {
            buffStart += len;
            if (buffStart >= buff->size) {
                buff++;
                buffStart = 0;
            }
            count -= len;
            ret   += len;
            continue;
        }

        /* we reached the end of stream? */
        if (len == 0) {
            if (ret == 0)
                ret = PIPE_ERROR_IO;
            break;
        }

        /* if we already wrote some stuff, simply return */
        if (ret > 0) {
            break;
        }

        /* need to return an appropriate error code */
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            ret = PIPE_ERROR_AGAIN;
        } else {
            ret = PIPE_ERROR_IO;
        }
        break;
    }

    return ret;
}

static int
netPipe_recvBuffers( void* opaque, GoldfishPipeBuffer*  buffers, int  numBuffers )
{
    NetPipe*  pipe = opaque;
    int       count = 0;
    int       ret   = 0;
    int       buffStart = 0;
    GoldfishPipeBuffer* buff = buffers;
    GoldfishPipeBuffer* buffEnd = buff + numBuffers;

    for (; buff < buffEnd; buff++)
        count += buff->size;

    buff = buffers;
    while (count > 0) {
        int  avail = buff->size - buffStart;
        int  len = socket_recv(pipe->io->fd, buff->data + buffStart, avail);

        /* the read succeeded */
        if (len > 0) {
            buffStart += len;
            if (buffStart >= buff->size) {
                buff++;
                buffStart = 0;
            }
            count -= len;
            ret   += len;
            continue;
        }

        /* we reached the end of stream? */
        if (len == 0) {
            if (ret == 0)
                ret = PIPE_ERROR_IO;
            break;
        }

        /* if we already read some stuff, simply return */
        if (ret > 0) {
            break;
        }

        /* need to return an appropriate error code */
        if (errno == EAGAIN || errno == EWOULDBLOCK) {
            ret = PIPE_ERROR_AGAIN;
        } else {
            ret = PIPE_ERROR_IO;
        }
        break;
    }
    return ret;
}

static unsigned
netPipe_poll( void* opaque )
{
    NetPipe*  pipe = opaque;
    unsigned  mask = loopIo_poll(pipe->io);
    unsigned  ret  = 0;

    if (mask & LOOP_IO_READ)
        ret |= PIPE_POLL_IN;
    if (mask & LOOP_IO_WRITE)
        ret |= PIPE_POLL_OUT;

    return ret;
}

static void
netPipe_wakeOn( void* opaque, int flags )
{
    NetPipe*  pipe = opaque;

    DD("%s: flags=%d", __FUNCTION__, flags);

    pipe->wakeWanted |= flags;
    netPipe_resetState(pipe);
}


void*
netPipe_initTcp( void* hwpipe, void* _looper, const char* args )
{
    /* Build SockAddress from arguments. Acceptable formats are:
     *   <port>
     */
    SockAddress  address;
    uint16_t     port;
    void*        ret;

    if (args == NULL) {
        D("%s: Missing address!", __FUNCTION__);
        return NULL;
    }
    D("%s: Port is '%s'", __FUNCTION__, args);

    /* Now, look at the port number */
    {
        char* end;
        long  val = strtol(args, &end, 10);
        if (end == NULL || *end != '\0' || val <= 0 || val > 65535) {
            D("%s: Invalid port number: '%s'", __FUNCTION__, args);
        }
        port = (uint16_t)val;
    }
    sock_address_init_inet(&address, SOCK_ADDRESS_INET_LOOPBACK, port);

    ret = netPipe_initFromAddress(hwpipe, &address, _looper);

    sock_address_done(&address);
    return ret;
}

#ifndef _WIN32
void*
netPipe_initUnix( void* hwpipe, void* _looper, const char* args )
{
    /* Build SockAddress from arguments. Acceptable formats are:
     *
     *   <path>
     */
    SockAddress  address;
    void*        ret;

    if (args == NULL || args[0] == '\0') {
        D("%s: Missing address!", __FUNCTION__);
        return NULL;
    }
    D("%s: Address is '%s'", __FUNCTION__, args);

    sock_address_init_unix(&address, args);

    ret = netPipe_initFromAddress(hwpipe, &address, _looper);

    sock_address_done(&address);
    return ret;
}
#endif

/**********************************************************************
 **********************************************************************
 *****
 *****  N E T W O R K   P I P E   M E S S A G E S
 *****
 *****/

static const GoldfishPipeFuncs  netPipeTcp_funcs = {
    netPipe_initTcp,
    netPipe_closeFromGuest,
    netPipe_sendBuffers,
    netPipe_recvBuffers,
    netPipe_poll,
    netPipe_wakeOn,
    NULL,  /* we can't save these */
    NULL,  /* we can't load these */
};

#ifndef _WIN32
static const GoldfishPipeFuncs  netPipeUnix_funcs = {
    netPipe_initUnix,
    netPipe_closeFromGuest,
    netPipe_sendBuffers,
    netPipe_recvBuffers,
    netPipe_poll,
    netPipe_wakeOn,
    NULL,  /* we can't save these */
    NULL,  /* we can't load these */
};
#endif

/* This is set to 1 in android_init_opengles() below, and tested
 * by openglesPipe_init() to refuse a pipe connection if the function
 * was never called.
 */
static int  _opengles_init;

static void*
openglesPipe_init( void* hwpipe, void* _looper, const char* args )
{
    NetPipe *pipe;

    if (!_opengles_init) {
        /* This should never happen, unless there is a bug in the
         * emulator's initialization, or the system image. */
        D("Trying to open the OpenGLES pipe without GPU emulation!");
        return NULL;
    }

    char server_addr[PATH_MAX];
    android_gles_server_path(server_addr, sizeof(server_addr));
#ifndef _WIN32
    if (android_gles_fast_pipes) {
        pipe = (NetPipe *)netPipe_initUnix(hwpipe, _looper, server_addr);
        D("Creating Unix OpenGLES pipe for GPU emulation: %s", server_addr);
    } else {
#else /* _WIN32 */
    {
#endif
        /* Connect through TCP as a fallback */
        pipe = (NetPipe *)netPipe_initTcp(hwpipe, _looper, server_addr);
        D("Creating TCP OpenGLES pipe for GPU emulation!");
    }
    if (pipe != NULL) {
        // Disable TCP nagle algorithm to improve throughput of small packets
        socket_set_nodelay(pipe->io->fd);

    // On Win32, adjust buffer sizes
#ifdef _WIN32
        {
            int sndbuf = 128 * 1024;
            int len = sizeof(sndbuf);
            if (setsockopt(pipe->io->fd, SOL_SOCKET, SO_SNDBUF,
                        (char*)&sndbuf, len) == SOCKET_ERROR) {
                D("Failed to set SO_SNDBUF to %d error=0x%x\n",
                sndbuf, WSAGetLastError());
            }
        }
#endif /* _WIN32 */
    }

    return pipe;
}

static const GoldfishPipeFuncs  openglesPipe_funcs = {
    openglesPipe_init,
    netPipe_closeFromGuest,
    netPipe_sendBuffers,
    netPipe_recvBuffers,
    netPipe_poll,
    netPipe_wakeOn,
    NULL,  /* we can't save these */
    NULL,  /* we can't load these */
};

void
android_net_pipes_init(void)
{
    Looper*  looper = looper_newCore();

    goldfish_pipe_add_type( "tcp", looper, &netPipeTcp_funcs );
#ifndef _WIN32
    goldfish_pipe_add_type( "unix", looper, &netPipeUnix_funcs );
#endif
    goldfish_pipe_add_type( "opengles", looper, &openglesPipe_funcs );
}

int
android_init_opengles_pipes(void)
{
    /* TODO: Check that we can load and initialize the host emulation
     *        libraries, and return -1 in case of error.
     */
    _opengles_init = 1;
    return 0;
}
