/*
 * This work is licensed under the terms of the GNU GPL, version 2 or
 * (at your option) any later version.  See the COPYING file in the
 * top-level directory.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/iov.h"
#include "trace.h"

#include "hw/qdev.h"
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-input.h"

#include "standard-headers/linux/input.h"

#define VIRTIO_INPUT_VM_VERSION 1

/* ----------------------------------------------------------------- */

void virtio_input_send(VirtIOInput *vinput, virtio_input_event *event)
{
    VirtQueueElement *elem;
    unsigned have, need;
    int i, len;

    if (!vinput->active) {
        return;
    }

    /* queue up events ... */
    if (vinput->qindex == vinput->qsize) {
        vinput->qsize++;
        vinput->queue = realloc(vinput->queue, vinput->qsize *
                                sizeof(virtio_input_event));
    }
    vinput->queue[vinput->qindex++] = *event;

    /* ... until we see a report sync ... */
    if (event->type != cpu_to_le16(EV_SYN) ||
        event->code != cpu_to_le16(SYN_REPORT)) {
        return;
    }

    /* ... then check available space ... */
    need = sizeof(virtio_input_event) * vinput->qindex;
    virtqueue_get_avail_bytes(vinput->evt, &have, NULL, need, 0);
    if (have < need) {
        vinput->qindex = 0;
        trace_virtio_input_queue_full();
        return;
    }

    /* ... and finally pass them to the guest */
    for (i = 0; i < vinput->qindex; i++) {
        elem = virtqueue_pop(vinput->evt, sizeof(VirtQueueElement));
        if (!elem) {
            /* should not happen, we've checked for space beforehand */
            fprintf(stderr, "%s: Huh?  No vq elem available ...\n", __func__);
            return;
        }
        len = iov_from_buf(elem->in_sg, elem->in_num,
                           0, vinput->queue+i, sizeof(virtio_input_event));
        virtqueue_push(vinput->evt, elem, len);
        g_free(elem);
    }
    virtio_notify(VIRTIO_DEVICE(vinput), vinput->evt);
    vinput->qindex = 0;
}

static void virtio_input_handle_evt(VirtIODevice *vdev, VirtQueue *vq)
{
    /* nothing */
}

static void virtio_input_handle_sts(VirtIODevice *vdev, VirtQueue *vq)
{
    VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
    VirtIOInput *vinput = VIRTIO_INPUT(vdev);
    virtio_input_event event;
    VirtQueueElement *elem;
    int len;

    for (;;) {
        elem = virtqueue_pop(vinput->sts, sizeof(VirtQueueElement));
        if (!elem) {
            break;
        }

        memset(&event, 0, sizeof(event));
        len = iov_to_buf(elem->out_sg, elem->out_num,
                         0, &event, sizeof(event));
        if (vic->handle_status) {
            vic->handle_status(vinput, &event);
        }
        virtqueue_push(vinput->sts, elem, len);
        g_free(elem);
    }
    virtio_notify(vdev, vinput->sts);
}

virtio_input_config *virtio_input_find_config(VirtIOInput *vinput,
                                              uint8_t select,
                                              uint8_t subsel)
{
    VirtIOInputConfig *cfg;

    QTAILQ_FOREACH(cfg, &vinput->cfg_list, node) {
        if (select == cfg->config.select &&
            subsel == cfg->config.subsel) {
            return &cfg->config;
        }
    }
    return NULL;
}

void virtio_input_add_config(VirtIOInput *vinput,
                             virtio_input_config *config)
{
    VirtIOInputConfig *cfg;

    if (virtio_input_find_config(vinput, config->select, config->subsel)) {
        /* should not happen */
        fprintf(stderr, "%s: duplicate config: %d/%d\n",
                __func__, config->select, config->subsel);
        abort();
    }

    cfg = g_new0(VirtIOInputConfig, 1);
    cfg->config = *config;
    QTAILQ_INSERT_TAIL(&vinput->cfg_list, cfg, node);
}

void virtio_input_init_config(VirtIOInput *vinput,
                              virtio_input_config *config)
{
    int i = 0;

    QTAILQ_INIT(&vinput->cfg_list);
    while (config[i].select) {
        virtio_input_add_config(vinput, config + i);
        i++;
    }
}

void virtio_input_idstr_config(VirtIOInput *vinput,
                               uint8_t select, const char *string)
{
    virtio_input_config id;

    if (!string) {
        return;
    }
    memset(&id, 0, sizeof(id));
    id.select = select;
    id.size = snprintf(id.u.string, sizeof(id.u.string), "%s", string);
    virtio_input_add_config(vinput, &id);
}

static void virtio_input_get_config(VirtIODevice *vdev, uint8_t *config_data)
{
    VirtIOInput *vinput = VIRTIO_INPUT(vdev);
    virtio_input_config *config;

    config = virtio_input_find_config(vinput, vinput->cfg_select,
                                      vinput->cfg_subsel);
    if (config) {
        memcpy(config_data, config, vinput->cfg_size);
    } else {
        memset(config_data, 0, vinput->cfg_size);
    }
}

