#!/usr/bin/env python3
#
# Copyright 2023 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import time

from robot.api.logger import info

import serial


# Ensure this class gets re-instantiated for every test.
ROBOT_LIBRARY_SCOPE = "TEST"


def OpenSerialPort(device, baudrate, timeout, write_timeout) -> serial.Serial:
    """
    Helper function to open a pyserial device using the given settings.

    Throws an AssertionError if it could not open the given device.
    """
    info(f"OpenSerialPort(dev={device}, baud={baudrate}, timeout={timeout}, wrtimeout={write_timeout}")
    ser = serial.Serial(port=device,
                        timeout=timeout,
                        write_timeout=write_timeout,
                        baudrate=baudrate)
    if not ser.is_open:
        raise AssertionError(f"Could not open {device}!")
    return ser


class FPGALibrary:
    """
    Class to extend the Robot test framework

    Adds Renode-compatible faked keywords as well as serial input and
    output for the various tests.
    """

    # Ensure this class gets re-instantiated for every test.
    ROBOT_LIBRARY_SCOPE = "TEST"

    def __init__(self, *args, **kwargs) -> None:
        """
        Initialize the class library.

        On construction, opens the serial ports for the given FPGA
        board ID. Throws an AssertionError if it fails.

        Arguments expected in kwargs:
          board_id: string. Required. The FPGA board ID to test. Used to
            construct path names to the UARTs.
          timeout: string. The amount of time in seconds to wait in a read
            or write to the serial ports.
        """
        info(f"FPGALibrary installed ({args}, {kwargs})")

        self.board_id = kwargs['board_id']

        self.timeout = None
        if kwargs.get('timeout'):
            self.timeout = float(kwargs['timeout'])
        if kwargs.get('quiesce_delay_seconds'):
            self.quiesce_delay_seconds = float(kwargs['quiesce_delay_seconds'])

        self.smc_uart = f"/dev/Nexus-CP210-FPGA-UART-{self.board_id}"
        self.sc_uart = f"/dev/Nexus-FTDI-{self.board_id}-FPGA-UART"

        self.uarts = {}
        self.default_uart = None

        self.open_serial_ports()

    def _quiesce_input(self, port) -> None:
        """
        Drains a given port of all incoming data.

        Because serial has no actual "end state", it's possible for
        a device to continually send data. The best we can do to sync
        up with the output is delay a second each time we drain to
        really wait for the output to stop.

        Essentially, if no character is sent for at least one second,
        we consider the port to be "quiesced". It's a bad heuristic,
        but since there is no actual command and control protocol,
        this is the best we get for synchronizing I/O to a command
        line.

        Arguments:
          port: serial.Serial instance. The port to drain of data.
        """
        # Loop while there is data available on the port, then delay
        # for a second to make sure we've actually caught all of the
        # incoming data.
        result = ''
        while True:
            info(f"_quiesce_input: port.read({port.in_waiting})")
            result += port.read(port.in_waiting).decode()
            info(f"_quiesce_input: sleep({self.quiesce_delay_seconds})")
            time.sleep(self.quiesce_delay_seconds)
            if port.in_waiting == 0:
                break
        info(f"_quiesce_input read: [{result}]")

    def _write_string_to_uart(self, port, s, wait_for_echo=True) -> None:
        """
        Writes a given string to the given port.

        Throws AssertionError if the echoed back data doesn't match, or a
        read timeout occurs.

        Arguments:
          port: serial.Serial instance. The port to write data to.
          s: string. The string to write to the port.
          wait_for_echo: boolean. Whether or not to wait for echoed
            data back from the port.
        """
        # Flush the write buffers and drain inputs -- might not be
        # needed, but do it anyway to ensure we're synced up.
        port.flush()
        self._quiesce_input(port)

        port.write(s.encode('utf-8'))
        port.flush()
        info(f"wrote [{s}]")

        if wait_for_echo:
            result = port.read(len(s)).decode()
            info(f"read [{result}]")

            # We didn't get the same length string back -- likely caused by a timeout.
            if len(result) < len(s):
                raise AssertionError(
                    "Timeout when reading from UART -- did not read " +
                    f"{s}]({len(result)})! " +
                    f"Got: [{result}]({len(result)})")

            if s != result:
                raise AssertionError(
                    "Write String to UART: Echo back: Did not read " +
                    f"[{s}]({len(result)}) from port! " +
                    f"Got: [{result}]({len(result)})")

    def _write_line_to_uart(self, port, line, wait_for_echo=True) -> None:
        """
        Writes the given string with a newline to the given port.

        Throws AssertionError if the echoed back data doesn't match, or
        a read timeout occurs.

        Arguments:
          port: serial.Serial instance. The port to write data to.
          s: string. The string to write to the port.
          wait_for_echo: boolean. Whether or not to wait for echoed
            data back from the port.
        """
        self._write_string_to_uart(port, line + '\n', wait_for_echo)

    def _wait_for_string_on_uart(self, port, s) -> None:
        """
        Waits until the given string is found in the port buffer.

        Throws AssertionError if a timeout occurs, or if the buffer
        doesn't match up with the string to wait for.

        Arguments:
          port: serial.Serial instance. The port to wait for data from.
          s: string. The string to look for on the port.
        """
        if not port.is_open:
          raise AssertionError(f"Port [{port}] not open!")
        result = port.read_until(expected=s.encode('utf-8')).decode()
        info(f"_wait_for_string_on_uart read: [{result}]({len(result)})")

        # Short read likely resulting from a timeout.
        if len(result) < len(s):
            raise AssertionError(
                f"Timeout while reading on UART: Did not find string [{s}]!")

        if not result.endswith(s):
            raise AssertionError(
                "Wait for String on UART: " +
                f"Did not get string [{s}] from port! Got [{result}]")

    def set_timeout(self, timeout) -> None:
        """
        Sets the read/write timeouts for serial operations.

        Robot keyword. Can be called as Set Timeout.

        Arguments:
          timeout: float. The amount of time in seconds to wait for a
            read or write to complete.
        """
        self.timeout = float(timeout)
        if self.uarts['sc']:
            self.uarts['sc'].timeout = self.timeout
            self.uarts['sc'].write_timeout = self.timeout
        if self.uarts['smc']:
            self.uarts['smc'].timeout = self.timeout
            self.uarts['smc'].write_timeout = self.timeout

    def open_serial_ports(self) -> None:
        """
        Opens the UART ports to the FPGA and sets the default UART.

        For now, sets the default UART to the SMC side only.

        Robot keyword. Can be called as Open Serial Ports.
        """
        self.uarts['sc'] = OpenSerialPort(self.sc_uart,
                                          timeout=self.timeout,
                                          write_timeout=self.timeout,
                                          baudrate=115200)
        self.uarts['smc'] = OpenSerialPort(self.smc_uart,
                                           timeout=self.timeout,
                                           write_timeout=self.timeout,
                                           baudrate=115200)
        self.default_uart = self.uarts['smc']

    def close_serial_ports(self) -> None:
        """
        Closes previously opened UARTs to the FPGA.

        Robot keyword. Can be called as Close Serial Ports.

        Throws AssertionError if it was unable to close a port.
        """
        for name, port in self.uarts.items():
            port.close()
            if port.is_open:
                raise AssertionError(f"Port {name} did not close.")

    def write_line_to_uart(self, line, **kwargs) -> None:
        """
        Writes a given string to the default UART.

        Throws AssertionError if a timeout occurs, or if the echoed back
        characters don't match the given string.

        Robot keyword. Can be called as Write Line To UART.

        Arguments expected in kwargs:
          waitForEcho: boolean. Deafults to True. Whether or not to check
            echoed back characters against the given string.
        """
        if 'waitForEcho' in kwargs:
            self._write_line_to_uart(self.default_uart,
                                     line,
                                     wait_for_echo=kwargs['waitForEcho'])
        else:
            self._write_line_to_uart(self.default_uart, line)

    def wait_for_line_on_uart(self, s, **kwargs) -> None:
        """
        Waits for a given string on the default UART.

        This does not actually look for a newline in the output. The
        name is a misnomer and holdover from Renode terms.

        Throws AssertionError if a timeout occurs, or if the read
        characters don't match the given string.

        Robot keyword. Used as Wait For Line On UART.
        """
        self._wait_for_string_on_uart(self.default_uart, s)

    def wait_for_prompt_on_uart(self, prompt, *args) -> None:
        """
        Waits for the given prompt on the default UART.

        Robot keyword. Can be called as Wait For Prompt On UART.
        """
        self._wait_for_string_on_uart(self.default_uart, prompt)

    def execute_command(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding command `{args}`")

    def execute_script(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding script `{args}`")

    def set_default_uart_timeout(self, timeout, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding set default uart timeout `{args}`")

    def create_log_tester(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding log tester `{args}`")

    def run_process(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding run process `{args}`")

    def requires(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding requires `{args}`")

    def provides(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding provides `{args}`")

    def start_emulation(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding start emulation `{args}`")

    def create_terminal_tester(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding create terminal tester `{args}`")

    def wait_for_logentry(self, *args) -> None:
        """Renode-compatible do nothing keyword."""
        info(f"Eliding wait for logentry `{args}`")
