/*
 * 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 "qemu-common.h"
#include "android/sockets.h"
#include "android/iolooper.h"
#include "android/async-utils.h"
#include "android/utils/debug.h"
#include "android/utils/list.h"
#include "android/utils/misc.h"
#include "android/adb-server.h"

#define  E(...)    derror(__VA_ARGS__)
#define  W(...)    dwarning(__VA_ARGS__)
#define  D(...)    VERBOSE_PRINT(adbserver,__VA_ARGS__)
#define  D_ACTIVE  VERBOSE_CHECK(adbserver)
#define  QB(b, s)  quote_bytes((const char*)b, (s < 32) ? s : 32)

typedef struct AdbServer    AdbServer;
typedef struct AdbHost      AdbHost;
typedef struct AdbGuest     AdbGuest;

/* ADB guest connection descriptor. */
struct AdbGuest {
    /* Entry in the list of pending or connected ADB guests.
     * NOTE: This must be the first entry in the descriptor! */
    ACList              list_entry;
    /* Opaque pointer associated with the guest. */
    void*               opaque;
    /* ADB server for this guest. */
    AdbServer*          adb_srv;
    /* ADB host connected with this ADB guest. */
    AdbHost*            adb_host;
    /* Callback routines for the ADB guest. */
    AdbGuestRoutines*   callbacks;
    /* ADB guest connection status. If 0 indicates that ADB guest is not yet
     * ready to receive data from the host. */
    int                 is_connected;
};

/* ADB host connection descriptor. */
struct AdbHost {
    /* Entry in the list of pending or connected ADB hosts.
     * NOTE: This must be the first entry in the descriptor! */
    ACList      list_entry;
    /* ADB server for this host. */
    AdbServer*  adb_srv;
    /* ADB socket connected with the host. */
    int         host_so;
    /* I/O port for asynchronous I/O on the host socket. */
    LoopIo      io[1];
    /* ADB guest connected with this ADB host. */
    AdbGuest*   adb_guest;
    /* Pending data to send to the guest when it is fully connected. */
    uint8_t*    pending_data;
    /* Size of the pending data buffer. */
    int         pending_data_size;
    /* Contains data that are pending to be sent to the host. */
    uint8_t*    pending_send_buffer;
    /* Number of bytes that are pending to be sent to the host. */
    int         pending_send_data_size;
    /* Size of the pending_send_buffer */
    int         pending_send_buffer_size;
};

/* ADB server descriptor. */
struct AdbServer {
    /* ADB socket address. */
    SockAddress socket_address;
    /* Looper for async I/O on ADB server socket. */
    Looper*     looper;
    /* I/O port for asynchronous I/O on ADB server socket. */
    LoopIo      io[1];
    /* ADB port. */
    int         port;
    /* Server socket. */
    int         so;
    /* List of connected ADB hosts. */
    ACList      adb_hosts;
    /* List of connected ADB guests. */
    ACList      adb_guests;
    /* List of ADB hosts pending connection with ADB guest. */
    ACList      pending_hosts;
    /* List of ADB guests pending connection with ADB host. */
    ACList      pending_guests;
};

/* One and only one ADB server instance. */
static AdbServer    _adb_server;
/* ADB server initialization flag. */
static int          _adb_server_initialized = 0;

/********************************************************************************
 *                             ADB host API
 *******************************************************************************/

/* Creates and initializes a new AdbHost instance. */
static AdbHost*
_adb_host_new(AdbServer* adb_srv)
{
    AdbHost* adb_host;

    ANEW0(adb_host);
    alist_init(&adb_host->list_entry);
    adb_host->adb_srv = adb_srv;
    adb_host->host_so = -1;

    return adb_host;
}

