#include "qemu/osdep.h"
#include "hw/hw.h"
#include "hw/pci/pci.h"
#include "vga_int.h"
#include "hw/virtio/virtio-pci.h"
#include "hw/virtio/virtio-gpu.h"
#include "qapi/error.h"

/*
 * virtio-vga: This extends VirtioPCIProxy.
 */
#define TYPE_VIRTIO_VGA "virtio-vga"
#define VIRTIO_VGA(obj) \
        OBJECT_CHECK(VirtIOVGA, (obj), TYPE_VIRTIO_VGA)
#define VIRTIO_VGA_GET_CLASS(obj) \
        OBJECT_GET_CLASS(VirtIOVGAClass, obj, TYPE_VIRTIO_VGA)
#define VIRTIO_VGA_CLASS(klass) \
        OBJECT_CLASS_CHECK(VirtIOVGAClass, klass, TYPE_VIRTIO_VGA)

typedef struct VirtIOVGA {
    VirtIOPCIProxy parent_obj;
    VirtIOGPU      vdev;
    VGACommonState vga;
    MemoryRegion   vga_mrs[3];
} VirtIOVGA;

typedef struct VirtIOVGAClass {
    VirtioPCIClass parent_class;
    DeviceReset parent_reset;
} VirtIOVGAClass;

static void virtio_vga_invalidate_display(void *opaque)
{
    VirtIOVGA *vvga = opaque;

    if (vvga->vdev.enable) {
        virtio_gpu_ops.invalidate(&vvga->vdev);
    } else {
        vvga->vga.hw_ops->invalidate(&vvga->vga);
    }
}

static void virtio_vga_update_display(void *opaque)
{
    VirtIOVGA *vvga = opaque;

    if (vvga->vdev.enable) {
        virtio_gpu_ops.gfx_update(&vvga->vdev);
    } else {
        vvga->vga.hw_ops->gfx_update(&vvga->vga);
    }
}

static void virtio_vga_text_update(void *opaque, console_ch_t *chardata)
{
    VirtIOVGA *vvga = opaque;

    if (vvga->vdev.enable) {
        if (virtio_gpu_ops.text_update) {
            virtio_gpu_ops.text_update(&vvga->vdev, chardata);
        }
    } else {
        if (vvga->vga.hw_ops->text_update) {
            vvga->vga.hw_ops->text_update(&vvga->vga, chardata);
        }
    }
}

static int virtio_vga_ui_info(void *opaque, uint32_t idx, QemuUIInfo *info)
{
    VirtIOVGA *vvga = opaque;

    if (virtio_gpu_ops.ui_info) {
        return virtio_gpu_ops.ui_info(&vvga->vdev, idx, info);
    }
    return -1;
}

static void virtio_vga_gl_block(void *opaque, bool block)
{
    VirtIOVGA *vvga = opaque;

    if (virtio_gpu_ops.gl_block) {
        virtio_gpu_ops.gl_block(&vvga->vdev, block);
    }
}

static const GraphicHwOps virtio_vga_ops = {
    .invalidate = virtio_vga_invalidate_display,
    .gfx_update = virtio_vga_update_display,
    .text_update = virtio_vga_text_update,
    .ui_info = virtio_vga_ui_info,
    .gl_block = virtio_vga_gl_block,
};

static const VMStateDescription vmstate_virtio_vga = {
    .name = "virtio-vga",
    .version_id = 2,
    .minimum_version_id = 2,
    .fields = (VMStateField[]) {
        /* no pci stuff here, saving the virtio device will handle that */
        VMSTATE_STRUCT(vga, VirtIOVGA, 0, vmstate_vga_common, VGACommonState),
        VMSTATE_END_OF_LIST()
    }
};

