# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0

import difflib
import filecmp
import inspect
import logging
import os
import re
import select
import shlex
import signal
import subprocess
import time


class Process:
    """Utility class used to spawn an interact with processs.s"""
    def __init__(self,
                 cmd,
                 logdir,
                 cwd=None,
                 startup_done_expect=None,
                 startup_timeout=None):
        """Creates Process instance.

        Args:
            cmd: Command line argument used to spawn process.
            logdir: Directory used to store STDOUT and STDERR output.
            cwd: Working directory used to spawn process.
            startup_done_expect: Pattern used to check at process startup time.
            startup_timeout: Timeout in seconds for |startup_done_expect| check.
        """
        if isinstance(cmd, str):
            self.cmd = shlex.split(cmd)
        else:
            self.cmd = cmd
        self.logdir = logdir
        self.cwd = cwd
        self.startup_done_expect = startup_done_expect
        self.startup_timeout = startup_timeout
        self.proc = None
        self.logger = logging.getLogger(__name__)

        self._f_stdout = None
        self._f_stderr = None
        self._f_stdout_r = None
        self._f_stderr_r = None

    def __del__(self):
        try:
            self.proc.kill()
            self._f_stdout.close()
            self._f_stderr.close()
            self._f_stdout_r.close()
            self._f_stderr_r.close()
        except:
            pass

    def run(self):
        """Start process with command line configured in constructor."""
        cmd_name = os.path.basename(self.cmd[0])

        # Enforce line-buffered STDOUT even when sending STDOUT/STDERR to file.
        # If applications don't fflush() STDOUT manually, STDOUT goes through
        # a 4kB buffer before we see any output, which prevents searching for
        # the string indicating a successful startup.
        # see discussion at http://www.pixelbeat.org/programming/stdio_buffering/
        cmd = ['stdbuf', '-oL'] + self.cmd
        self.logger.info("Running command " + ' '.join(cmd))

        logfile_stdout = os.path.join(self.logdir,
                                      "{}.stdout".format(cmd_name))
        logfile_stderr = os.path.join(self.logdir,
                                      "{}.stderr".format(cmd_name))
        self.logger.debug("Capturing STDOUT at " + logfile_stdout)
        self.logger.debug("Capturing STDERR at " + logfile_stderr)

        self._f_stdout = open(logfile_stdout, 'w')
        self._f_stderr = open(logfile_stderr, 'w')
        self.proc = subprocess.Popen(cmd,
                                     cwd=self.cwd,
                                     universal_newlines=True,
                                     bufsize=1,
                                     stdin=subprocess.PIPE,
                                     stdout=self._f_stdout,
                                     stderr=self._f_stderr)

        self._f_stdout_r = open(logfile_stdout, 'r')
        self._f_stderr_r = open(logfile_stderr, 'r')

        # no startup match pattern given => startup done!
        if self.startup_done_expect == None:
            return True

        # check if the string indicating a successful startup appears in the
        # the program output (STDOUT or STDERR)
        init_done = self.find_in_output(pattern=self.startup_done_expect,
                                        timeout=self.startup_timeout)

        if init_done == None:
            raise subprocess.TimeoutExpired

        self.logger.info("Startup sequence matched, startup done.")

        return True

    def terminate(self):
        """Terminates process started by run call."""
        if not self.proc:
            return
        self.proc.terminate()

    def send_ctrl_c(self):
        """Sends SIGINT to process started by run call."""
        if not self.proc:
            return
        self.proc.send_signal(signal.SIGINT)

    def expect(self, stdin_data=None, pattern=None, timeout=None):
        """Write send to STDIN and check if the output is as expected.

        Args:
            stdin_data: Data to send to STDIN.
            pattern: Pattern to search for after sending |stdin_data|.
            timeout: Timeout in seconds for |pattern| check.
        Returns:
            True if |pattern| found, False otherwise.
        """
        # We don't get STDOUT/STDERR from subprocess.communicate() as it's
        # redirected to file. We need to read the files instead.

        # XXX: races (false positives) can happen here if output is generated
        # before the input is sent to the process.
        if pattern == None:
            self._f_stdout_r.seek(0, 2)

        self.proc.stdin.write(stdin_data)
        self.proc.stdin.flush()

        if pattern == None:
            return True

        return self.find_in_output(pattern, timeout) != None

    def find_in_output(self, pattern, timeout):
        """Read STDOUT and STDERR to find an expected pattern.

        Both streams are reset to the start of the stream before searching.
        pattern can be of two types:
        1. A regular expression (a re object). In this case, the pattern is
           matched against all lines and the result of re.match(pattern) is
           returned. Multi-line matches are not supported.
        2. A string. In this case pattern is compared to each line with
           startswith(), and the full matching line is returned on a match.
        If no match is found None is returned.
        timeout is given in seconds.

        Args:
            pattern: Pattern to search for in STDOUT or STDERR.
            timeout: Timeout in seconds for |pattern| check.
        Returns:
            String containing |pattern|, None otherwise.
        """

        if timeout != None:
            t_end = time.time() + timeout

        # reset streams
        self._f_stdout_r.seek(0)
        self._f_stderr_r.seek(0)

        while True:
            # check STDOUT as long as there is one
            i = 0
            for line in self._f_stdout_r:
                i += 1
                if hasattr(pattern, "match"):
                    m = pattern.match(line)
                    if m:
                        return m
                else:
                    if line.startswith(pattern):
                        return line

                # Check if we exceed the timeout while reading from STDOUT
                # do so only every 100 lines to reduce the performance impact.
                if timeout != None and i % 100 == 99 and time.time() >= t_end:
                    break

            # check STDERR as long as there is one
            i = 0
            for line in self._f_stderr_r:
                i += 1
                if hasattr(pattern, "match"):
                    m = pattern.match(line)
                    if m:
                        return m
                else:
                    if line.startswith(pattern):
                        return line

                # Check if we exceed the timeout while reading from STDERR
                # do so only every 100 lines to reduce the performance impact.
                if timeout != None and i % 100 == 99 and time.time() >= t_end:
                    break

            # wait for 200ms for new output
            if timeout != None:
                try:
                    self.proc.wait(timeout=0.2)
                except subprocess.TimeoutExpired:
                    pass

        return None


