/*
 * 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/format.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  FHP(dst, dstLen, src, srcLen)  format_hex_printable2(dst, dstLen, src, (srcLen < 32) ? srcLen : 32)
#define  FHP_MAX (9*(32/4) + 4 + 9*(32/8)) // format_hex_printable2 output len for 32 src bytes

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 tmp[FHP_MAX];
    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, FHP(tmp, sizeof(tmp), 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;
    char tmp[FHP_MAX];

    if (adb_host != NULL) {
        D("Sending %d bytes to the ADB host: %s", msglen, FHP(tmp, sizeof(tmp), 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, FHP(tmp, sizeof(tmp), 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);
}
