#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "cpu.h"
#include "migration/vmstate.h"
#include "chardev/char-fe.h"
#include "hw/irq.h"
#include "hw/ppc/spapr.h"
#include "hw/ppc/spapr_vio.h"
#include "hw/qdev-properties.h"

#define VTERM_BUFSIZE   16

typedef struct SpaprVioVty {
    SpaprVioDevice sdev;
    CharBackend chardev;
    uint32_t in, out;
    uint8_t buf[VTERM_BUFSIZE];
} SpaprVioVty;

#define TYPE_VIO_SPAPR_VTY_DEVICE "spapr-vty"
#define VIO_SPAPR_VTY_DEVICE(obj) \
     OBJECT_CHECK(SpaprVioVty, (obj), TYPE_VIO_SPAPR_VTY_DEVICE)

static int vty_can_receive(void *opaque)
{
    SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(opaque);

    return VTERM_BUFSIZE - (dev->in - dev->out);
}

static void vty_receive(void *opaque, const uint8_t *buf, int size)
{
    SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(opaque);
    int i;

    if ((dev->in == dev->out) && size) {
        /* toggle line to simulate edge interrupt */
        qemu_irq_pulse(spapr_vio_qirq(&dev->sdev));
    }
    for (i = 0; i < size; i++) {
        if (dev->in - dev->out >= VTERM_BUFSIZE) {
            static bool reported;
            if (!reported) {
                error_report("VTY input buffer exhausted - characters dropped."
                             " (input size = %i)", size);
                reported = true;
            }
            break;
        }
        dev->buf[dev->in++ % VTERM_BUFSIZE] = buf[i];
    }
}

static int vty_getchars(SpaprVioDevice *sdev, uint8_t *buf, int max)
{
    SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);
    int n = 0;

    while ((n < max) && (dev->out != dev->in)) {
        /*
         * Long ago, PowerVM's vty implementation had a bug where it
         * inserted a \0 after every \r going to the guest.  Existing
         * guests have a workaround for this which removes every \0
         * immediately following a \r.  To avoid triggering this
         * workaround, we stop before inserting a \0 if the preceding
         * character in the output buffer is a \r.
         */
        if (n > 0 && (buf[n - 1] == '\r') &&
                (dev->buf[dev->out % VTERM_BUFSIZE] == '\0')) {
            break;
        }
        buf[n++] = dev->buf[dev->out++ % VTERM_BUFSIZE];
    }

    qemu_chr_fe_accept_input(&dev->chardev);

    return n;
}

void vty_putchars(SpaprVioDevice *sdev, uint8_t *buf, int len)
{
    SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);

    /* XXX this blocks entire thread. Rewrite to use
     * qemu_chr_fe_write and background I/O callbacks */
    qemu_chr_fe_write_all(&dev->chardev, buf, len);
}

static void spapr_vty_realize(SpaprVioDevice *sdev, Error **errp)
{
    SpaprVioVty *dev = VIO_SPAPR_VTY_DEVICE(sdev);

    if (!qemu_chr_fe_backend_connected(&dev->chardev)) {
        error_setg(errp, "chardev property not set");
        return;
    }

    qemu_chr_fe_set_handlers(&dev->chardev, vty_can_receive,
                             vty_receive, NULL, NULL, dev, NULL, true);
}

/* Forward declaration */
static target_ulong h_put_term_char(PowerPCCPU *cpu, SpaprMachineState *spapr,
                                    target_ulong opcode, target_ulong *args)
{
    target_ulong reg = args[0];
    target_ulong len = args[1];
    target_ulong char0_7 = args[2];
    target_ulong char8_15 = args[3];
    SpaprVioDevice *sdev;
    uint8_t buf[16];

    sdev = vty_lookup(spapr, reg);
    if (!sdev) {
        return H_PARAMETER;
    }

    if (len > 16) {
        return H_PARAMETER;
    }

    *((uint64_t *)buf) = cpu_to_be64(char0_7);
    *((uint64_t *)buf + 1) = cpu_to_be64(char8_15);

    vty_putchars(sdev, buf, len);

    return H_SUCCESS;
}