/* Frees AdbHost instance created with _adb_host_new routine. */
static void
_adb_host_free(AdbHost* adb_host)
{
    if (adb_host != NULL) {
        /* At this point it must not be listed anywhere. */
        assert(alist_is_empty(&adb_host->list_entry));

        /* Close the host socket. */
        if (adb_host->host_so >= 0) {
            loopIo_done(adb_host->io);
            socket_close(adb_host->host_so);
        }

        /* Free pending data buffers. */
        if (adb_host->pending_data != NULL) {
            free(adb_host->pending_data);
        }
        if (adb_host->pending_send_buffer != NULL) {
            free(adb_host->pending_send_buffer);
        }

        AFREE(adb_host);
    }
}

static void
_adb_host_append_message(AdbHost* adb_host, const void* msg, int msglen)
{
    printf("Append %d bytes to ADB host buffer.\n", msglen);

    /* Make sure that buffer can contain the appending data. */
    if (adb_host->pending_send_buffer == NULL) {
        adb_host->pending_send_buffer = (uint8_t*)malloc(msglen);
        adb_host->pending_send_buffer_size = msglen;
    } else if ((adb_host->pending_send_data_size + msglen) >
               adb_host->pending_send_buffer_size) {
        adb_host->pending_send_buffer =
            (uint8_t*)realloc(adb_host->pending_send_buffer,
                              adb_host->pending_send_data_size + msglen);
        adb_host->pending_send_buffer_size =
            adb_host->pending_send_data_size + msglen;
    }

    if (adb_host->pending_send_buffer == NULL) {
        D("Unable to allocate %d bytes for pending ADB host data.",
          adb_host->pending_send_data_size + msglen);
        adb_host->pending_send_buffer_size = adb_host->pending_send_data_size = 0;
        loopIo_dontWantWrite(adb_host->io);
        return;
    }

    memcpy(adb_host->pending_send_buffer + adb_host->pending_send_data_size,
           msg, msglen);
    loopIo_wantWrite(adb_host->io);
}

/* Connects ADB host with ADB guest. */
static void
_adb_connect(AdbHost* adb_host, AdbGuest* adb_guest)
{
    D("Connecting ADB host %p(so=%d) with ADB guest %p(o=%p)",
      adb_host, adb_host->host_so, adb_guest, adb_guest->opaque);

    adb_guest->adb_host = adb_host;
    adb_host->adb_guest = adb_guest;
    adb_guest->callbacks->on_connected(adb_guest->opaque, adb_guest);
}

/* Callback invoked when ADB host socket gets disconnected. */
static void
_on_adb_host_disconnected(AdbHost* adb_host)
{
    AdbGuest* const adb_guest = adb_host->adb_guest;

    /* Notify the ADB guest that the host got disconnected. */
    if (adb_guest != NULL) {
        D("Disconnecting ADB host %p(so=%d) from ADB guest %p(o=%p)",
          adb_host, adb_host->host_so, adb_guest, adb_guest->opaque);
        adb_host->adb_guest = NULL;
        adb_guest->callbacks->on_disconnect(adb_guest->opaque, adb_guest);
        adb_guest->adb_host = NULL;
    } else {
        D("Disconnecting ADB host %p(so=%d)", adb_host, adb_host->host_so);
    }

    /* Destroy the host. */
    alist_remove(&adb_host->list_entry);
    _adb_host_free(adb_host);

    /* Remove the guest from the list. */
    if (adb_guest != NULL) {
        alist_remove(&adb_guest->list_entry);
    }
}

