"""
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__), '..', '..', 'python'))
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: tags=arch: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)