def stream_fd_to_log(fd, logger, pattern, timeout=None):
    """
    Streams lines from the given fd to log until pattern matches.

    Returns the match object derived from pattern.match(), or None if
    the timeout expires.
    """

    deadline = None
    if timeout != None:
        deadline = time.monotonic() + timeout

    os.set_blocking(fd, False)
    line_of_output = b''
    while True:
        curtime = time.monotonic()
        if deadline != None and curtime > deadline:
            return None

        if line_of_output.endswith(b'\n'):
            line_of_output = b''

        # select() on the fd so that we don't waste time reading when
        # we wouldn't get anything out of it.
        if deadline != None:
            rlist, _, _ = select.select([fd], [], [],
                                        deadline - curtime)
        else:
            rlist, _, _ = select.select([fd], [], [])

        if len(rlist) == 0:
            continue

        raw_bytes = os.read(fd, 1024)
        lines = raw_bytes.splitlines(True)

        for line in lines:
            line_of_output += line
            if not line_of_output.endswith(b'\n'):
                break

            logger.debug('fd#%d: %s' % (fd, line_of_output))
            match = pattern.match(line_of_output.decode('utf-8'))
            if match != None:
              return match

            line_of_output = b''

# If logfile option was given, log all outputs to file.
def setup_logfile(logger, logfile):
    if logfile:
        logger.debug("Logfile at %s" % (logfile))
        logger.setLevel(logging.DEBUG)
        fh = logging.FileHandler(filename=logfile, mode='w')
        fh.setLevel(logging.DEBUG)
        logger.addHandler(fh)