static void virtio_input_set_config(VirtIODevice *vdev,
                                    const uint8_t *config_data)
{
    VirtIOInput *vinput = VIRTIO_INPUT(vdev);
    virtio_input_config *config = (virtio_input_config *)config_data;

    vinput->cfg_select = config->select;
    vinput->cfg_subsel = config->subsel;
    virtio_notify_config(vdev);
}

static uint64_t virtio_input_get_features(VirtIODevice *vdev, uint64_t f,
                                          Error **errp)
{
    return f;
}

static void virtio_input_set_status(VirtIODevice *vdev, uint8_t val)
{
    VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
    VirtIOInput *vinput = VIRTIO_INPUT(vdev);

    if (val & VIRTIO_CONFIG_S_DRIVER_OK) {
        if (!vinput->active) {
            vinput->active = true;
            if (vic->change_active) {
                vic->change_active(vinput);
            }
        }
    }
}

static void virtio_input_reset(VirtIODevice *vdev)
{
    VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vdev);
    VirtIOInput *vinput = VIRTIO_INPUT(vdev);

    if (vinput->active) {
        vinput->active = false;
        if (vic->change_active) {
            vic->change_active(vinput);
        }
    }
}

static int virtio_input_load(QEMUFile *f, void *opaque, size_t size)
{
    VirtIOInput *vinput = opaque;
    VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(vinput);
    VirtIODevice *vdev = VIRTIO_DEVICE(vinput);
    int ret;

    ret = virtio_load(vdev, f, VIRTIO_INPUT_VM_VERSION);
    if (ret) {
        return ret;
    }

    /* post_load() */
    vinput->active = vdev->status & VIRTIO_CONFIG_S_DRIVER_OK;
    if (vic->change_active) {
        vic->change_active(vinput);
    }
    return 0;
}

static void virtio_input_device_realize(DeviceState *dev, Error **errp)
{
    VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    VirtIOInput *vinput = VIRTIO_INPUT(dev);
    VirtIOInputConfig *cfg;
    Error *local_err = NULL;

    if (vic->realize) {
        vic->realize(dev, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            return;
        }
    }

    virtio_input_idstr_config(vinput, VIRTIO_INPUT_CFG_ID_SERIAL,
                              vinput->serial);

    QTAILQ_FOREACH(cfg, &vinput->cfg_list, node) {
        if (vinput->cfg_size < cfg->config.size) {
            vinput->cfg_size = cfg->config.size;
        }
    }
    vinput->cfg_size += 8;
    assert(vinput->cfg_size <= sizeof(virtio_input_config));

    virtio_init(vdev, "virtio-input", VIRTIO_ID_INPUT,
                vinput->cfg_size);
    vinput->evt = virtio_add_queue(vdev, 64, virtio_input_handle_evt);
    vinput->sts = virtio_add_queue(vdev, 64, virtio_input_handle_sts);
}

static void virtio_input_finalize(Object *obj)
{
    VirtIOInput *vinput = VIRTIO_INPUT(obj);
    VirtIOInputConfig *cfg, *next;

    QTAILQ_FOREACH_SAFE(cfg, &vinput->cfg_list, node, next) {
        QTAILQ_REMOVE(&vinput->cfg_list, cfg, node);
        g_free(cfg);
    }
}
static void virtio_input_device_unrealize(DeviceState *dev, Error **errp)
{
    VirtIOInputClass *vic = VIRTIO_INPUT_GET_CLASS(dev);
    VirtIODevice *vdev = VIRTIO_DEVICE(dev);
    Error *local_err = NULL;

    if (vic->unrealize) {
        vic->unrealize(dev, &local_err);
        if (local_err) {
            error_propagate(errp, local_err);
            return;
        }
    }
    virtio_cleanup(vdev);
}

VMSTATE_VIRTIO_DEVICE(input, VIRTIO_INPUT_VM_VERSION, virtio_input_load,
                      virtio_vmstate_save);

static Property virtio_input_properties[] = {
    DEFINE_PROP_STRING("serial", VirtIOInput, serial),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_input_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioDeviceClass *vdc = VIRTIO_DEVICE_CLASS(klass);

    dc->props          = virtio_input_properties;
    dc->vmsd           = &vmstate_virtio_input;
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
    vdc->realize      = virtio_input_device_realize;
    vdc->unrealize    = virtio_input_device_unrealize;
    vdc->get_config   = virtio_input_get_config;
    vdc->set_config   = virtio_input_set_config;
    vdc->get_features = virtio_input_get_features;
    vdc->set_status   = virtio_input_set_status;
    vdc->reset        = virtio_input_reset;
}

static const TypeInfo virtio_input_info = {
    .name          = TYPE_VIRTIO_INPUT,
    .parent        = TYPE_VIRTIO_DEVICE,
    .instance_size = sizeof(VirtIOInput),
    .class_size    = sizeof(VirtIOInputClass),
    .class_init    = virtio_input_class_init,
    .abstract      = true,
    .instance_finalize = virtio_input_finalize,
};

/* ----------------------------------------------------------------- */

static void virtio_register_types(void)
{
    type_register_static(&virtio_input_info);
}

type_init(virtio_register_types)
