# Copyright (c) 2015 Stephen Warren
# Copyright (c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
#
# SPDX-License-Identifier: GPL-2.0

# Generate an HTML-formatted log file containing multiple streams of data,
# each represented in a well-delineated/-structured fashion.

import cgi
import os.path
import shutil
import subprocess

mod_dir = os.path.dirname(os.path.abspath(__file__))

class LogfileStream(object):
    """A file-like object used to write a single logical stream of data into
    a multiplexed log file. Objects of this type should be created by factory
    functions in the Logfile class rather than directly."""

    def __init__(self, logfile, name, chained_file):
        """Initialize a new object.

        Args:
            logfile: The Logfile object to log to.
            name: The name of this log stream.
            chained_file: The file-like object to which all stream data should be
            logged to in addition to logfile. Can be None.

        Returns:
            Nothing.
        """

        self.logfile = logfile
        self.name = name
        self.chained_file = chained_file

    def close(self):
        """Dummy function so that this class is "file-like".

        Args:
            None.

        Returns:
            Nothing.
        """

        pass

    def write(self, data, implicit=False):
        """Write data to the log stream.

        Args:
            data: The data to write tot he file.
            implicit: Boolean indicating whether data actually appeared in the
                stream, or was implicitly generated. A valid use-case is to
                repeat a shell prompt at the start of each separate log
                section, which makes the log sections more readable in
                isolation.

        Returns:
            Nothing.
        """

        self.logfile.write(self, data, implicit)
        if self.chained_file:
            self.chained_file.write(data)

    def flush(self):
        """Flush the log stream, to ensure correct log interleaving.

        Args:
            None.

        Returns:
            Nothing.
        """

        self.logfile.flush()
        if self.chained_file:
            self.chained_file.flush()

