/* virtio-pingpong: virtio-serial backend that just sends all
 * data it receives back to the guest.
 *
 * Copyright (c) 2013 Linaro Limited
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 */

#include "sysemu/char.h"
#include "qemu/error-report.h"
#include "trace.h"
#include "hw/virtio/virtio-serial.h"

#define TYPE_VIRTIO_PINGPONG "virtpingpong"
#define VIRTIO_PINGPONG(obj) \
    OBJECT_CHECK(VirtPingpong, (obj), TYPE_VIRTIO_PINGPONG)

typedef struct VirtPingpong {
    VirtIOSerialPort parent_obj;
    /* Any per-backend data goes here */
} VirtPingpong;


/* Callback function that's called when the guest sends us data */
static ssize_t virtpingpong_have_data(VirtIOSerialPort *port,
                                      const uint8_t *buf, ssize_t len)
{
    //VirtPingpong *vpp = VIRTIO_PINGPONG(port);
    ssize_t ret;

    printf("virtpingpong_have_data: %zd bytes\n", len);

    ret = virtio_serial_write(port, buf, len);

    printf("virtpingpong_have_data: passed %zd bytes back\n", ret);

    if (ret < len) {
        /* We didn't manage to send all the data: throttle the
         * port so we don't get any more for now.
         */
        virtio_serial_throttle_port(port, true);
    }

    return ret;
}

static void virtpingpong_guest_writable(VirtIOSerialPort *port)
{
    printf("virtpingpong_guest_writable\n");
    /* Just unthrottle the other end of the port so it can send us more data */
    virtio_serial_throttle_port(port, false);
}

/* Callback function that's called when the guest opens/closes the port */
static void virtpingpong_set_guest_connected(VirtIOSerialPort *port,
                                             int guest_connected)
{
    //VirtPingpong *vpp = VIRTIO_PINGPONG(port);

    printf("virtpingpong: guest %sconnected\n", guest_connected ? "" : "dis");
}

static void virtpingpong_realize(DeviceState *dev, Error **errp)
{
    VirtIOSerialPort *port = VIRTIO_SERIAL_PORT(dev);
    //VirtPingpong *vpp = VIRTIO_PINGPONG(dev);
    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_GET_CLASS(dev);

    if (port->id == 0 && !k->is_console) {
        error_setg(errp, "Port number 0 on virtio-serial devices reserved "
                   "for virtconsole devices for backward compatibility.");
        return;
    }

    /* The host end of this connection is always open. */
    virtio_serial_open(port);
}

static void virtpingpong_unrealize(DeviceState *dev, Error **errp)
{
    // VirtPingpong *vpp = VIRTIO_PINGPONG(dev);

    /* Nothing for us to do here */
}

static void virtpingpong_class_init(ObjectClass *klass, void *data)
{
    VirtIOSerialPortClass *k = VIRTIO_SERIAL_PORT_CLASS(klass);

    k->realize = virtpingpong_realize;
    k->unrealize = virtpingpong_unrealize;
    k->have_data = virtpingpong_have_data;
    k->guest_writable = virtpingpong_guest_writable;
    k->set_guest_connected = virtpingpong_set_guest_connected;
    /* If we have any device state for save/load we should
     * register a vmstate here.
     */
}

static const TypeInfo virtpingpong_info = {
    .name          = TYPE_VIRTIO_PINGPONG,
    .parent        = TYPE_VIRTIO_SERIAL_PORT,
    .instance_size = sizeof(VirtPingpong),
    .class_init    = virtpingpong_class_init,
};

static void virtpingpong_register_types(void)
{
    type_register_static(&virtpingpong_info);
}

type_init(virtpingpong_register_types)