/* Read I/O callback on ADB host socket. */
static void
_on_adb_host_read(AdbHost* adb_host)
{
    char buff[4096];

    /* Read data from the socket. */
    const int size = socket_recv(adb_host->host_so, buff, sizeof(buff));
    if (size < 0) {
        D("Error while reading from ADB host %p(so=%d). Error: %s",
          adb_host, adb_host->host_so, strerror(errno));
    } else if (size == 0) {
        /* This is a "disconnect" condition. */
        _on_adb_host_disconnected(adb_host);
    } else {
        D("%s %d bytes received from ADB host %p(so=%d): %s",
           adb_host->adb_guest ? "Transfer" : "Pend", size, adb_host,
           adb_host->host_so, QB(buff, size));

        /* Lets see if there is an ADB guest associated with this host, and it
         * is ready to receive host data. */
        AdbGuest* const adb_guest = adb_host->adb_guest;
        if (adb_guest != NULL && adb_guest->is_connected) {
            /* Channel the data through... */
            adb_guest->callbacks->on_read(adb_guest->opaque, adb_guest, buff, size);
        } else {
            /* Pend the data for the upcoming guest connection. */
            if (adb_host->pending_data == NULL) {
                adb_host->pending_data = malloc(size);
            } else {
                adb_host->pending_data = realloc(adb_host->pending_data,
                                                 adb_host->pending_data_size + size);
            }
            if (adb_host->pending_data != NULL) {
                memcpy(adb_host->pending_data + adb_host->pending_data_size,
                       buff, size);
                adb_host->pending_data_size += size;
            } else {
                D("Unable to (re)allocate %d bytes for pending ADB host data",
                  adb_host->pending_data_size + size);
            }
        }
    }
}

/* Write I/O callback on ADB host socket. */
static void
_on_adb_host_write(AdbHost* adb_host)
{
    while (adb_host->pending_send_data_size && adb_host->pending_send_buffer != NULL) {
        const int sent = socket_send(adb_host->host_so,
                                     adb_host->pending_send_buffer,
                                     adb_host->pending_send_data_size);
        if (sent < 0) {
            if (errno == EWOULDBLOCK) {
                /* Try again later. */
                return;
            } else {
                D("Unable to send pending data to the ADB host: %s",
                   strerror(errno));
                free(adb_host->pending_send_buffer);
                adb_host->pending_send_buffer = NULL;
                adb_host->pending_send_buffer_size = 0;
                adb_host->pending_send_data_size = 0;
                break;
            }
        } else if (sent == 0) {
            /* Disconnect condition. */
            free(adb_host->pending_send_buffer);
            adb_host->pending_send_buffer = NULL;
            adb_host->pending_send_buffer_size = 0;
            adb_host->pending_send_data_size = 0;
            _on_adb_host_disconnected(adb_host);
            break;
        } else if (sent == adb_host->pending_send_data_size) {
            free(adb_host->pending_send_buffer);
            adb_host->pending_send_buffer = NULL;
            adb_host->pending_send_buffer_size = 0;
            adb_host->pending_send_data_size = 0;
        } else {
            adb_host->pending_send_data_size -= sent;
            memmove(adb_host->pending_send_buffer,
                    adb_host->pending_send_buffer + sent,
                    adb_host->pending_send_data_size);
            return;
        }
    }

    loopIo_dontWantWrite(adb_host->io);
}

/* I/O callback on ADB host socket. */
static void
_on_adb_host_io(void* opaque, int fd, unsigned events)
{
    AdbHost* const adb_host = (AdbHost*)opaque;
    assert(fd == adb_host->host_so);

    /* Dispatch I/O to read / write handlers. */
    if ((events & LOOP_IO_READ) != 0) {
        _on_adb_host_read(adb_host);
    }
    if ((events & LOOP_IO_WRITE) != 0) {
        _on_adb_host_write(adb_host);
    }
}

/********************************************************************************
 *                            ADB guest API
 *******************************************************************************/

/* Creates and initializes a new AdbGuest instance. */
static AdbGuest*
_adb_guest_new(AdbServer* adb_srv)
{
    AdbGuest* adb_guest;

    ANEW0(adb_guest);
    alist_init(&adb_guest->list_entry);
    adb_guest->adb_srv = adb_srv;

    return adb_guest;
}

/* Frees AdbGuest instance created with _adb_guest_new routine. */
static void
_adb_guest_free(AdbGuest* adb_guest)
{
    if (adb_guest != NULL) {
        /* At this poin the guest must not be in any of the lists. */
        assert(alist_is_empty(&adb_guest->list_entry));
        AFREE(adb_guest);
    }
}

