/*
 * QEMU I/O channels null driver
 *
 * Copyright (c) 2022 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-null.h"
#include "io/channel-watch.h"
#include "qapi/error.h"
#include "trace.h"
#include "qemu/iov.h"

typedef struct QIOChannelNullSource QIOChannelNullSource;
struct QIOChannelNullSource {
    GSource parent;
    QIOChannel *ioc;
    GIOCondition condition;
};


QIOChannelNull *
qio_channel_null_new(void)
{
    QIOChannelNull *ioc;

    ioc = QIO_CHANNEL_NULL(object_new(TYPE_QIO_CHANNEL_NULL));

    trace_qio_channel_null_new(ioc);

    return ioc;
}


static void
qio_channel_null_init(Object *obj)
{
    QIOChannelNull *ioc = QIO_CHANNEL_NULL(obj);
    ioc->closed = false;
}


static ssize_t
qio_channel_null_readv(QIOChannel *ioc,
                       const struct iovec *iov,
                       size_t niov,
                       int **fds G_GNUC_UNUSED,
                       size_t *nfds G_GNUC_UNUSED,
                       Error **errp)
{
    QIOChannelNull *nioc = QIO_CHANNEL_NULL(ioc);

    if (nioc->closed) {
        error_setg_errno(errp, EINVAL,
                         "Channel is closed");
        return -1;
    }

    return 0;
}


static ssize_t
qio_channel_null_writev(QIOChannel *ioc,
                        const struct iovec *iov,
                        size_t niov,
                        int *fds G_GNUC_UNUSED,
                        size_t nfds G_GNUC_UNUSED,
                        int flags G_GNUC_UNUSED,
                        Error **errp)
{
    QIOChannelNull *nioc = QIO_CHANNEL_NULL(ioc);

    if (nioc->closed) {
        error_setg_errno(errp, EINVAL,
                         "Channel is closed");
        return -1;
    }

    return iov_size(iov, niov);
}


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


static off_t
qio_channel_null_seek(QIOChannel *ioc G_GNUC_UNUSED,
                      off_t offset G_GNUC_UNUSED,
                      int whence G_GNUC_UNUSED,
                      Error **errp G_GNUC_UNUSED)
{
    return 0;
}


static int
qio_channel_null_close(QIOChannel *ioc,
                       Error **errp G_GNUC_UNUSED)
{
    QIOChannelNull *nioc = QIO_CHANNEL_NULL(ioc);

    nioc->closed = true;
    return 0;
}


static void
qio_channel_null_set_aio_fd_handler(QIOChannel *ioc G_GNUC_UNUSED,
                                    AioContext *ctx G_GNUC_UNUSED,
                                    IOHandler *io_read G_GNUC_UNUSED,
                                    IOHandler *io_write G_GNUC_UNUSED,
                                    void *opaque G_GNUC_UNUSED)
{
}


static gboolean
qio_channel_null_source_prepare(GSource *source G_GNUC_UNUSED,
                                gint *timeout)
{
    *timeout = -1;

    return TRUE;
}


static gboolean
qio_channel_null_source_check(GSource *source G_GNUC_UNUSED)
{
    return TRUE;
}


static gboolean
qio_channel_null_source_dispatch(GSource *source,
                                 GSourceFunc callback,
                                 gpointer user_data)
{
    QIOChannelFunc func = (QIOChannelFunc)callback;
    QIOChannelNullSource *ssource = (QIOChannelNullSource *)source;

    return (*func)(ssource->ioc,
                   ssource->condition,
                   user_data);
}


static void
qio_channel_null_source_finalize(GSource *source)
{
    QIOChannelNullSource *ssource = (QIOChannelNullSource *)source;

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


GSourceFuncs qio_channel_null_source_funcs = {
    qio_channel_null_source_prepare,
    qio_channel_null_source_check,
    qio_channel_null_source_dispatch,
    qio_channel_null_source_finalize
};


static GSource *
qio_channel_null_create_watch(QIOChannel *ioc,
                              GIOCondition condition)
{
    GSource *source;
    QIOChannelNullSource *ssource;

    source = g_source_new(&qio_channel_null_source_funcs,
                          sizeof(QIOChannelNullSource));
    ssource = (QIOChannelNullSource *)source;

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

    ssource->condition = condition;

    return source;
}


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

    ioc_klass->io_writev = qio_channel_null_writev;
    ioc_klass->io_readv = qio_channel_null_readv;
    ioc_klass->io_set_blocking = qio_channel_null_set_blocking;
    ioc_klass->io_seek = qio_channel_null_seek;
    ioc_klass->io_close = qio_channel_null_close;
    ioc_klass->io_create_watch = qio_channel_null_create_watch;
    ioc_klass->io_set_aio_fd_handler = qio_channel_null_set_aio_fd_handler;
}


static const TypeInfo qio_channel_null_info = {
    .parent = TYPE_QIO_CHANNEL,
    .name = TYPE_QIO_CHANNEL_NULL,
    .instance_size = sizeof(QIOChannelNull),
    .instance_init = qio_channel_null_init,
    .class_init = qio_channel_null_class_init,
};


static void
qio_channel_null_register_types(void)
{
    type_register_static(&qio_channel_null_info);
}

type_init(qio_channel_null_register_types);
