/*
 * ARM Android emulator adb backend
 *
 * Copyright (c) 2014 Linaro Limited
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Handle connections to the qemud:adb pipe from Android guests and route
 * traffic over this pipe to the host adb server connecting to the qemu
 * process on a tcp socket.
 */

#include <glib.h>
#include <stdio.h>
#include <unistd.h>

#include "qemu-common.h"
#include "qemu/config-file.h"
#include "qemu/main-loop.h"
#include "qapi/error.h"
#include "qemu/module.h"
#include "qemu/sockets.h"

#include "hw/misc/android_pipe.h"

//#define DEBUG_ADB

#ifdef DEBUG_ADB
#define DPRINTF(fmt, ...) \
do { fprintf(stderr, "adb: " fmt , ## __VA_ARGS__); } while (0)
#else
#define DPRINTF(fmt, ...) do {} while(0)
#endif

#define PIPE_QUEUE_LEN     16
#define HANDSHAKE_MAXLEN   128
#define ADB_BUFFER_LEN     4096

#define ADB_SERVER_PORT         5037

/* 'accept' request from adbd */
static const char _accept_req[] = "accept";
/* 'start' request from adbd */
static const char _start_req[]  = "start";
/* handshake reply to adbd */
static const char _ok_resp[]    = "ok";
static const char _ko_resp[]    = "ko";


static bool pipe_backend_initialized = false;

enum adb_connect_state {
    ADB_CONNECTION_STATE_UNCONNECTED = 0,
    ADB_CONNECTION_STATE_ACCEPT,
    ADB_CONNECTION_STATE_CONNECTED,
};

typedef struct {
    void*     hwpipe;
    enum adb_connect_state state;
    GIOChannel *chan;   /* I/O channel to adb server */
    unsigned flags;

    /* TODO: Make sure access to thes buffers is
     * synchronized through the io accessor
     * functions in QEMU or some other
     * mechanism. */
    char out_buffer[ADB_BUFFER_LEN];
    char *out_next;
    unsigned out_cnt;

} adb_pipe;

/*
 * This structure keeps track of the adb-server connection state (that
 * is HOST adb-server <-> QEMU connections). We only expect to see one
 * active connection at a time as data is multiplexed over the pipe.
 */

typedef struct {
    GIOChannel *listen_chan;    /* listener/connect socket */
    GIOChannel *chan;           /* actual comms socket */
    /* these cache the read/write state for when wakeon is called */
    gboolean    data_in;        /* have we seen data? */
    gboolean    data_out;       /* can we output data? */
    adb_pipe *adb_pipes[PIPE_QUEUE_LEN];
    adb_pipe *connected_pipe;
} adb_backend_state;

static adb_backend_state adb_state;

static void adb_reply(adb_pipe *apipe, const char *reply);


/****************************************************************************
 * ADB Server Interface
 */

static QemuOpts* adb_server_config(void) {
    QemuOpts *socket_opts;

    socket_opts = qemu_opts_create(&socket_optslist, NULL, 0,
                                   &error_abort);

    if (!qemu_opt_get(socket_opts, "host")) {
        qemu_opt_set(socket_opts, "host", "localhost");
    }

    if (!qemu_opt_get(socket_opts, "port")) {
        qemu_opt_set_number(socket_opts, "port", ADB_SERVER_PORT);
    }

    return socket_opts;
}

static void adb_server_notify(int adb_port) {
    Error *local_err = NULL;
    QemuOpts *socket_opts = adb_server_config();
    int sock = inet_connect_opts(socket_opts, &local_err, NULL, NULL);
    size_t len;
    gchar *message,*handshake;

    if (sock >= 0) {
        socket_set_nodelay(sock);
    }

    /* Failed to establish connection */
    if (sock < 0) {
        fprintf(stderr,"%s: Failed to establish connection to ADB server\n",
                __func__);
        return;
    }

    message = g_strdup_printf("host:emulator:%d", adb_port);
    handshake = g_strdup_printf("%04x%s", (int) strlen(message), message);
    len = strlen(handshake);

    if (send_all(sock, handshake, len) != len) {
        fprintf(stderr,"%s: error sending string:%s\n", __func__, handshake);
    }

    closesocket(sock);

    g_free(message);
    g_free(handshake);
    return;
}

/* TODO: Needs a common implementation with the likes of qemu-char.c */
static GIOChannel *io_channel_from_socket(int fd)
{
    GIOChannel *chan;

    if (fd == -1) {
        return NULL;
    }

#ifdef _WIN32
    chan = g_io_channel_win32_new_socket(fd);
#else
    chan = g_io_channel_unix_new(fd);
#endif

    g_io_channel_set_encoding(chan, NULL, NULL);
    g_io_channel_set_buffered(chan, FALSE);

    return chan;
}
static gboolean tcp_adb_accept(GIOChannel *channel, GIOCondition cond,
                               void *opaque);

/* Close a connection to the server.
**
** We need to ensure we clean-up any connection state and re-enable
** the watch on the listen socket so new connections can be created.
*/
static void tcp_adb_server_close(adb_backend_state *bs)
{
    g_assert(bs->chan);
    g_assert(bs->listen_chan);

    /* clean-up connected pipes */
    if (bs->connected_pipe) {
        DPRINTF("%s: closing connected pipe\n", __func__);
        android_pipe_close(bs->connected_pipe->hwpipe);
        bs->connected_pipe->chan = NULL;
        bs->connected_pipe = NULL;
    }

    /* wait for new connections */
    g_io_add_watch(bs->listen_chan, G_IO_IN, tcp_adb_accept, bs);

    /* finally close down this socket */
    g_io_channel_shutdown(bs->chan, FALSE, NULL);
    g_io_channel_unref(bs->chan);
    bs->chan = NULL;
}

/*
 * This handles state changes on the server socket. We don't directly
 * start receiving or sending data here but we do need to ensure that
 * the pipe guest wakes up so it can start reading data.
 *
 * This is a one-shot wake up - the watch needs re-adding whenever
 * things go quite so we'll wake up again when needed.
 */
static gboolean tcp_adb_server_data(GIOChannel *channel, GIOCondition cond,
                                    void *opaque)
{
    adb_backend_state *bs = (adb_backend_state *) opaque;
    if (cond & G_IO_IN) {
        bs->data_in = TRUE;
        if (bs->connected_pipe && bs->connected_pipe->flags & PIPE_WAKE_READ) {
            DPRINTF("%s: waking up pipe for incomming data\n", __func__);
            android_pipe_wake(bs->connected_pipe->hwpipe, PIPE_WAKE_READ);
        }
    }

    if (cond & G_IO_OUT) {
        bs->data_out = TRUE;
        if (bs->connected_pipe && bs->connected_pipe->flags & PIPE_WAKE_WRITE) {
            DPRINTF("%s: waking up pipe for now able to write\n", __func__);
            android_pipe_wake(bs->connected_pipe->hwpipe, PIPE_WAKE_WRITE);
        }
    }

    if ((cond & G_IO_ERR) ||
        (cond & G_IO_HUP)) {
        DPRINTF("%s: error %d - closing server connectio\n", __func__, cond);
        tcp_adb_server_close(bs);
    }

    /* Done, we must re-add watch next time we are waiting for data */
    return FALSE;
}

static gboolean tcp_adb_connect(adb_backend_state *bs, int fd)
{
    if (bs->chan) {
        DPRINTF("%s: existing connection %p, fail connect!\n",
                __func__, bs->chan);
        return FALSE;
    } else {
        DPRINTF("%s: in-coming connection on %d\n", __func__, fd);

        qemu_set_nonblock(fd);
        bs->chan = io_channel_from_socket(fd);
        g_io_add_watch(bs->chan, G_IO_IN|G_IO_ERR|G_IO_HUP, tcp_adb_server_data, bs);

        /* If we don't have a pipe to use for the tcp backend, then find one in
         * the accept state.  Note, this can happen, for example, if the previous
         * connected pipe was closed for some reason.  Also note that this becomes
         * sort of random which pipe we select, but there doesn't seem to be any
         * clearly defined semantics about the ordering here.  A proper fifo may
         * be a better data structure for this.
         */
        if (!bs->connected_pipe) {
            int i;
            for (i = 0; i < PIPE_QUEUE_LEN; i++) {
                if (bs->adb_pipes[i] &&
                    bs->adb_pipes[i]->state == ADB_CONNECTION_STATE_ACCEPT) {
                    bs->connected_pipe = bs->adb_pipes[i];
                }
            }
        }

        /* Tell the adbd that the adb server has conected and that we're ready to
         * receive the start package */
        if (bs->connected_pipe) {
            DPRINTF("Incoming TCP connection on already accepted pipe, connect\n");
            adb_pipe *apipe = bs->connected_pipe;
            apipe->chan = bs->chan;
            if (apipe->out_next) {
                fprintf(stderr, "Pending reply on non-connected pipe, error\n");
                abort();
            }
            adb_reply(apipe, _ok_resp);
        }

        return TRUE;
    }
}

/* Accept incoming connections. If the connect succeeds and we create
 * a connection we return FALSE to take the listen socket out of the
 * polling loop. We need to re-add the watch if/when the connection
 * dies so another connection can be created.
 */
static gboolean tcp_adb_accept(GIOChannel *channel, GIOCondition cond,
                               void *opaque)
{
    adb_backend_state *bs = opaque;
    struct sockaddr_in saddr;
    struct sockaddr *addr;
    socklen_t len;
    int fd;

    for(;;) {
        len = sizeof(saddr);
        addr = (struct sockaddr *)&saddr;
        fd = qemu_accept(g_io_channel_unix_get_fd(bs->listen_chan), addr, &len);
        if (fd < 0 && errno != EINTR) {
            DPRINTF("%s: failed to accept %d/%d\n", __func__, fd, errno);
            return FALSE;
        } else if (fd >= 0) {
            break;
        }
    }

    if (tcp_adb_connect(bs, fd)) {
        return FALSE;
    } else {
        return TRUE;
    }
}

static bool adb_server_listen_incoming(int port)
{
    adb_backend_state *bs = &adb_state;
    char *host_port;
    Error *err = NULL;
    int fd;

    host_port = g_strdup_printf("127.0.0.1:%d", port);
    fd = inet_listen(host_port, NULL, 0, SOCK_STREAM, 0, &err);
    if (fd < 0) {
        return false;
    }

    bs->listen_chan = io_channel_from_socket(fd);
    g_io_add_watch(bs->listen_chan, G_IO_IN, tcp_adb_accept, bs);
    return true;
}


/****************************************************************************
 * Android Pipe adbd Interface
 */

static void* adb_pipe_init(void *hwpipe,void *opaque, const char *args)
{
    adb_pipe *apipe;
    int i;

    DPRINTF("%s: hwpipe=%p\n", __FUNCTION__, hwpipe);
    apipe = g_malloc0(sizeof(adb_pipe));
    apipe->hwpipe = hwpipe;
    apipe->state = ADB_CONNECTION_STATE_UNCONNECTED;
    apipe->out_next = NULL;
    apipe->out_cnt = 0;
    apipe->flags = 0;

    for (i = 0; i < PIPE_QUEUE_LEN; i++) {
        if (adb_state.adb_pipes[i] == NULL) {
            adb_state.adb_pipes[i] = apipe;
            break;
        }
    }

    if (i == PIPE_QUEUE_LEN) {
        DPRINTF("Could not handle more open adb pipes\n");
        g_free(apipe);
        return NULL;
    }

    return apipe;
}

static void adb_pipe_close(void *opaque )
{
    adb_pipe *apipe = opaque;
    int i;

    DPRINTF("%s: hwpipe=%p\n", __FUNCTION__, apipe->hwpipe);
    if (adb_state.connected_pipe == apipe) {
        tcp_adb_server_close(&adb_state);
        adb_state.connected_pipe = NULL;
    }
    for (i = 0; i < PIPE_QUEUE_LEN; i++) {
        if (adb_state.adb_pipes[i] == apipe) {
            adb_state.adb_pipes[i] = NULL;
            break;
        }
    }

    g_free(apipe);
}

static int pipe_send_data(adb_pipe *apipe, char *data, unsigned len,
                          const AndroidPipeBuffer *buffers, int cnt)
{
    int avail = len;
    int chunk;

    while (cnt > 0 && avail > 0) {
        if (avail < buffers[0].size) {
            chunk = avail;
        } else {
            chunk = buffers[0].size;
        }

        memcpy(data, buffers[0].data, chunk);
        data += chunk;
        avail -= chunk;

        buffers++;
        cnt--;
    }

    return len - avail;
}

static bool match_request(const char *request, int len, const char *match)
{
    return len == strlen(match) && !strncmp(request, match, strlen(match));
}

static const char *handle_request(adb_pipe *apipe, const char *request, int len)
{
    adb_backend_state *bs = &adb_state;

    if (match_request(request, len, _accept_req)) {
        if (apipe->state != ADB_CONNECTION_STATE_UNCONNECTED) {
            return _ko_resp;
        }

        apipe->state = ADB_CONNECTION_STATE_ACCEPT;

        /* If we don't have any connected adb_pipe to the tcp backend yet,
         * elect ourselves.  If the tcp connection is ready as well, go ahead
         * and thell adbd to carry on.
         */
        if (!bs->connected_pipe) {
            bs->connected_pipe = apipe;
            if (bs->chan) {
                g_assert(!bs->connected_pipe->chan);
                bs->connected_pipe->chan = bs->chan;
                DPRINTF("Already have tcp connection, reply 'ok' to 'accept'\n");
                return _ok_resp;
            }
        }

        DPRINTF("no tcp connection, wait for it\n");
        return NULL; /* wait until adb server connects */
    } else if (match_request(request, len, _start_req)) {
        if (apipe->state != ADB_CONNECTION_STATE_ACCEPT) {
            DPRINTF("adbd requested 'start' when we are not ready, error\n");
            android_pipe_close(apipe->hwpipe);
            return NULL;
        }

        if (!bs->chan) {
            DPRINTF("adbd requested 'start' but tcp connection not yet connected, error\n");
            bs->connected_pipe->chan = NULL;
            android_pipe_close(apipe->hwpipe);
            return NULL;
        }

        apipe->state = ADB_CONNECTION_STATE_CONNECTED;
        return NULL; /* start proxying data */
    } else {
        /* unrecognized command */
        return _ko_resp;
    }
}

static void adb_reply(adb_pipe *apipe, const char *reply)
{
    strcpy(apipe->out_buffer, reply);
    apipe->out_cnt = strlen(reply);
    apipe->out_next = &apipe->out_buffer[0];
}

static int adb_pipe_proxy_send(adb_pipe *apipe, const AndroidPipeBuffer *buffers,
                               int cnt)
{
    gsize total_copied = 0;
    adb_backend_state *bs = &adb_state;

    g_assert(apipe->chan);

    DPRINTF("%s: %p/%d\n", __func__, buffers, cnt);
    do {
        GError *error = NULL;
        gchar *bptr = (gchar *) buffers[0].data;
        gsize bsize = buffers[0].size;
        gsize copied = 0;
        GIOStatus status = g_io_channel_write_chars(
            apipe->chan, bptr, bsize, &copied, &error);

        total_copied += copied;

        /* If we have already copied some data lets signal that and
         * let it come back to here.
         */
        if (total_copied > 0 &&
            ((status == G_IO_STATUS_EOF || status == G_IO_STATUS_AGAIN))) {
            bs->data_out = FALSE;
            return total_copied;
        }

        /* Can't write and more data.... */
        if (status == G_IO_STATUS_AGAIN) {
            DPRINTF("%s: out of data, setting up watch\n", __func__);
            g_io_add_watch(apipe->chan, G_IO_IN|G_IO_ERR|G_IO_HUP,
                           tcp_adb_server_data, bs);
            bs->data_out = FALSE;
            return PIPE_ERROR_AGAIN;
        }

        if (status == G_IO_STATUS_EOF) {
            bs->data_out = FALSE;
            tcp_adb_server_close(bs);
            return 0;
        }

        if (status != G_IO_STATUS_NORMAL) {
            DPRINTF("%s: went wrong (%d)\n", __func__, status);
            bs->data_out = FALSE;
            tcp_adb_server_close(bs);
            return PIPE_ERROR_IO;
        }

        if (copied < bsize) {
            g_assert(total_copied > 0);
            bs->data_out = FALSE;
            break;
        }

        buffers++;
    } while (--cnt);

    return total_copied;
}

static int adb_pipe_send(void *opaque, const AndroidPipeBuffer* buffers,
                             int cnt)
{
    adb_pipe *apipe = opaque;
    int  ret = 0;
    char request[HANDSHAKE_MAXLEN + 1];
    const char *reply;

    if (apipe->state != ADB_CONNECTION_STATE_CONNECTED) {
        if (apipe->out_next) {
            /* Existing reply in progress, not ready */
            DPRINTF("%s: unconnected pipe, reply in progress\n", __func__);
            return PIPE_ERROR_AGAIN;
        }
        ret = pipe_send_data(apipe, request, sizeof(request), buffers, cnt);
        reply = handle_request(apipe, request, ret);

        if (reply) {
            adb_reply(apipe, reply);
            android_pipe_wake(adb_state.connected_pipe->hwpipe, PIPE_WAKE_READ);
        }
    } else {
        ret = adb_pipe_proxy_send(apipe, buffers, cnt);
        if (ret == 0) {
            return PIPE_ERROR_AGAIN;
        }
    }

    return ret;
}

static int pipe_recv_data(adb_pipe *apipe, const char *data, unsigned len,
                          AndroidPipeBuffer *buffers, int cnt)
{
    int remain = len;
    int chunk;

    while (remain > 0 && cnt > 0) {
        if (remain > buffers[0].size) {
            chunk = buffers[0].size;
        } else {
            chunk = remain;
        }

        memcpy(buffers[0].data, data, chunk);
        data += chunk;
        remain -= chunk;

        buffers++;
        cnt--;
    }

    return len - remain;
}

static int adb_pipe_proxy_recv(adb_pipe *apipe, AndroidPipeBuffer *buffers,
                               int cnt)
{
    gsize total_copied = 0;
    adb_backend_state *bs = &adb_state;

    g_assert(apipe->chan);
    g_assert(bs->chan == apipe->chan);

    DPRINTF("%s: hwpipe=%p (buffers %p/%d)\n", __func__, apipe->hwpipe, buffers, cnt);
    do {
        GError *error = NULL;
        gchar *bptr = (gchar *) buffers[0].data;
        gsize bsize = buffers[0].size;
        gsize copied = 0;
        GIOStatus status = g_io_channel_read_chars(
            apipe->chan, bptr, bsize, &copied, &error);

        DPRINTF("%s: read %zd bytes into %p[%zd] -> %d\n", __func__,
                copied, bptr, bsize, status);

        total_copied += copied;

        /* If we have already copied some data lets signal that and
         * let it come back to here */
        if (total_copied > 0 &&
            ((status == G_IO_STATUS_EOF || status == G_IO_STATUS_AGAIN))) {
            bs->data_in = FALSE;
            return total_copied;
        }

        /* no data to read.... */
        if (status == G_IO_STATUS_AGAIN) {
            DPRINTF("%s: out of data, setting up watch\n", __func__);
            g_io_add_watch(apipe->chan, G_IO_IN|G_IO_ERR|G_IO_HUP,
                           tcp_adb_server_data, bs);
            bs->data_in = FALSE;
            return PIPE_ERROR_AGAIN;
        }

        if (status == G_IO_STATUS_EOF) {
            bs->data_in = FALSE;
            tcp_adb_server_close(bs);
            return 0;
        }

        if (status != G_IO_STATUS_NORMAL) {
            DPRINTF("%s: went wrong (%d)\n", __func__, status);
            bs->data_in = FALSE;
            tcp_adb_server_close(bs);
            return PIPE_ERROR_IO;
        }

        if (copied < bsize) {
            g_assert(total_copied > 0);
            bs->data_in = FALSE;
            break;
        }
        buffers++;
        cnt--;
    } while (cnt);

    return total_copied;
}

static int adb_pipe_recv(void *opaque, AndroidPipeBuffer *buffers,
                             int cnt)
{
    adb_pipe *apipe = opaque;
    adb_backend_state *bs = &adb_state;
    int ret = 0;

    if (apipe->state == ADB_CONNECTION_STATE_CONNECTED) {
        if (bs->data_in) {
            ret = adb_pipe_proxy_recv(apipe, buffers, cnt);
            return ret;
        } else {
            return PIPE_ERROR_AGAIN;
        }
    }

    assert(cnt > 0);

    if (!apipe->out_next) {
        return PIPE_ERROR_AGAIN;
    }

    assert((apipe->out_next - apipe->out_buffer)
             + apipe->out_cnt < ADB_BUFFER_LEN);

    ret = pipe_recv_data(apipe, apipe->out_next, apipe->out_cnt, buffers, cnt);
    apipe->out_cnt -= ret;
    if (ret == apipe->out_cnt) {
        apipe->out_next = NULL;
    } else {
        apipe->out_next += ret;
    }

    return ret;
}

static unsigned adb_pipe_poll(void *opaque)
{
    adb_pipe *apipe = opaque;
    adb_backend_state *bs = &adb_state;
    unsigned flags = 0;

    if (apipe->state != ADB_CONNECTION_STATE_CONNECTED) {
        if (apipe->out_next) {
            flags |= PIPE_POLL_IN;
        } else {
            flags |= PIPE_POLL_OUT;
        }
    } else {
        if (bs->data_in) {
            flags |= PIPE_POLL_IN;
        }
        /* We can always forward data to the socket as far as we know */
        flags |= PIPE_POLL_OUT;
    }

    return flags;
}

static void adb_pipe_wake_on(void *opaque, int flags)
{
    adb_pipe *apipe = opaque;
    DPRINTF("%s: setting flags 0x%x->0x%x\n", __func__, apipe->flags, flags);
    apipe->flags |= flags;

    if (flags & PIPE_WAKE_READ && adb_state.data_in) {
        android_pipe_wake(apipe->hwpipe, PIPE_WAKE_READ);
    }

    if (flags & PIPE_WAKE_WRITE && adb_state.data_out) {
        android_pipe_wake(apipe->hwpipe, PIPE_WAKE_WRITE);
    }
}

static const AndroidPipeFuncs adb_pipe_funcs = {
    adb_pipe_init,
    adb_pipe_close,
    adb_pipe_send,
    adb_pipe_recv,
    adb_pipe_poll,
    adb_pipe_wake_on,
};

/* Initialize and try to listen on the specified port;
 * return true on success or false if the port was in use.
 * Note that there's no way to undo this, so the board must
 * set up the console port first and the adb port second.
 */
bool adb_server_init(int port)
{
    if (!pipe_backend_initialized) {
        adb_state.chan = NULL;
        adb_state.listen_chan = NULL;
        adb_state.data_in = FALSE;
        adb_state.connected_pipe = NULL;

        android_pipe_add_type("qemud:adb", NULL, &adb_pipe_funcs);
        pipe_backend_initialized = true;
    }

    if (!adb_server_listen_incoming(port)) {
        return false;
    }
    adb_server_notify(port);
    return true;
}
