#!/usr/libexec/platform-python
#
# Test subsystem-vendor for rhel/vz7 machine types
#
# Copyright (c) 2018 Virtuozzo International GmbH
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#

import sys
import os
import iotests

sys.path.append(os.path.join(os.path.dirname(__file__), '..', '..', 'python'))
from qemu.machine import QEMUMachine

# just to not run the test on each format
iotests.script_initialize(supported_fmts=['qcow2'])


def check_balloon_id(machine, subsystem_vendor):
    vm = QEMUMachine(iotests.qemu_prog,
                     ['-machine', machine,
                      '-device', 'virtio-balloon-pci,id=balloon0'])
    vm.launch()
    devices = vm.qmp('query-pci')['return'][0]['devices']
    vm.shutdown()

    # possibly the last one
    for dev in devices:
        if dev['qdev_id'] == 'balloon0':
            break

    assert dev['qdev_id'] == 'balloon0'
    assert dev['id']['vendor'] == 0x1af4
    assert dev['id']['device'] == 0x1002
    assert dev['id']['subsystem'] == 0x5

    if (dev['id']['subsystem-vendor'] != subsystem_vendor):
        print('ERROR: %s: subsystem_vendor: %x (should be %x)' %
              (machine, dev['id']['subsystem-vendor'], subsystem_vendor))
        return False

    return True

def check_qxl_subvendor_id(machine, expected_vendor):
    def print_test_error(msg):
        print("ERROR [check qxl vendor id]: {0}".format(msg))

    qxl_id = 'qxl0'
    qxl_dev_cmd = 'qxl-vga,id={0}'.format(qxl_id)

    vm = QEMUMachine(iotests.qemu_prog,
            ['-machine', machine, '-device', qxl_dev_cmd])
    vm.launch()
    devices = vm.qmp('query-pci')['return'][0]['devices']
    vm.shutdown()

    qxl_dev = None
    for dev in devices:
        if dev['qdev_id'] == qxl_id:
            qxl_dev = dev['id']
            break

    if dev == None:
        print_test_error('qxl device wasn\'t found')
        return False

    assert qxl_dev['vendor'] == 0x1b36 # PCI_VENDOR_ID_REDHAT
    assert qxl_dev['device'] == 0x100  # PCI_DEVICE_ID_REDHAT_QXL
    assert qxl_dev['subsystem'] == 0x1100 # PCI_SUBDEVICE_ID_QEMU

    found_vendor = qxl_dev['subsystem-vendor']

    if (found_vendor != expected_vendor):
        msg = "%s: subsystem-vendor-id mismatch: %x (should be: %x)"\
              % (machine, found_vendor, expected_vendor)
        print_test_error(msg)
        return False

    return True


vm = iotests.VM()
vm.launch()
machines = [m['name'] for m in vm.qmp('query-machines')['return']]
vm.shutdown()

failed = 0

for m in sorted(machines):
    if m.startswith('rhel6') or m == 'none':
        continue

    # checking for baloon subvendor setting
    prefix, major, minor = m.split('.')
    machine, chipset, osrel = prefix.split('-')
    if (osrel == 'vz7' and int(major) >= 7) or osrel == 'vz8':
        # VZ subsystem-vendor
        ok = check_balloon_id(m, 0x1df0)
    else:
        # RHEL subsystem-vendor
        ok = check_balloon_id(m, 0x1af4)

    # checking for qxl-vga subvendor setting
    if (osrel == 'vz7' and int(major) >= 12) or osrel == 'vz8':
        # VZ subsystem-vendor
        ok = check_qxl_subvendor_id(m, 0x1df0)
    else:
        # RHEL subsystem-vendor
        ok = check_qxl_subvendor_id(m, 0x1af4)

    if not ok:
        failed += 1

if failed > 0:
    print('\nFailed %d machine types' % failed)
else:
    print('Success')
