/*
 * libqos driver framework
 *
 * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License version 2 as published by the Free Software Foundation.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, see <http://www.gnu.org/licenses/>
 */

#include "qemu/osdep.h"
#include "libqtest.h"
#include "qemu/module.h"
#include "standard-headers/linux/virtio_blk.h"
#include "libqos/qgraph.h"
#include "libqos/virtio-blk.h"

#define PCI_SLOT                0x04
#define PCI_FN                  0x00

/* virtio-blk-device */
static void *qvirtio_blk_get_driver(QVirtioBlk *v_blk,
                                    const char *interface)
{
    if (!g_strcmp0(interface, "virtio-blk")) {
        return v_blk;
    }
    if (!g_strcmp0(interface, "virtio")) {
        return v_blk->vdev;
    }

    fprintf(stderr, "%s not present in virtio-blk-device\n", interface);
    g_assert_not_reached();
}

static void *qvirtio_blk_device_get_driver(void *object,
                                           const char *interface)
{
    QVirtioBlkDevice *v_blk = object;
    return qvirtio_blk_get_driver(&v_blk->blk, interface);
}

static void *virtio_blk_device_create(void *virtio_dev,
                                      QGuestAllocator *t_alloc,
                                      void *addr)
{
    QVirtioBlkDevice *virtio_blk = g_new0(QVirtioBlkDevice, 1);
    QVirtioBlk *interface = &virtio_blk->blk;

    interface->vdev = virtio_dev;

    virtio_blk->obj.get_driver = qvirtio_blk_device_get_driver;

    return &virtio_blk->obj;
}

/* virtio-blk-pci */
static void *qvirtio_blk_pci_get_driver(void *object, const char *interface)
{
    QVirtioBlkPCI *v_blk = object;
    if (!g_strcmp0(interface, "pci-device")) {
        return v_blk->pci_vdev.pdev;
    }
    return qvirtio_blk_get_driver(&v_blk->blk, interface);
}

static void *virtio_blk_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
                                      void *addr)
{
    QVirtioBlkPCI *virtio_blk = g_new0(QVirtioBlkPCI, 1);
    QVirtioBlk *interface = &virtio_blk->blk;
    QOSGraphObject *obj = &virtio_blk->pci_vdev.obj;

    virtio_pci_init(&virtio_blk->pci_vdev, pci_bus, addr);
    interface->vdev = &virtio_blk->pci_vdev.vdev;

    g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_BLOCK);

    obj->get_driver = qvirtio_blk_pci_get_driver;

    return obj;
}

static void virtio_blk_register_nodes(void)
{
    /* FIXME: every test using these two nodes needs to setup a
     * -drive,id=drive0 otherwise QEMU is not going to start.
     * Therefore, we do not include "produces" edge for virtio
     * and pci-device yet.
    */

    char *arg = g_strdup_printf("id=drv0,drive=drive0,addr=%x.%x",
                                PCI_SLOT, PCI_FN);

    QPCIAddress addr = {
        .devfn = QPCI_DEVFN(PCI_SLOT, PCI_FN),
    };

    QOSGraphEdgeOptions opts = { };

    /* virtio-blk-device */
    opts.extra_device_opts = "drive=drive0";
    qos_node_create_driver("virtio-blk-device", virtio_blk_device_create);
    qos_node_consumes("virtio-blk-device", "virtio-bus", &opts);
    qos_node_produces("virtio-blk-device", "virtio-blk");

    /* virtio-blk-pci */
    opts.extra_device_opts = arg;
    add_qpci_address(&opts, &addr);
    qos_node_create_driver("virtio-blk-pci", virtio_blk_pci_create);
    qos_node_consumes("virtio-blk-pci", "pci-bus", &opts);
    qos_node_produces("virtio-blk-pci", "virtio-blk");

    g_free(arg);
}

libqos_init(virtio_blk_register_nodes);
