/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program is distributed in the hope that 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.
*/
#include "android/utils/cbuffer.h"
#include "android/utils/debug.h"
#include "qemu/osdep.h"
#include "chardev/char-fe.h"

#define DEBUG 0

#define CPR(ptr) \
    if (!(ptr))  \
        goto Error;

#if DEBUG
#include <stdio.h>
#include "android/utils/misc.h"
#define D(...) (fprintf(stderr, __VA_ARGS__), fprintf(stderr, "\n"))
#else
#define D(...) ((void)0)
#endif

/* we want to implement a bi-directionnal communication channel
 * between two QEMU character drivers that merge well into the
 * QEMU event loop.
 *
 * each half of the channel has its own object and buffer, and
 * we implement communication through charpipe_poll() which
 * must be called by the main event loop after its call to select()
 *
 */
#define BIP_BUFFER_SIZE 512

typedef struct BipBuffer {
    struct BipBuffer* next;
    CBuffer cb[1];
    char buff[BIP_BUFFER_SIZE];
} BipBuffer;

static BipBuffer* _free_bip_buffers;

static BipBuffer* bip_buffer_alloc(void) {
    BipBuffer* bip = _free_bip_buffers;
    if (bip != NULL) {
        _free_bip_buffers = bip->next;
    } else {
        bip = malloc(sizeof(*bip));
        if (bip == NULL) {
            derror("%s: not enough memory", __FUNCTION__);
            exit(1);
        }
    }
    bip->next = NULL;
    cbuffer_reset(bip->cb, bip->buff, sizeof(bip->buff));
    return bip;
}

static void bip_buffer_free(BipBuffer* bip) {
    bip->next = _free_bip_buffers;
    _free_bip_buffers = bip;
}

/* this models each half of the charpipe */
typedef struct PipeChardev {
    Chardev parent;
    BipBuffer* bip_first;
    BipBuffer* bip_last;
    struct PipeChardev* peer; /* NULL if closed */
    QLIST_ENTRY(PipeChardev) entry;
} PipeChardev;

/** This models a charbuffer, an object used to buffer
 ** the data that is sent to a given endpoint Chardev
 ** object.
 **
 ** On the other hand, any can_read() / read() request performed
 ** by the endpoint will be passed to the BufferChardev's corresponding
 ** handlers.
 **/
typedef struct BufferChardev {
    Chardev parent;
    BipBuffer* bip_first;
    BipBuffer* bip_last;
    Chardev* endpoint; /* NULL if closed */
    QLIST_ENTRY(BufferChardev) entry;
} BufferChardev;

#define TYPE_CHARDEV_BUFFER "chardev-buffer"
#define BUFFER_CHARDEV(obj) \
    OBJECT_CHECK(BufferChardev, (obj), TYPE_CHARDEV_BUFFER)

#define TYPE_CHARDEV_ANDROID_PIPE "chardev-android-pipe"
#define ANDROID_PIPE_CHARDEV(obj) \
    OBJECT_CHECK(PipeChardev, (obj), TYPE_CHARDEV_ANDROID_PIPE)

static int charpipehalf_write(Chardev* dev, const uint8_t* buf, int len) {
    PipeChardev* ph = ANDROID_PIPE_CHARDEV(dev);
    PipeChardev* peer = ph->peer;
    BipBuffer* bip = ph->bip_last;
    int ret = 0;

    D("%s: writing %d bytes to %p: '%s'", __FUNCTION__, len, ph,
      quote_bytes((const char*)buf, len));

    if (bip == NULL && peer != NULL && peer->parent.be->chr_read != NULL) {
        /* no buffered data, try to write directly to the peer */
        while (len > 0) {
            int size;

            if (peer->parent.be->chr_can_read) {
                size = qemu_chr_be_can_write(&peer->parent);
                if (size == 0)
                    break;

                if (size > len)
                    size = len;
            } else
                size = len;

            qemu_chr_be_write(&peer->parent, (uint8_t*)buf, size);
            buf += size;
            len -= size;
            ret += size;
        }
    }

    if (len == 0)
        return ret;

    /* buffer the remaining data */
    if (bip == NULL) {
        bip = bip_buffer_alloc();
        ph->bip_first = ph->bip_last = bip;
    }

    while (len > 0) {
        int len2 = cbuffer_write(bip->cb, buf, len);

        buf += len2;
        ret += len2;
        len -= len2;
        if (len == 0)
            break;

        /* ok, we need another buffer */
        ph->bip_last = bip_buffer_alloc();
        bip->next = ph->bip_last;
        bip = ph->bip_last;
    }
    return ret;
}

