"""
Check compatibility of virtio device types
"""
# Copyright (c) 2018 Red Hat, Inc.
#
# Author:
#  Eduardo Habkost <ehabkost@redhat.com>
#
# This work is licensed under the terms of the GNU GPL, version 2 or
# later.  See the COPYING file in the top-level directory.
import sys
import os

sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "scripts"))
from qemu import QEMUMachine
from avocado_qemu import Test

# Virtio Device IDs:
VIRTIO_NET = 1
VIRTIO_BLOCK = 2
VIRTIO_CONSOLE = 3
VIRTIO_RNG = 4
VIRTIO_BALLOON = 5
VIRTIO_RPMSG = 7
VIRTIO_SCSI = 8
VIRTIO_9P = 9
VIRTIO_RPROC_SERIAL = 11
VIRTIO_CAIF = 12
VIRTIO_GPU = 16
VIRTIO_INPUT = 18
VIRTIO_VSOCK = 19
VIRTIO_CRYPTO = 20

PCI_VENDOR_ID_REDHAT_QUMRANET = 0x1af4

# Device IDs for legacy/transitional devices:
PCI_LEGACY_DEVICE_IDS = {
    VIRTIO_NET:     0x1000,
    VIRTIO_BLOCK:   0x1001,
    VIRTIO_BALLOON: 0x1002,
    VIRTIO_CONSOLE: 0x1003,
    VIRTIO_SCSI:    0x1004,
    VIRTIO_RNG:     0x1005,
    VIRTIO_9P:      0x1009,
    VIRTIO_VSOCK:   0x1012,
}

def pci_modern_device_id(virtio_devid):
    return virtio_devid + 0x1040

def devtype_implements(vm, devtype, implements):
    return devtype in [d['name'] for d in vm.command('qom-list-types', implements=implements)]

def get_pci_interfaces(vm, devtype):
    interfaces = ('pci-express-device', 'conventional-pci-device')
    return [i for i in interfaces if devtype_implements(vm, devtype, i)]

class VirtioVersionCheck(Test):
    """
    Check if virtio-version-specific device types result in the
    same device tree created by `disable-modern` and
    `disable-legacy`.

    :avocado: enable
    :avocado: tags=x86_64
    """

    # just in case there are failures, show larger diff:
    maxDiff = 4096

    def run_device(self, devtype, opts=None, machine='pc'):
        """
        Run QEMU with `-device DEVTYPE`, return device info from `query-pci`
        """
        with QEMUMachine(self.qemu_bin) as vm:
            vm.set_machine(machine)
            if opts:
                devtype += ',' + opts
            vm.add_args('-device', '%s,id=devfortest' % (devtype))
            vm.add_args('-S')
            vm.launch()

            pcibuses = vm.command('query-pci')
            alldevs = [dev for bus in pcibuses for dev in bus['devices']]
            devfortest = [dev for dev in alldevs
                          if dev['qdev_id'] == 'devfortest']
            return devfortest[0], get_pci_interfaces(vm, devtype)


    def assert_devids(self, dev, devid, non_transitional=False):
        self.assertEqual(dev['id']['vendor'], PCI_VENDOR_ID_REDHAT_QUMRANET)
        self.assertEqual(dev['id']['device'], devid)
        if non_transitional:
            self.assertTrue(0x1040 <= dev['id']['device'] <= 0x107f)
            self.assertGreaterEqual(dev['id']['subsystem'], 0x40)

    def check_all_variants(self, qemu_devtype, virtio_devid):
        """Check if a virtio device type and its variants behave as expected"""
        # Force modern mode:
        dev_modern, _ = self.run_device(qemu_devtype,
                                       'disable-modern=off,disable-legacy=on')
        self.assert_devids(dev_modern, pci_modern_device_id(virtio_devid),
                           non_transitional=True)

        # <prefix>-non-transitional device types should be 100% equivalent to
        # <prefix>,disable-modern=off,disable-legacy=on
        dev_1_0, nt_ifaces = self.run_device('%s-non-transitional' % (qemu_devtype))
        self.assertEqual(dev_modern, dev_1_0)

        # Force transitional mode:
        dev_trans, _ = self.run_device(qemu_devtype,
                                      'disable-modern=off,disable-legacy=off')
        self.assert_devids(dev_trans, PCI_LEGACY_DEVICE_IDS[virtio_devid])

        # Force legacy mode:
        dev_legacy, _ = self.run_device(qemu_devtype,
                                       'disable-modern=on,disable-legacy=off')
        self.assert_devids(dev_legacy, PCI_LEGACY_DEVICE_IDS[virtio_devid])

        # No options: default to transitional on PC machine-type:
        no_opts_pc, generic_ifaces = self.run_device(qemu_devtype)
        self.assertEqual(dev_trans, no_opts_pc)

        #TODO: check if plugging on a PCI Express bus will make the
        #      device non-transitional
        #no_opts_q35 = self.run_device(qemu_devtype, machine='q35')
        #self.assertEqual(dev_modern, no_opts_q35)

        # <prefix>-transitional device types should be 100% equivalent to
        # <prefix>,disable-modern=off,disable-legacy=off
        dev_trans, trans_ifaces = self.run_device('%s-transitional' % (qemu_devtype))
        self.assertEqual(dev_trans, dev_trans)

        # ensure the interface information is correct:
        self.assertIn('conventional-pci-device', generic_ifaces)
        self.assertIn('pci-express-device', generic_ifaces)

        self.assertIn('conventional-pci-device', nt_ifaces)
        self.assertIn('pci-express-device', nt_ifaces)

        self.assertIn('conventional-pci-device', trans_ifaces)
        self.assertNotIn('pci-express-device', trans_ifaces)


    def test_conventional_devs(self):
        self.check_all_variants('virtio-net-pci', VIRTIO_NET)
        # virtio-blk requires 'driver' parameter
        #self.check_all_variants('virtio-blk-pci', VIRTIO_BLOCK)
        self.check_all_variants('virtio-serial-pci', VIRTIO_CONSOLE)
        self.check_all_variants('virtio-rng-pci', VIRTIO_RNG)
        self.check_all_variants('virtio-balloon-pci', VIRTIO_BALLOON)
        self.check_all_variants('virtio-scsi-pci', VIRTIO_SCSI)
        # virtio-9p requires 'fsdev' parameter
        #self.check_all_variants('virtio-9p-pci', VIRTIO_9P)

    def check_modern_only(self, qemu_devtype, virtio_devid):
        """Check if a modern-only virtio device type behaves as expected"""
        # Force modern mode:
        dev_modern, _ = self.run_device(qemu_devtype,
                                       'disable-modern=off,disable-legacy=on')
        self.assert_devids(dev_modern, pci_modern_device_id(virtio_devid),
                           non_transitional=True)

        # No options: should be modern anyway
        dev_no_opts, ifaces = self.run_device(qemu_devtype)
        self.assertEqual(dev_modern, dev_no_opts)

        self.assertIn('conventional-pci-device', ifaces)
        self.assertIn('pci-express-device', ifaces)

    def test_modern_only_devs(self):
        self.check_modern_only('virtio-vga', VIRTIO_GPU)
        self.check_modern_only('virtio-gpu-pci', VIRTIO_GPU)
        self.check_modern_only('virtio-mouse-pci', VIRTIO_INPUT)
        self.check_modern_only('virtio-tablet-pci', VIRTIO_INPUT)
        self.check_modern_only('virtio-keyboard-pci', VIRTIO_INPUT)
