/*
 * QEMUFile backend for QIOChannel objects
 *
 * Copyright (c) 2015-2016 Red Hat, Inc
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include "qemu/osdep.h"
#include "qemu-file-channel.h"
#include "migration/qemu-file.h"
#include "io/channel-socket.h"
#include "qemu/iov.h"


static ssize_t channel_writev_buffer(void *opaque,
                                     struct iovec *iov,
                                     int iovcnt,
                                     int64_t pos)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);
    ssize_t done = 0;
    struct iovec *local_iov = g_new(struct iovec, iovcnt);
    struct iovec *local_iov_head = local_iov;
    unsigned int nlocal_iov = iovcnt;

    nlocal_iov = iov_copy(local_iov, nlocal_iov,
                          iov, iovcnt,
                          0, iov_size(iov, iovcnt));

    while (nlocal_iov > 0) {
        ssize_t len;
        len = qio_channel_writev(ioc, local_iov, nlocal_iov, NULL);
        if (len == QIO_CHANNEL_ERR_BLOCK) {
            qio_channel_wait(ioc, G_IO_OUT);
            continue;
        }
        if (len < 0) {
            /* XXX handle Error objects */
            done = -EIO;
            goto cleanup;
        }

        iov_discard_front(&local_iov, &nlocal_iov, len);
        done += len;
    }

 cleanup:
    g_free(local_iov_head);
    return done;
}


static ssize_t channel_get_buffer(void *opaque,
                                  uint8_t *buf,
                                  int64_t pos,
                                  size_t size)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);
    ssize_t ret;

    do {
        ret = qio_channel_read(ioc, (char *)buf, size, NULL);
        if (ret < 0) {
            if (ret == QIO_CHANNEL_ERR_BLOCK) {
                qio_channel_yield(ioc, G_IO_IN);
            } else {
                /* XXX handle Error * object */
                return -EIO;
            }
        }
    } while (ret == QIO_CHANNEL_ERR_BLOCK);

    return ret;
}


static int channel_close(void *opaque)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);
    qio_channel_close(ioc, NULL);
    object_unref(OBJECT(ioc));
    return 0;
}


static int channel_shutdown(void *opaque,
                            bool rd,
                            bool wr)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);

    if (qio_channel_has_feature(ioc,
                                QIO_CHANNEL_FEATURE_SHUTDOWN)) {
        QIOChannelShutdown mode;
        if (rd && wr) {
            mode = QIO_CHANNEL_SHUTDOWN_BOTH;
        } else if (rd) {
            mode = QIO_CHANNEL_SHUTDOWN_READ;
        } else {
            mode = QIO_CHANNEL_SHUTDOWN_WRITE;
        }
        if (qio_channel_shutdown(ioc, mode, NULL) < 0) {
            /* XXX handler Error * object */
            return -EIO;
        }
    }
    return 0;
}


static int channel_set_blocking(void *opaque,
                                bool enabled)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);

    if (qio_channel_set_blocking(ioc, enabled, NULL) < 0) {
        return -1;
    }
    return 0;
}

static QEMUFile *channel_get_input_return_path(void *opaque)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);

    return qemu_fopen_channel_output(ioc);
}

static QEMUFile *channel_get_output_return_path(void *opaque)
{
    QIOChannel *ioc = QIO_CHANNEL(opaque);

    return qemu_fopen_channel_input(ioc);
}

static const QEMUFileOps channel_input_ops = {
    .get_buffer = channel_get_buffer,
    .close = channel_close,
    .shut_down = channel_shutdown,
    .set_blocking = channel_set_blocking,
    .get_return_path = channel_get_input_return_path,
};


static const QEMUFileOps channel_output_ops = {
    .writev_buffer = channel_writev_buffer,
    .close = channel_close,
    .shut_down = channel_shutdown,
    .set_blocking = channel_set_blocking,
    .get_return_path = channel_get_output_return_path,
};


QEMUFile *qemu_fopen_channel_input(QIOChannel *ioc)
{
    object_ref(OBJECT(ioc));
    return qemu_fopen_ops(ioc, &channel_input_ops);
}

QEMUFile *qemu_fopen_channel_output(QIOChannel *ioc)
{
    object_ref(OBJECT(ioc));
    return qemu_fopen_ops(ioc, &channel_output_ops);
}
