/*
 * QEMU I/O channels memory buffer driver
 *
 * Copyright (c) 2015 Red Hat, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include "qemu/osdep.h"
#include "io/channel-buffer.h"
#include "io/channel-watch.h"
#include "qemu/module.h"
#include "qemu/sockets.h"
#include "trace.h"

QIOChannelBuffer *
qio_channel_buffer_new(size_t capacity)
{
    QIOChannelBuffer *ioc;

    ioc = QIO_CHANNEL_BUFFER(object_new(TYPE_QIO_CHANNEL_BUFFER));

    if (capacity) {
        ioc->data = g_new0(uint8_t, capacity);
        ioc->capacity = capacity;
    }

    return ioc;
}


static void qio_channel_buffer_finalize(Object *obj)
{
    QIOChannelBuffer *ioc = QIO_CHANNEL_BUFFER(obj);
    g_free(ioc->data);
    ioc->capacity = ioc->usage = ioc->offset = 0;
}


static ssize_t qio_channel_buffer_readv(QIOChannel *ioc,
                                        const struct iovec *iov,
                                        size_t niov,
                                        int **fds,
                                        size_t *nfds,
                                        Error **errp)
{
    QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);
    ssize_t ret = 0;
    size_t i;

    for (i = 0; i < niov; i++) {
        size_t want = iov[i].iov_len;
        if (bioc->offset >= bioc->usage) {
            break;
        }
        if ((bioc->offset + want) > bioc->usage)  {
            want = bioc->usage - bioc->offset;
        }
        memcpy(iov[i].iov_base, bioc->data + bioc->offset, want);
        ret += want;
        bioc->offset += want;
    }

    return ret;
}

static ssize_t qio_channel_buffer_writev(QIOChannel *ioc,
                                         const struct iovec *iov,
                                         size_t niov,
                                         int *fds,
                                         size_t nfds,
                                         Error **errp)
{
    QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);
    ssize_t ret = 0;
    size_t i;
    size_t towrite = 0;

    for (i = 0; i < niov; i++) {
        towrite += iov[i].iov_len;
    }

    if ((bioc->offset + towrite) > bioc->capacity) {
        bioc->capacity = bioc->offset + towrite;
        bioc->data = g_realloc(bioc->data, bioc->capacity);
    }

    if (bioc->offset > bioc->usage) {
        memset(bioc->data, 0, bioc->offset - bioc->usage);
        bioc->usage = bioc->offset;
    }

    for (i = 0; i < niov; i++) {
        memcpy(bioc->data + bioc->usage,
               iov[i].iov_base,
               iov[i].iov_len);
        bioc->usage += iov[i].iov_len;
        bioc->offset += iov[i].iov_len;
        ret += iov[i].iov_len;
    }

    return ret;
}

static int qio_channel_buffer_set_blocking(QIOChannel *ioc G_GNUC_UNUSED,
                                           bool enabled G_GNUC_UNUSED,
                                           Error **errp G_GNUC_UNUSED)
{
    return 0;
}


static off_t qio_channel_buffer_seek(QIOChannel *ioc,
                                     off_t offset,
                                     int whence,
                                     Error **errp)
{
    QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);

    bioc->offset = offset;

    return offset;
}


static int qio_channel_buffer_close(QIOChannel *ioc,
                                    Error **errp)
{
    QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);

    g_free(bioc->data);
    bioc->data = NULL;
    bioc->capacity = bioc->usage = bioc->offset = 0;

    return 0;
}


typedef struct QIOChannelBufferSource QIOChannelBufferSource;
struct QIOChannelBufferSource {
    GSource parent;
    QIOChannelBuffer *bioc;
    GIOCondition condition;
};

static gboolean
qio_channel_buffer_source_prepare(GSource *source,
                                  gint *timeout)
{
    QIOChannelBufferSource *bsource = (QIOChannelBufferSource *)source;

    *timeout = -1;

    return (G_IO_IN | G_IO_OUT) & bsource->condition;
}

static gboolean
qio_channel_buffer_source_check(GSource *source)
{
    QIOChannelBufferSource *bsource = (QIOChannelBufferSource *)source;

    return (G_IO_IN | G_IO_OUT) & bsource->condition;
}

static gboolean
qio_channel_buffer_source_dispatch(GSource *source,
                                   GSourceFunc callback,
                                   gpointer user_data)
{
    QIOChannelFunc func = (QIOChannelFunc)callback;
    QIOChannelBufferSource *bsource = (QIOChannelBufferSource *)source;

    return (*func)(QIO_CHANNEL(bsource->bioc),
                   ((G_IO_IN | G_IO_OUT) & bsource->condition),
                   user_data);
}

static void
qio_channel_buffer_source_finalize(GSource *source)
{
    QIOChannelBufferSource *ssource = (QIOChannelBufferSource *)source;

    object_unref(OBJECT(ssource->bioc));
}

GSourceFuncs qio_channel_buffer_source_funcs = {
    qio_channel_buffer_source_prepare,
    qio_channel_buffer_source_check,
    qio_channel_buffer_source_dispatch,
    qio_channel_buffer_source_finalize
};

static GSource *qio_channel_buffer_create_watch(QIOChannel *ioc,
                                                GIOCondition condition)
{
    QIOChannelBuffer *bioc = QIO_CHANNEL_BUFFER(ioc);
    QIOChannelBufferSource *ssource;
    GSource *source;

    source = g_source_new(&qio_channel_buffer_source_funcs,
                          sizeof(QIOChannelBufferSource));
    ssource = (QIOChannelBufferSource *)source;

    ssource->bioc = bioc;
    object_ref(OBJECT(bioc));

    ssource->condition = condition;

    return source;
}


static void qio_channel_buffer_class_init(ObjectClass *klass,
                                          void *class_data G_GNUC_UNUSED)
{
    QIOChannelClass *ioc_klass = QIO_CHANNEL_CLASS(klass);

    ioc_klass->io_writev = qio_channel_buffer_writev;
    ioc_klass->io_readv = qio_channel_buffer_readv;
    ioc_klass->io_set_blocking = qio_channel_buffer_set_blocking;
    ioc_klass->io_seek = qio_channel_buffer_seek;
    ioc_klass->io_close = qio_channel_buffer_close;
    ioc_klass->io_create_watch = qio_channel_buffer_create_watch;
}

static const TypeInfo qio_channel_buffer_info = {
    .parent = TYPE_QIO_CHANNEL,
    .name = TYPE_QIO_CHANNEL_BUFFER,
    .instance_size = sizeof(QIOChannelBuffer),
    .instance_finalize = qio_channel_buffer_finalize,
    .class_init = qio_channel_buffer_class_init,
};

static void qio_channel_buffer_register_types(void)
{
    type_register_static(&qio_channel_buffer_info);
}

type_init(qio_channel_buffer_register_types);
