# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
r"""Runs a binary on an FPGA,  which is expected to write
one of "PASS!\r\n" or "FAIL!\r\n" to the UART to determine success or failure.
Failing to write either will result in a timeout.

This test requires some setup and some configuration. This test expects you
to have:
  - A supported FPGA connected to your workstation.
  - That FPGA must be flashed with a synthesized EarlGrey bitfile, which has
    been spliced with the OpenTitan bootloader.
  - A prebuilt spiflash executable.

You must then provide this test with the .bin file for the test, the UART
device path for the FPGA, and the spiflash executable. For example:

$ cd ${REPO_TOP}
$ pytest -s -v test/systemtest/functional_fpga_test.py \
  --test_bin sw/device/tests/hmac/sw.bin \
  --fpga_uart /dev/ttyUSB2 \
  --spiflash sw/host/spiflash/spiflash
"""

import logging
from pathlib import Path
import re

import pytest

import test_utils

logging.basicConfig(level=logging.DEBUG)


class TestFunctionalFpga:
    """
    Execute a test binary on a locally connected FPGA, using UART
    output to validate test success or failure.
    """
    @pytest.fixture
    def spiflash_proc(self, tmp_path, spiflash, sw_test_bin):
        cmd_flash = [str(spiflash), '--input', str(sw_test_bin)]
        p_flash = test_utils.Process(cmd_flash,
                                   logdir=str(tmp_path),
                                   cwd=str(tmp_path),
                                   startup_done_expect='Running SPI flash update.',
                                   startup_timeout=10)
        p_flash.run()

        yield p_flash

        p_flash.terminate()

    def test_execute_binary(self, spiflash_proc, fpga_uart, uart_timeout, logfile):
        """
        Executes the binary and inspects its UART for "PASS!\r\n" or "FAIL!\r\n".
        """

        logger = logging.getLogger(__name__)
        test_utils.setup_logfile(logger, logfile)


        # Open the UART device and read line by line until we pass or fail.
        with fpga_uart.open('rb') as uart_device:
            uart_fd = uart_device.fileno()
            pattern = re.compile('.*?(PASS!\r\n|FAIL!\r\n)')
            match = test_utils.stream_fd_to_log(uart_fd, logger, pattern,
                                                uart_timeout)

            if match == None:
                pytest.fail('Deadline exceeded: did not see PASS! or FAIL! within %ds.', uart_timeout)

            if match.group(1) == 'PASS!\r\n':
                logger.debug('Got PASS! from binary.')
            else:
                pytest.fail('Got FAIL! from binary.')
