# Functional tests for the MIPS Malta board
#
# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org>
#
# This work is licensed under the terms of the GNU GPL, version 2 or later.
# See the COPYING file in the top-level directory.
#
# SPDX-License-Identifier: GPL-2.0-or-later

import os
import gzip
import logging

from avocado import skip
from avocado import skipIf
from avocado import skipUnless
from avocado.utils import archive
from avocado_qemu import QemuSystemTest
from avocado_qemu import exec_command_and_wait_for_pattern
from avocado_qemu import interrupt_interactive_console_until_pattern
from avocado_qemu import wait_for_console_pattern


NUMPY_AVAILABLE = True
try:
    import numpy as np
except ImportError:
    NUMPY_AVAILABLE = False

CV2_AVAILABLE = True
try:
    import cv2
except ImportError:
    CV2_AVAILABLE = False


@skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed')
@skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed')
class MaltaMachineFramebuffer(QemuSystemTest):

    timeout = 30

    KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '

    def do_test_i6400_framebuffer_logo(self, cpu_cores_count):
        """
        Boot Linux kernel and check Tux logo is displayed on the framebuffer.
        """
        screendump_path = os.path.join(self.workdir, 'screendump.pbm')

        kernel_url = ('https://github.com/philmd/qemu-testing-blob/raw/'
                      'a5966ca4b5/mips/malta/mips64el/'
                      'vmlinux-4.7.0-rc1.I6400.gz')
        kernel_hash = '096f50c377ec5072e6a366943324622c312045f6'
        kernel_path_gz = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
        kernel_path = self.workdir + "vmlinux"
        archive.gzip_uncompress(kernel_path_gz, kernel_path)

        tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/'
                       'drivers/video/logo/logo_linux_vga16.ppm')
        tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af'
        tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash)

        self.vm.set_console()
        kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
                               'clocksource=GIC console=tty0 console=ttyS0')
        self.vm.add_args('-kernel', kernel_path,
                         '-smp', '%u' % cpu_cores_count,
                         '-vga', 'std',
                         '-append', kernel_command_line)
        self.vm.launch()
        framebuffer_ready = 'Console: switching to colour frame buffer device'
        wait_for_console_pattern(self, framebuffer_ready,
                                 failure_message='Kernel panic - not syncing')
        self.vm.command('human-monitor-command', command_line='stop')
        self.vm.command('human-monitor-command',
                        command_line='screendump %s' % screendump_path)
        logger = logging.getLogger('framebuffer')

        match_threshold = 0.95
        screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR)
        tuxlogo_bgr = cv2.imread(tuxlogo_path, cv2.IMREAD_COLOR)
        result = cv2.matchTemplate(screendump_bgr, tuxlogo_bgr,
                                   cv2.TM_CCOEFF_NORMED)
        loc = np.where(result >= match_threshold)
        tuxlogo_count = 0
        h, w = tuxlogo_bgr.shape[:2]
        debug_png = os.getenv('AVOCADO_CV2_SCREENDUMP_PNG_PATH')
        for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1):
            logger.debug('found Tux at position (x, y) = %s', pt)
            cv2.rectangle(screendump_bgr, pt,
                          (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
        if debug_png:
            cv2.imwrite(debug_png, screendump_bgr)
        self.assertGreaterEqual(tuxlogo_count, cpu_cores_count)

    @skip('https://gitlab.com/qemu-project/qemu/-/issues/1884')
    def test_mips_malta_i6400_framebuffer_logo_1core(self):
        """
        :avocado: tags=arch:mips64el
        :avocado: tags=machine:malta
        :avocado: tags=cpu:I6400
        """
        self.do_test_i6400_framebuffer_logo(1)

    @skip('https://gitlab.com/qemu-project/qemu/-/issues/1884')
    @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
    def test_mips_malta_i6400_framebuffer_logo_7cores(self):
        """
        :avocado: tags=arch:mips64el
        :avocado: tags=machine:malta
        :avocado: tags=cpu:I6400
        :avocado: tags=mips:smp
        """
        self.do_test_i6400_framebuffer_logo(7)

    @skip('https://gitlab.com/qemu-project/qemu/-/issues/1884')
    @skipIf(os.getenv('GITLAB_CI'), 'Running on GitLab')
    def test_mips_malta_i6400_framebuffer_logo_8cores(self):
        """
        :avocado: tags=arch:mips64el
        :avocado: tags=machine:malta
        :avocado: tags=cpu:I6400
        :avocado: tags=mips:smp
        """
        self.do_test_i6400_framebuffer_logo(8)

class MaltaMachine(QemuSystemTest):

    def do_test_yamon(self):
        rom_url = ('http://www.imgtec.com/tools/mips-tools/downloads/'
                   'yamon/yamon-bin-02.22.zip')
        rom_hash = '8da7ecddbc5312704b8b324341ee238189bde480'
        zip_path = self.fetch_asset(rom_url, asset_hash=rom_hash)

        archive.extract(zip_path, self.workdir)
        yamon_path = os.path.join(self.workdir, 'yamon-02.22.bin')

        self.vm.set_console()
        self.vm.add_args('-bios', yamon_path)
        self.vm.launch()

        prompt =  'YAMON>'
        pattern = 'YAMON ROM Monitor'
        interrupt_interactive_console_until_pattern(self, pattern, prompt)
        wait_for_console_pattern(self, prompt)
        self.vm.shutdown()

    @skip('https://gitlab.com/qemu-project/qemu/-/issues/1884')
    def test_mipsel_malta_yamon(self):
        """
        :avocado: tags=arch:mipsel
        :avocado: tags=machine:malta
        :avocado: tags=endian:little
        """
        self.do_test_yamon()

    @skip('https://gitlab.com/qemu-project/qemu/-/issues/1884')
    def test_mips64el_malta_yamon(self):
        """
        :avocado: tags=arch:mips64el
        :avocado: tags=machine:malta
        :avocado: tags=endian:little
        """
        self.do_test_yamon()