class RunAndLog(object):
    """A utility object used to execute sub-processes and log their output to
    a multiplexed log file. Objects of this type should be created by factory
    functions in the Logfile class rather than directly."""

    def __init__(self, logfile, name, chained_file):
        """Initialize a new object.

        Args:
            logfile: The Logfile object to log to.
            name: The name of this log stream or sub-process.
            chained_file: The file-like object to which all stream data should
                be logged to in addition to logfile. Can be None.

        Returns:
            Nothing.
        """

        self.logfile = logfile
        self.name = name
        self.chained_file = chained_file
        self.output = None

    def close(self):
        """Clean up any resources managed by this object."""
        pass

    def run(self, cmd, cwd=None, ignore_errors=False):
        """Run a command as a sub-process, and log the results.

        The output is available at self.output which can be useful if there is
        an exception.

        Args:
            cmd: The command to execute.
            cwd: The directory to run the command in. Can be None to use the
                current directory.
            ignore_errors: Indicate whether to ignore errors. If True, the
                function will simply return if the command cannot be executed
                or exits with an error code, otherwise an exception will be
                raised if such problems occur.

        Returns:
            The output as a string.
        """

        msg = '+' + ' '.join(cmd) + '\n'
        if self.chained_file:
            self.chained_file.write(msg)
        self.logfile.write(self, msg)

        try:
            p = subprocess.Popen(cmd, cwd=cwd,
                stdin=None, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            (stdout, stderr) = p.communicate()
            output = ''
            if stdout:
                if stderr:
                    output += 'stdout:\n'
                output += stdout
            if stderr:
                if stdout:
                    output += 'stderr:\n'
                output += stderr
            exit_status = p.returncode
            exception = None
        except subprocess.CalledProcessError as cpe:
            output = cpe.output
            exit_status = cpe.returncode
            exception = cpe
        except Exception as e:
            output = ''
            exit_status = 0
            exception = e
        if output and not output.endswith('\n'):
            output += '\n'
        if exit_status and not exception and not ignore_errors:
            exception = Exception('Exit code: ' + str(exit_status))
        if exception:
            output += str(exception) + '\n'
        self.logfile.write(self, output)
        if self.chained_file:
            self.chained_file.write(output)

        # Store the output so it can be accessed if we raise an exception.
        self.output = output
        if exception:
            raise exception
        return output

class SectionCtxMgr(object):
    """A context manager for Python's "with" statement, which allows a certain
    portion of test code to be logged to a separate section of the log file.
    Objects of this type should be created by factory functions in the Logfile
    class rather than directly."""

    def __init__(self, log, marker, anchor):
        """Initialize a new object.

        Args:
            log: The Logfile object to log to.
            marker: The name of the nested log section.
            anchor: The anchor value to pass to start_section().

        Returns:
            Nothing.
        """

        self.log = log
        self.marker = marker
        self.anchor = anchor

    def __enter__(self):
        self.anchor = self.log.start_section(self.marker, self.anchor)

    def __exit__(self, extype, value, traceback):
        self.log.end_section(self.marker)

class Logfile(object):
    """Generates an HTML-formatted log file containing multiple streams of
    data, each represented in a well-delineated/-structured fashion."""

    def __init__(self, fn):
        """Initialize a new object.

        Args:
            fn: The filename to write to.

        Returns:
            Nothing.
        """

        self.f = open(fn, 'wt')
        self.last_stream = None
        self.blocks = []
        self.cur_evt = 1
        self.anchor = 0

        shutil.copy(mod_dir + '/multiplexed_log.css', os.path.dirname(fn))
        self.f.write('''\
<html>
<head>
<link rel="stylesheet" type="text/css" href="multiplexed_log.css">
<script src="http://code.jquery.com/jquery.min.js"></script>
<script>
$(document).ready(function () {
    // Copy status report HTML to start of log for easy access
    sts = $(".block#status_report")[0].outerHTML;
    $("tt").prepend(sts);

    // Add expand/contract buttons to all block headers
    btns = "<span class=\\\"block-expand hidden\\\">[+] </span>" +
        "<span class=\\\"block-contract\\\">[-] </span>";
    $(".block-header").prepend(btns);

    // Pre-contract all blocks which passed, leaving only problem cases
    // expanded, to highlight issues the user should look at.
    // Only top-level blocks (sections) should have any status
    passed_bcs = $(".block-content:has(.status-pass)");
    // Some blocks might have multiple status entries (e.g. the status
    // report), so take care not to hide blocks with partial success.
    passed_bcs = passed_bcs.not(":has(.status-fail)");
    passed_bcs = passed_bcs.not(":has(.status-xfail)");
    passed_bcs = passed_bcs.not(":has(.status-xpass)");
    passed_bcs = passed_bcs.not(":has(.status-skipped)");
    // Hide the passed blocks
    passed_bcs.addClass("hidden");
    // Flip the expand/contract button hiding for those blocks.
    bhs = passed_bcs.parent().children(".block-header")
    bhs.children(".block-expand").removeClass("hidden");
    bhs.children(".block-contract").addClass("hidden");

    // Add click handler to block headers.
    // The handler expands/contracts the block.
    $(".block-header").on("click", function (e) {
        var header = $(this);
        var content = header.next(".block-content");
        var expanded = !content.hasClass("hidden");
        if (expanded) {
            content.addClass("hidden");
            header.children(".block-expand").first().removeClass("hidden");
            header.children(".block-contract").first().addClass("hidden");
        } else {
            header.children(".block-contract").first().removeClass("hidden");
            header.children(".block-expand").first().addClass("hidden");
            content.removeClass("hidden");
        }
    });

    // When clicking on a link, expand the target block
    $("a").on("click", function (e) {
        var block = $($(this).attr("href"));
        var header = block.children(".block-header");
        var content = block.children(".block-content").first();
        header.children(".block-contract").first().removeClass("hidden");
        header.children(".block-expand").first().addClass("hidden");
        content.removeClass("hidden");
    });
});
</script>
</head>
<body>
<tt>
''')

    def close(self):
        """Close the log file.

        After calling this function, no more data may be written to the log.

        Args:
            None.

        Returns:
            Nothing.
        """

        self.f.write('''\
</tt>
</body>
</html>
''')
        self.f.close()

    # The set of characters that should be represented as hexadecimal codes in
    # the log file.
    _nonprint = ('%' + ''.join(chr(c) for c in range(0, 32) if c not in (9, 10)) +
                 ''.join(chr(c) for c in range(127, 256)))

    def _escape(self, data):
        """Render data format suitable for inclusion in an HTML document.

        This includes HTML-escaping certain characters, and translating
        control characters to a hexadecimal representation.

        Args:
            data: The raw string data to be escaped.

        Returns:
            An escaped version of the data.
        """

        data = data.replace(chr(13), '')
        data = ''.join((c in self._nonprint) and ('%%%02x' % ord(c)) or
                       c for c in data)
        data = cgi.escape(data)
        return data

    def _terminate_stream(self):
        """Write HTML to the log file to terminate the current stream's data.

        Args:
            None.

        Returns:
            Nothing.
        """

        self.cur_evt += 1
        if not self.last_stream:
            return
        self.f.write('</pre>\n')
        self.f.write('<div class="stream-trailer block-trailer">End stream: ' +
                     self.last_stream.name + '</div>\n')
        self.f.write('</div>\n')
        self.f.write('</div>\n')
        self.last_stream = None

    def _note(self, note_type, msg, anchor=None):
        """Write a note or one-off message to the log file.

        Args:
            note_type: The type of note. This must be a value supported by the
                accompanying multiplexed_log.css.
            msg: The note/message to log.
            anchor: Optional internal link target.

        Returns:
            Nothing.
        """

        self._terminate_stream()
        self.f.write('<div class="' + note_type + '">\n')
        if anchor:
            self.f.write('<a href="#%s">\n' % anchor)
        self.f.write('<pre>')
        self.f.write(self._escape(msg))
        self.f.write('\n</pre>\n')
        if anchor:
            self.f.write('</a>\n')
        self.f.write('</div>\n')

    def start_section(self, marker, anchor=None):
        """Begin a new nested section in the log file.

        Args:
            marker: The name of the section that is starting.
            anchor: The value to use for the anchor. If None, a unique value
              will be calculated and used

        Returns:
            Name of the HTML anchor emitted before section.
        """

        self._terminate_stream()
        self.blocks.append(marker)
        if not anchor:
            self.anchor += 1
            anchor = str(self.anchor)
        blk_path = '/'.join(self.blocks)
        self.f.write('<div class="section block" id="' + anchor + '">\n')
        self.f.write('<div class="section-header block-header">Section: ' +
                     blk_path + '</div>\n')
        self.f.write('<div class="section-content block-content">\n')

        return anchor

    def end_section(self, marker):
        """Terminate the current nested section in the log file.

        This function validates proper nesting of start_section() and
        end_section() calls. If a mismatch is found, an exception is raised.

        Args:
            marker: The name of the section that is ending.

        Returns:
            Nothing.
        """

        if (not self.blocks) or (marker != self.blocks[-1]):
            raise Exception('Block nesting mismatch: "%s" "%s"' %
                            (marker, '/'.join(self.blocks)))
        self._terminate_stream()
        blk_path = '/'.join(self.blocks)
        self.f.write('<div class="section-trailer block-trailer">' +
                     'End section: ' + blk_path + '</div>\n')
        self.f.write('</div>\n')
        self.f.write('</div>\n')
        self.blocks.pop()

    def section(self, marker, anchor=None):
        """Create a temporary section in the log file.

        This function creates a context manager for Python's "with" statement,
        which allows a certain portion of test code to be logged to a separate
        section of the log file.

        Usage:
            with log.section("somename"):
                some test code

        Args:
            marker: The name of the nested section.
            anchor: The anchor value to pass to start_section().

        Returns:
            A context manager object.
        """

        return SectionCtxMgr(self, marker, anchor)

    def error(self, msg):
        """Write an error note to the log file.

        Args:
            msg: A message describing the error.

        Returns:
            Nothing.
        """

        self._note("error", msg)

    def warning(self, msg):
        """Write an warning note to the log file.

        Args:
            msg: A message describing the warning.

        Returns:
            Nothing.
        """

        self._note("warning", msg)

    def info(self, msg):
        """Write an informational note to the log file.

        Args:
            msg: An informational message.

        Returns:
            Nothing.
        """

        self._note("info", msg)

    def action(self, msg):
        """Write an action note to the log file.

        Args:
            msg: A message describing the action that is being logged.

        Returns:
            Nothing.
        """

        self._note("action", msg)

    def status_pass(self, msg, anchor=None):
        """Write a note to the log file describing test(s) which passed.

        Args:
            msg: A message describing the passed test(s).
            anchor: Optional internal link target.

        Returns:
            Nothing.
        """

        self._note("status-pass", msg, anchor)

    def status_skipped(self, msg, anchor=None):
        """Write a note to the log file describing skipped test(s).

        Args:
            msg: A message describing the skipped test(s).
            anchor: Optional internal link target.

        Returns:
            Nothing.
        """

        self._note("status-skipped", msg, anchor)

    def status_xfail(self, msg, anchor=None):
        """Write a note to the log file describing xfailed test(s).

        Args:
            msg: A message describing the xfailed test(s).
            anchor: Optional internal link target.

        Returns:
            Nothing.
        """

        self._note("status-xfail", msg, anchor)

    def status_xpass(self, msg, anchor=None):
        """Write a note to the log file describing xpassed test(s).

        Args:
            msg: A message describing the xpassed test(s).
            anchor: Optional internal link target.

        Returns:
            Nothing.
        """

        self._note("status-xpass", msg, anchor)

    def status_fail(self, msg, anchor=None):
        """Write a note to the log file describing failed test(s).

        Args:
            msg: A message describing the failed test(s).
            anchor: Optional internal link target.

        Returns:
            Nothing.
        """

        self._note("status-fail", msg, anchor)

    def get_stream(self, name, chained_file=None):
        """Create an object to log a single stream's data into the log file.

        This creates a "file-like" object that can be written to in order to
        write a single stream's data to the log file. The implementation will
        handle any required interleaving of data (from multiple streams) in
        the log, in a way that makes it obvious which stream each bit of data
        came from.

        Args:
            name: The name of the stream.
            chained_file: The file-like object to which all stream data should
                be logged to in addition to this log. Can be None.

        Returns:
            A file-like object.
        """

        return LogfileStream(self, name, chained_file)

    def get_runner(self, name, chained_file=None):
        """Create an object that executes processes and logs their output.

        Args:
            name: The name of this sub-process.
            chained_file: The file-like object to which all stream data should
                be logged to in addition to logfile. Can be None.

        Returns:
            A RunAndLog object.
        """

        return RunAndLog(self, name, chained_file)

    def write(self, stream, data, implicit=False):
        """Write stream data into the log file.

        This function should only be used by instances of LogfileStream or
        RunAndLog.

        Args:
            stream: The stream whose data is being logged.
            data: The data to log.
            implicit: Boolean indicating whether data actually appeared in the
                stream, or was implicitly generated. A valid use-case is to
                repeat a shell prompt at the start of each separate log
                section, which makes the log sections more readable in
                isolation.

        Returns:
            Nothing.
        """

        if stream != self.last_stream:
            self._terminate_stream()
            self.f.write('<div class="stream block">\n')
            self.f.write('<div class="stream-header block-header">Stream: ' +
                         stream.name + '</div>\n')
            self.f.write('<div class="stream-content block-content">\n')
            self.f.write('<pre>')
        if implicit:
            self.f.write('<span class="implicit">')
        self.f.write(self._escape(data))
        if implicit:
            self.f.write('</span>')
        self.last_stream = stream

    def flush(self):
        """Flush the log stream, to ensure correct log interleaving.

        Args:
            None.

        Returns:
            Nothing.
        """

        self.f.flush()