/* VGA device wrapper around PCI device around virtio GPU */
static void virtio_vga_realize(VirtIOPCIProxy *vpci_dev, Error **errp)
{
    VirtIOVGA *vvga = VIRTIO_VGA(vpci_dev);
    VirtIOGPU *g = &vvga->vdev;
    VGACommonState *vga = &vvga->vga;
    Error *err = NULL;
    uint32_t offset;
    int i;

    /* init vga compat bits */
    vga->vram_size_mb = 8;
    vga_common_init(vga, OBJECT(vpci_dev));
    vga_init(vga, OBJECT(vpci_dev), pci_address_space(&vpci_dev->pci_dev),
             pci_address_space_io(&vpci_dev->pci_dev), true);
    pci_register_bar(&vpci_dev->pci_dev, 0,
                     PCI_BASE_ADDRESS_MEM_PREFETCH, &vga->vram);

    /*
     * Configure virtio bar and regions
     *
     * We use bar #2 for the mmio regions, to be compatible with stdvga.
     * virtio regions are moved to the end of bar #2, to make room for
     * the stdvga mmio registers at the start of bar #2.
     */
    vpci_dev->modern_mem_bar_idx = 2;
    vpci_dev->msix_bar_idx = 4;

    if (!(vpci_dev->flags & VIRTIO_PCI_FLAG_PAGE_PER_VQ)) {
        /*
         * with page-per-vq=off there is no padding space we can use
         * for the stdvga registers.  Make the common and isr regions
         * smaller then.
         */
        vpci_dev->common.size /= 2;
        vpci_dev->isr.size /= 2;
    }

    offset = memory_region_size(&vpci_dev->modern_bar);
    offset -= vpci_dev->notify.size;
    vpci_dev->notify.offset = offset;
    offset -= vpci_dev->device.size;
    vpci_dev->device.offset = offset;
    offset -= vpci_dev->isr.size;
    vpci_dev->isr.offset = offset;
    offset -= vpci_dev->common.size;
    vpci_dev->common.offset = offset;

    /* init virtio bits */
    qdev_set_parent_bus(DEVICE(g), BUS(&vpci_dev->bus));
    virtio_pci_force_virtio_1(vpci_dev);
    object_property_set_bool(OBJECT(g), true, "realized", &err);
    if (err) {
        error_propagate(errp, err);
        return;
    }

    /* add stdvga mmio regions */
    pci_std_vga_mmio_region_init(vga, OBJECT(vvga), &vpci_dev->modern_bar,
                                 vvga->vga_mrs, true, false);

    vga->con = g->scanout[0].con;
    graphic_console_set_hwops(vga->con, &virtio_vga_ops, vvga);

    for (i = 0; i < g->conf.max_outputs; i++) {
        object_property_set_link(OBJECT(g->scanout[i].con),
                                 OBJECT(vpci_dev),
                                 "device", errp);
    }
}

static void virtio_vga_reset(DeviceState *dev)
{
    VirtIOVGAClass *klass = VIRTIO_VGA_GET_CLASS(dev);
    VirtIOVGA *vvga = VIRTIO_VGA(dev);

    /* reset virtio-gpu */
    klass->parent_reset(dev);

    /* reset vga */
    vga_common_reset(&vvga->vga);
    vga_dirty_log_start(&vvga->vga);
}

static Property virtio_vga_properties[] = {
    DEFINE_VIRTIO_GPU_PCI_PROPERTIES(VirtIOPCIProxy),
    DEFINE_PROP_END_OF_LIST(),
};

static void virtio_vga_class_init(ObjectClass *klass, void *data)
{
    DeviceClass *dc = DEVICE_CLASS(klass);
    VirtioPCIClass *k = VIRTIO_PCI_CLASS(klass);
    VirtIOVGAClass *v = VIRTIO_VGA_CLASS(klass);
    PCIDeviceClass *pcidev_k = PCI_DEVICE_CLASS(klass);

    set_bit(DEVICE_CATEGORY_DISPLAY, dc->categories);
    dc->props = virtio_vga_properties;
    dc->vmsd = &vmstate_virtio_vga;
    dc->hotpluggable = false;
    device_class_set_parent_reset(dc, virtio_vga_reset,
                                  &v->parent_reset);

    k->realize = virtio_vga_realize;
    pcidev_k->romfile = "vgabios-virtio.bin";
    pcidev_k->class_id = PCI_CLASS_DISPLAY_VGA;
}

static void virtio_vga_inst_initfn(Object *obj)
{
    VirtIOVGA *dev = VIRTIO_VGA(obj);

    virtio_instance_init_common(obj, &dev->vdev, sizeof(dev->vdev),
                                TYPE_VIRTIO_GPU);
}

static VirtioPCIDeviceTypeInfo virtio_vga_info = {
    .generic_name  = TYPE_VIRTIO_VGA,
    .instance_size = sizeof(struct VirtIOVGA),
    .instance_init = virtio_vga_inst_initfn,
    .class_size    = sizeof(struct VirtIOVGAClass),
    .class_init    = virtio_vga_class_init,
};

static void virtio_vga_register_types(void)
{
    virtio_pci_types_register(&virtio_vga_info);
}

type_init(virtio_vga_register_types)
