/*
 * QEMU System Emulator
 *
 * Copyright (c) 2003-2008 Fabrice Bellard
 *
 * 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/module.h"
#include "qemu/sockets.h"
#include "qapi/error.h"
#include "chardev/char.h"
#include "chardev/char-fe.h"
#include "io/channel-file.h"

#include "chardev/char-fd.h"
#include "chardev/char-io.h"

/* Called with chr_write_lock held.  */
static int fd_chr_write(Chardev *chr, const uint8_t *buf, int len)
{
    FDChardev *s = FD_CHARDEV(chr);

    if (!s->ioc_out) {
        return -1;
    }

    return io_channel_send(s->ioc_out, buf, len);
}

static gboolean fd_chr_read(QIOChannel *chan, GIOCondition cond, void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    FDChardev *s = FD_CHARDEV(opaque);
    int len;
    uint8_t buf[CHR_READ_BUF_LEN];
    ssize_t ret;

    len = sizeof(buf);
    if (len > s->max_size) {
        len = s->max_size;
    }
    if (len == 0) {
        return TRUE;
    }

    ret = qio_channel_read(
        chan, (gchar *)buf, len, NULL);
    if (ret == 0) {
        remove_fd_in_watch(chr);
        qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
        return FALSE;
    }
    if (ret > 0) {
        qemu_chr_be_write(chr, buf, ret);
    }

    return TRUE;
}

static int fd_chr_read_poll(void *opaque)
{
    Chardev *chr = CHARDEV(opaque);
    FDChardev *s = FD_CHARDEV(opaque);

    s->max_size = qemu_chr_be_can_write(chr);
    return s->max_size;
}

typedef struct FDSource {
    GSource parent;

    GIOCondition cond;
} FDSource;

static gboolean
fd_source_prepare(GSource *source,
                  gint *timeout_)
{
    FDSource *src = (FDSource *)source;

    return src->cond != 0;
}

static gboolean
fd_source_check(GSource *source)
{
    FDSource *src = (FDSource *)source;

    return src->cond != 0;
}

static gboolean
fd_source_dispatch(GSource *source, GSourceFunc callback,
                   gpointer user_data)
{
    FDSource *src = (FDSource *)source;
    FEWatchFunc func = (FEWatchFunc)callback;
    gboolean ret = G_SOURCE_CONTINUE;

    if (src->cond) {
        ret = func(NULL, src->cond, user_data);
        src->cond = 0;
    }

    return ret;
}

static GSourceFuncs fd_source_funcs = {
  fd_source_prepare,
  fd_source_check,
  fd_source_dispatch,
  NULL, NULL, NULL
};

static GSource *fd_source_new(FDChardev *chr)
{
    return g_source_new(&fd_source_funcs, sizeof(FDSource));
}

static gboolean child_func(GIOChannel *source,
                           GIOCondition condition,
                           gpointer data)
{
    FDSource *parent = data;

    parent->cond |= condition;

    return G_SOURCE_CONTINUE;
}

static GSource *fd_chr_add_watch(Chardev *chr, GIOCondition cond)
{
    FDChardev *s = FD_CHARDEV(chr);
    g_autoptr(GSource) source = fd_source_new(s);

    if (s->ioc_out) {
        g_autoptr(GSource) child = qio_channel_create_watch(s->ioc_out, cond & ~G_IO_IN);
        g_source_set_callback(child, (GSourceFunc)child_func, source, NULL);
        g_source_add_child_source(source, child);
    }
    if (s->ioc_in) {
        g_autoptr(GSource) child = qio_channel_create_watch(s->ioc_in, cond & ~G_IO_OUT);
        g_source_set_callback(child, (GSourceFunc)child_func, source, NULL);
        g_source_add_child_source(source, child);
    }

    return g_steal_pointer(&source);
}

static void fd_chr_update_read_handler(Chardev *chr)
{
    FDChardev *s = FD_CHARDEV(chr);

    remove_fd_in_watch(chr);
    if (s->ioc_in) {
        chr->gsource = io_add_watch_poll(chr, s->ioc_in,
                                           fd_chr_read_poll,
                                           fd_chr_read, chr,
                                           chr->gcontext);
    }
}

static void char_fd_finalize(Object *obj)
{
    Chardev *chr = CHARDEV(obj);
    FDChardev *s = FD_CHARDEV(obj);

    remove_fd_in_watch(chr);
    if (s->ioc_in) {
        object_unref(OBJECT(s->ioc_in));
    }
    if (s->ioc_out) {
        object_unref(OBJECT(s->ioc_out));
    }

    qemu_chr_be_event(chr, CHR_EVENT_CLOSED);
}

int qmp_chardev_open_file_source(char *src, int flags, Error **errp)
{
    int fd = -1;

    fd = RETRY_ON_EINTR(qemu_open_old(src, flags, 0666));
    if (fd == -1) {
        error_setg_file_open(errp, errno, src);
    }
    return fd;
}

/* open a character device to a unix fd */
void qemu_chr_open_fd(Chardev *chr,
                      int fd_in, int fd_out)
{
    FDChardev *s = FD_CHARDEV(chr);
    g_autofree char *name = NULL;

    if (fd_out >= 0 && !g_unix_set_fd_nonblocking(fd_out, true, NULL)) {
        assert(!"Failed to set FD nonblocking");
    }

    if (fd_out == fd_in && fd_in >= 0) {
        s->ioc_in = QIO_CHANNEL(qio_channel_file_new_fd(fd_in));
        name = g_strdup_printf("chardev-file-%s", chr->label);
        qio_channel_set_name(QIO_CHANNEL(s->ioc_in), name);
        s->ioc_out = QIO_CHANNEL(object_ref(s->ioc_in));
        return;
    }

    if (fd_in >= 0) {
        s->ioc_in = QIO_CHANNEL(qio_channel_file_new_fd(fd_in));
        name = g_strdup_printf("chardev-file-in-%s", chr->label);
        qio_channel_set_name(QIO_CHANNEL(s->ioc_in), name);
    }

    if (fd_out >= 0) {
        s->ioc_out = QIO_CHANNEL(qio_channel_file_new_fd(fd_out));
        g_free(name);
        name = g_strdup_printf("chardev-file-out-%s", chr->label);
        qio_channel_set_name(QIO_CHANNEL(s->ioc_out), name);
    }
}

static void char_fd_class_init(ObjectClass *oc, void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->chr_add_watch = fd_chr_add_watch;
    cc->chr_write = fd_chr_write;
    cc->chr_update_read_handler = fd_chr_update_read_handler;
}

static const TypeInfo char_fd_type_info = {
    .name = TYPE_CHARDEV_FD,
    .parent = TYPE_CHARDEV,
    .instance_size = sizeof(FDChardev),
    .instance_finalize = char_fd_finalize,
    .class_init = char_fd_class_init,
    .abstract = true,
};

static void register_types(void)
{
    type_register_static(&char_fd_type_info);
}

type_init(register_types);
