# 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 skipUnless
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.cmd('human-monitor-command', command_line='stop')
        self.vm.cmd('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)

    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)

    @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable 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
        :avocado: tags=flaky
        """
        self.do_test_i6400_framebuffer_logo(7)

    @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable 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
        :avocado: tags=flaky
        """
        self.do_test_i6400_framebuffer_logo(8)

class MaltaMachine(QemuSystemTest):

    def do_test_yamon(self):
        rom_url = ('https://s3-eu-west-1.amazonaws.com/'
                   'downloads-mips/mips-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()

    def test_mipsel_malta_yamon(self):
        """
        :avocado: tags=arch:mipsel
        :avocado: tags=machine:malta
        :avocado: tags=endian:little
        """
        self.do_test_yamon()

    def test_mips64el_malta_yamon(self):
        """
        :avocado: tags=arch:mips64el
        :avocado: tags=machine:malta
        :avocado: tags=endian:little
        """
        self.do_test_yamon()