static target_ulong h_get_term_char(PowerPCCPU *cpu, SpaprMachineState *spapr,
                                    target_ulong opcode, target_ulong *args)
{
    target_ulong reg = args[0];
    target_ulong *len = args + 0;
    target_ulong *char0_7 = args + 1;
    target_ulong *char8_15 = args + 2;
    SpaprVioDevice *sdev;
    uint8_t buf[16];

    sdev = vty_lookup(spapr, reg);
    if (!sdev) {
        return H_PARAMETER;
    }

    *len = vty_getchars(sdev, buf, sizeof(buf));
    if (*len < 16) {
        memset(buf + *len, 0, 16 - *len);
    }

    *char0_7 = be64_to_cpu(*((uint64_t *)buf));
    *char8_15 = be64_to_cpu(*((uint64_t *)buf + 1));

    return H_SUCCESS;
}

void spapr_vty_create(SpaprVioBus *bus, Chardev *chardev)
{
    DeviceState *dev;

    dev = qdev_create(&bus->bus, "spapr-vty");
    qdev_prop_set_chr(dev, "chardev", chardev);
    qdev_init_nofail(dev);
}

static Property spapr_vty_properties[] = {
    DEFINE_SPAPR_PROPERTIES(SpaprVioVty, sdev),
    DEFINE_PROP_CHR("chardev", SpaprVioVty, chardev),
    DEFINE_PROP_END_OF_LIST(),
};

static const VMStateDescription vmstate_spapr_vty = {
    .name = "spapr_vty",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (VMStateField[]) {
        VMSTATE_SPAPR_VIO(sdev, SpaprVioVty),

        VMSTATE_UINT32(in, SpaprVioVty),
        VMSTATE_UINT32(out, SpaprVioVty),
        VMSTATE_BUFFER(buf, SpaprVioVty),
        VMSTATE_END_OF_LIST()
    },
};

static void spapr_vty_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    SpaprVioDeviceClass *k = VIO_SPAPR_DEVICE_CLASS(klass);

    k->realize = spapr_vty_realize;
    k->dt_name = "vty";
    k->dt_type = "serial";
    k->dt_compatible = "hvterm1";
    set_bit(DEVICE_CATEGORY_INPUT, dc->categories);
    dc->props = spapr_vty_properties;
    dc->vmsd = &vmstate_spapr_vty;
}

static const TypeInfo spapr_vty_info = {
    .name          = TYPE_VIO_SPAPR_VTY_DEVICE,
    .parent        = TYPE_VIO_SPAPR_DEVICE,
    .instance_size = sizeof(SpaprVioVty),
    .class_init    = spapr_vty_class_init,
};

SpaprVioDevice *spapr_vty_get_default(SpaprVioBus *bus)
{
    SpaprVioDevice *sdev, *selected;
    BusChild *kid;

    /*
     * To avoid the console bouncing around we want one VTY to be
     * the "default". We haven't really got anything to go on, so
     * arbitrarily choose the one with the lowest reg value.
     */

    selected = NULL;
    QTAILQ_FOREACH(kid, &bus->bus.children, sibling) {
        DeviceState *iter = kid->child;

        /* Only look at VTY devices */
        if (!object_dynamic_cast(OBJECT(iter), TYPE_VIO_SPAPR_VTY_DEVICE)) {
            continue;
        }

        sdev = VIO_SPAPR_DEVICE(iter);

        /* First VTY we've found, so it is selected for now */
        if (!selected) {
            selected = sdev;
            continue;
        }

        /* Choose VTY with lowest reg value */
        if (sdev->reg < selected->reg) {
            selected = sdev;
        }
    }

    return selected;
}

SpaprVioDevice *vty_lookup(SpaprMachineState *spapr, target_ulong reg)
{
    SpaprVioDevice *sdev;

    sdev = spapr_vio_find_by_reg(spapr->vio_bus, reg);
    if (!sdev && reg == 0) {
        /* Hack for kernel early debug, which always specifies reg==0.
         * We search all VIO devices, and grab the vty with the lowest
         * reg.  This attempts to mimic existing PowerVM behaviour
         * (early debug does work there, despite having no vty with
         * reg==0. */
        return spapr_vty_get_default(spapr->vio_bus);
    }

    if (!object_dynamic_cast(OBJECT(sdev), TYPE_VIO_SPAPR_VTY_DEVICE)) {
        return NULL;
    }

    return sdev;
}

static void spapr_vty_register_types(void)
{
    spapr_register_hypercall(H_PUT_TERM_CHAR, h_put_term_char);
    spapr_register_hypercall(H_GET_TERM_CHAR, h_get_term_char);
    type_register_static(&spapr_vty_info);
}

type_init(spapr_vty_register_types)