/********************************************************************************
 *                            ADB server internals
 *******************************************************************************/

/* I/O callback on ADB server socket. */
static void
_on_server_socket_io(void* opaque, int fd, unsigned events)
{
    AdbHost* adb_host;
    AdbGuest* adb_guest;
    AdbServer* adb_srv = (AdbServer*)opaque;
    assert(adb_srv->so == fd);

    /* Since this is a server socket, we only expect a connection I/O here. */
    if ((events & LOOP_IO_READ) == 0) {
        D("Unexpected write I/O on ADB server socket");
        return;
    }

    /* Create AdbHost instance for the new host connection. */
    adb_host = _adb_host_new(adb_srv);

    /* Accept the connection. */
    adb_host->host_so = socket_accept(fd, &adb_srv->socket_address);
    if (adb_host->host_so < 0) {
        D("Unable to accept ADB connection: %s", strerror(errno));
        _adb_host_free(adb_host);
        return;
    }

    /* Prepare for I/O on the host connection socket. */
    loopIo_init(adb_host->io, adb_srv->looper, adb_host->host_so,
                _on_adb_host_io, adb_host);

    /* Lets see if there is an ADB guest waiting for a host connection. */
    adb_guest = (AdbGuest*)alist_remove_head(&adb_srv->pending_guests);
    if (adb_guest != NULL) {
        /* Tie up ADB host with the ADB guest. */
        alist_insert_tail(&adb_srv->adb_guests, &adb_guest->list_entry);
        alist_insert_tail(&adb_srv->adb_hosts, &adb_host->list_entry);
        _adb_connect(adb_host, adb_guest);
    } else {
        /* Pend this connection. */
        D("Pend ADB host %p(so=%d)", adb_host, adb_host->host_so);
        alist_insert_tail(&adb_srv->pending_hosts, &adb_host->list_entry);
    }

    /* Enable I/O on the host socket. */
    loopIo_wantRead(adb_host->io);
}

/********************************************************************************
 *                            ADB server API
 *******************************************************************************/
int
adb_server_init(int port)
{
    if (!_adb_server_initialized) {
        /* Initialize the descriptor. */
        memset(&_adb_server, 0, sizeof(_adb_server));
        alist_init(&_adb_server.adb_hosts);
        alist_init(&_adb_server.adb_guests);
        alist_init(&_adb_server.pending_hosts);
        alist_init(&_adb_server.pending_guests);
        _adb_server.port = port;

        /* Create looper for an async I/O on the server. */
        _adb_server.looper = looper_newCore();
        if (_adb_server.looper == NULL) {
            E("Unable to create I/O looper for ADB server");
            return -1;
        }

        /* Create loopback server socket for the ADB port. */
        sock_address_init_inet(&_adb_server.socket_address,
                               SOCK_ADDRESS_INET_LOOPBACK, port);
        _adb_server.so = socket_loopback_server(port, SOCKET_STREAM);
        if (_adb_server.so < 0) {
            E("Unable to create ADB server socket: %s", strerror(errno));
            return -1;
        }

        /* Prepare server socket for I/O */
        socket_set_nonblock(_adb_server.so);
        loopIo_init(_adb_server.io, _adb_server.looper, _adb_server.so,
                    _on_server_socket_io, &_adb_server);
        loopIo_wantRead(_adb_server.io);

        D("ADB server has been initialized for port %d. Socket: %d",
          port, _adb_server.so);

        _adb_server_initialized = 1;
    }

    return 0;
}

int
adb_server_is_initialized(void)
{
    return _adb_server_initialized;
}