static void charpipehalf_poll(PipeChardev* dev) {
    assert(dev);
    PipeChardev* peer = dev->peer;
    int size;

    if (peer == NULL || peer->parent.be->chr_read == NULL)
        return;

    while (1) {
        BipBuffer* bip = dev->bip_first;
        uint8_t* base;
        int avail;

        if (bip == NULL)
            break;

        size = cbuffer_read_avail(bip->cb);
        if (size == 0) {
            dev->bip_first = bip->next;
            if (dev->bip_first == NULL)
                dev->bip_last = NULL;
            bip_buffer_free(bip);
            continue;
        }

        if (dev->parent.be->chr_can_read) {
            int size2 = qemu_chr_be_can_write(&peer->parent);

            if (size2 == 0)
                break;

            if (size > size2)
                size = size2;
        }

        avail = cbuffer_read_peek(bip->cb, &base);
        if (avail > size)
            avail = size;
        D("%s: sending %d bytes from %p: '%s'", __FUNCTION__, avail, dev,
          quote_bytes((const char*)base, avail));

        qemu_chr_be_write(&peer->parent, base, avail);
        cbuffer_read_step(bip->cb, avail);
    }
}

static QLIST_HEAD(, PipeChardev) s_pipes = QLIST_HEAD_INITIALIZER(s_pipes);
static bool s_pipe_poll = false;

int qemu_chr_open_charpipe(Chardev** pfirst, Chardev** psecond) {
    Error* ignored_error = NULL;
    *pfirst = NULL;
    *psecond = NULL;
    Chardev* first = NULL;
    Chardev* second = NULL;
    PipeChardev* a = NULL;
    PipeChardev* b = NULL;

    first = qemu_chardev_new(NULL, TYPE_CHARDEV_ANDROID_PIPE, NULL,
                             &ignored_error);
    CPR(first);

    second = qemu_chardev_new(NULL, TYPE_CHARDEV_ANDROID_PIPE, NULL,
                              &ignored_error);
    CPR(second);

    // Link and register the chardevs.
    a = ANDROID_PIPE_CHARDEV(first);
    b = ANDROID_PIPE_CHARDEV(second);

    a->peer = b;
    b->peer = a;

    // Note that only the entry of a will be set and
    // will occur in the list, b will not occur in this list
    QLIST_INSERT_HEAD(&s_pipes, a, entry);

    *pfirst = first;
    *psecond = second;

    D("%s: created pipe between %p <--> %p", __FUNCTION__, *pfirst, *psecond);
    return 0;

Error:
    object_unref(OBJECT(first));
    object_unref(OBJECT(second));
    return -1;
}

static int charbuffer_write(Chardev* dev, const uint8_t* buf, int len) {
    BufferChardev* cbuf = BUFFER_CHARDEV(dev);
    Chardev* peer = cbuf->endpoint;
    BipBuffer* bip = cbuf->bip_last;
    int ret = 0;

    D("%s: writing %d bytes from %p to %p: '%s'", __FUNCTION__, len, dev, peer,
      quote_bytes((const char*)buf, len));

    if (bip == NULL && peer != NULL) {
        /* no buffered data, try to write directly to the peer */
        int size = qemu_chr_fe_write(peer->be, buf, len);

        if (size < 0) /* just to be safe */
            size = 0;
        else if (size > len)
            size = len;

        buf += size;
        ret += size;
        len -= size;
    }

    if (len == 0)
        return ret;

    /* buffer the remaining data */
    if (bip == NULL) {
        bip = bip_buffer_alloc();
        cbuf->bip_first = cbuf->bip_last = bip;
    }

    while (len > 0) {
        int len2 = cbuffer_write(bip->cb, buf, len);

        buf += len2;
        ret += len2;
        len -= len2;
        if (len == 0)
            break;

        /* ok, we need another buffer */
        cbuf->bip_last = bip_buffer_alloc();
        bip->next = cbuf->bip_last;
        bip = cbuf->bip_last;
    }
    return ret;
}

static void charbuffer_poll(BufferChardev* cbuf) {
    Chardev* peer = cbuf->endpoint;

    if (peer == NULL)
        return;

    while (1) {
        BipBuffer* bip = cbuf->bip_first;
        uint8_t* base;
        int avail;
        int size;

        if (bip == NULL)
            break;

        avail = cbuffer_read_peek(bip->cb, &base);
        if (avail == 0) {
            cbuf->bip_first = bip->next;
            if (cbuf->bip_first == NULL)
                cbuf->bip_last = NULL;
            bip_buffer_free(bip);
            continue;
        }

        size = qemu_chr_fe_write(peer->be, base, avail);

        if (size < 0) /* just to be safe */
            size = 0;
        else if (size > avail)
            size = avail;

        cbuffer_read_step(bip->cb, size);

        if (size < avail)
            break;
    }
}

