# 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
        self.exit_status = 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
        self.exit_status = exit_status
        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')
        self.f.write('<pre>')
        if anchor:
            self.f.write('<a href="#%s">' % anchor)
        self.f.write(self._escape(msg))
        if anchor:
            self.f.write('</a>')
        self.f.write('\n</pre>\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()