void*
adb_server_register_guest(void* opaque, AdbGuestRoutines* callbacks)
{
    if (_adb_server_initialized) {
        AdbHost* adb_host;

        /* Create and initialize ADB guest descriptor. */
        AdbGuest* const adb_guest = _adb_guest_new(&_adb_server);
        adb_guest->opaque = opaque;
        adb_guest->callbacks = callbacks;

        /* Lets see if there is a pending ADB host for the new guest. */
        adb_host = (AdbHost*)alist_remove_head(&_adb_server.pending_hosts);
        if (adb_host != NULL) {
            /* Tie up ADB host with the ADB guest. */
            alist_insert_tail(&_adb_server.adb_guests, &adb_guest->list_entry);
            alist_insert_tail(&_adb_server.adb_hosts, &adb_host->list_entry);
            _adb_connect(adb_host, adb_guest);
        } else {
            /* Host is not available. Pend this guest. */
            D("Pend ADB guest %p(o=%p)", adb_guest, adb_guest->opaque);
            alist_insert_tail(&_adb_server.pending_guests, &adb_guest->list_entry);
        }

        return adb_guest;
    } else {
        D("%s is called on an uninitialized ADB server.", __FUNCTION__);
        return NULL;
    }
}

void
adb_server_complete_connection(void* opaque)
{
    AdbGuest* const adb_guest = (AdbGuest*)opaque;
    AdbHost* const adb_host = adb_guest->adb_host;

    /* Mark the guest as fully connected and ready for the host data. */
    adb_guest->is_connected = 1;

    /* Lets see if there is a host data pending transmission to the guest. */
    if (adb_host->pending_data != NULL && adb_host->pending_data_size != 0) {
        /* Send the pending data to the guest. */
        D("Pushing %d bytes of the pending ADB host data.",
          adb_host->pending_data_size);
        adb_guest->callbacks->on_read(adb_guest->opaque, adb_guest,
                                      adb_host->pending_data,
                                      adb_host->pending_data_size);
        free(adb_host->pending_data);
        adb_host->pending_data = NULL;
        adb_host->pending_data_size = 0;
    }
}

void
adb_server_on_guest_message(void* opaque, const uint8_t* msg, int msglen)
{
    AdbGuest* const adb_guest = (AdbGuest*)opaque;
    AdbHost* const adb_host = adb_guest->adb_host;

    if (adb_host != NULL) {
        D("Sending %d bytes to the ADB host: %s", msglen, QB(msg, msglen));

        /* Lets see if we can send the data immediatelly... */
        if (adb_host->pending_send_buffer == NULL) {
            /* There are no data that are pending to be sent to the host. Do the
             * direct send. */
            const int sent = socket_send(adb_host->host_so, msg, msglen);
            if (sent < 0) {
                if (errno == EWOULDBLOCK) {
                } else {
                    D("Unable to send data to ADB host: %s", strerror(errno));
                }
            } else if (sent == 0) {
                /* Disconnect condition. */
                _on_adb_host_disconnected(adb_host);
            } else if (sent < msglen) {
                /* Couldn't send everything. Schedule write via I/O callback. */
                _adb_host_append_message(adb_host, msg + sent, msglen - sent);
            }
        } else {
            /* There are data that are pending to be sent to the host. We need
             * to append new data to the end of the pending data buffer. */
            _adb_host_append_message(adb_host, msg, msglen);
        }
    } else {
        D("ADB host is disconneted and can't accept %d bytes in %s",
          msglen, QB(msg, msglen));
    }
}

void
adb_server_on_guest_closed(void* opaque)
{
    AdbGuest* const adb_guest = (AdbGuest*)opaque;
    AdbHost* const adb_host = adb_guest->adb_host;

    /* Remove the guest from the list */
    if (!alist_is_empty(&adb_guest->list_entry)) {
        alist_remove(&adb_guest->list_entry);
    }

    /* Disassociate the host. */
    if (adb_host != NULL) {
        if (!alist_is_empty(&adb_host->list_entry)) {
            alist_remove(&adb_host->list_entry);
        }
        _adb_host_free(adb_host);
    }
    _adb_guest_free(adb_guest);
}