static QLIST_HEAD(, BufferChardev)
        s_charbuffers = QLIST_HEAD_INITIALIZER(s_charbuffers);

Chardev* qemu_chr_open_buffer(Chardev* endpoint) {
    Error* error = NULL;
    Chardev* dev = qemu_chardev_new(NULL, TYPE_CHARDEV_BUFFER, NULL, &error);
    if (!dev) {
        return NULL;
    }

    BufferChardev* buffer = BUFFER_CHARDEV(dev);
    buffer->endpoint = endpoint;

    QLIST_INSERT_HEAD(&s_charbuffers, buffer, entry);

    D("%s: created buffered chardev %p with endpoint: %p", __FUNCTION__, dev,
      buffer->endpoint);
    return dev;
}

void qemu_charpipe_poll(void) {
    /**
     * Look ma! No locks.
     *
     * There are 2 cases where locking is needed:
     *
     * - We are introducing new devices when this loop is active
     *   - This does not happen in the case of android emulator.
     *     All the devices are constructed before the execution of
     *     qemu main_loop. So new elements will not be added to
     *     any of the lists that we iterate over.
     *
     * - We are removing devices when this loop is active:
     *   - QEMU does not decrease the refcount of any of its created devices
     *     (yet). Because of this finalize is never called on any of the
     *     objects, and hence we will never decrease the refcount to the point
     *     where we will have to remove a device while this loops is active.
     */
    PipeChardev* cps;
    BufferChardev* bc;

    // Polling loop has been activated. If you need support for dynamically
    // adding/removing of devices you will need to turn this into a mutex.
    s_pipe_poll = true;

    /* poll the charpipes */
    QLIST_FOREACH(cps, &s_pipes, entry) {
        charpipehalf_poll(cps);
        charpipehalf_poll(cps->peer);
    }

    /* poll the buffers */
    QLIST_FOREACH(bc, &s_charbuffers, entry) { charbuffer_poll(bc); }
}

static void charbuffer_finalize(Object* obj) {
    // We don't support deletion of devices once we started
    // the polling loop, as we don't have locks around our list
    // access
    assert(!s_pipe_poll);
    BufferChardev* cbuf = BUFFER_CHARDEV(obj);
    while (cbuf->bip_first) {
        BipBuffer* bip = cbuf->bip_first;
        cbuf->bip_first = bip->next;
        bip_buffer_free(bip);
    }
    cbuf->bip_last = NULL;
    cbuf->endpoint = NULL;

    if (cbuf->endpoint != NULL) {
        object_unparent(OBJECT(cbuf->endpoint));
        cbuf->endpoint = NULL;
    }

    QLIST_REMOVE(cbuf, entry);
}

static void charbuffer_class_init(ObjectClass* oc, void* data) {
    ChardevClass* cc = CHARDEV_CLASS(oc);
    cc->chr_write = charbuffer_write;
}

static const TypeInfo charbuffer_type_info = {
        .name = TYPE_CHARDEV_BUFFER,
        .parent = TYPE_CHARDEV,
        .instance_size = sizeof(BufferChardev),
        .instance_finalize = charbuffer_finalize,
        .class_init = charbuffer_class_init,
};

static void charpipe_finalize(Object* obj) {
    // We don't support deletion of devices once we started
    // the polling loop, as we don't have locks around our list
    // access
    assert(!s_pipe_poll);

    PipeChardev* ph = ANDROID_PIPE_CHARDEV(obj);
    while (ph->bip_first) {
        BipBuffer* bip = ph->bip_first;
        ph->bip_first = bip->next;
        bip_buffer_free(bip);
    }
    ph->bip_last = NULL;
    ph->peer = NULL;

    QLIST_REMOVE(ph, entry);
}

static void charpipe_class_init(ObjectClass* oc, void* data) {
    ChardevClass* cc = CHARDEV_CLASS(oc);
    cc->chr_write = charpipehalf_write;
}

static const TypeInfo charpipe_type_info = {
        .name = TYPE_CHARDEV_ANDROID_PIPE,
        .parent = TYPE_CHARDEV,
        .instance_size = sizeof(PipeChardev),
        .instance_finalize = charpipe_finalize,
        .class_init = charpipe_class_init,
};

static void register_types(void) {
    type_register_static(&charbuffer_type_info);
    type_register_static(&charpipe_type_info);
}

// Note that this is a static constructor that gets called upon
// loading of this library. This only works if one function in this
// file gets actually linked into the final executable. Two cases:
// 1. This does not get linked in:
//   -- This is fine as the devices registered are only referenced
//      in this file.
// 2. This does get linked in:
//   -- The qemu types will be registered and therefore available.
type_init(register_types);
