# Copyright (C) 2013 Samsung Electronics. All rights reserved.
#
# Based on code from Chromium, copyright as follows:
#
# Copyright (c) 2013 The Chromium Authors. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#     * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from collections import defaultdict
import hashlib
import logging
import re
import subprocess
from xml.dom.minidom import parseString
from xml.parsers.expat import ExpatError

from webkitpy.common.unicode_compatibility import encode_if_necessary, decode_for

_log = logging.getLogger(__name__)


def get_text_of(top_node, name):
    """ Returns all text in all DOM nodes with a certain |name| that are children of |top_node|. """

    text = ""
    for nodes_named in top_node.getElementsByTagName(name):
        text += "".join([node.data for node in nodes_named.childNodes
                         if node.nodeType == node.TEXT_NODE])
    return text


def get_CDATA_of(top_node, name):
    """ Returns all CDATA in all DOM nodes with a certain |name| that are children of |top_node|. """

    text = ""
    for nodes_named in top_node.getElementsByTagName(name):
        text += "".join([node.data for node in nodes_named.childNodes
                         if node.nodeType == node.CDATA_SECTION_NODE])
    if (text == ""):
        return None
    return text


# Constants that give real names to the abbreviations in valgrind XML output.
INSTRUCTION_POINTER = "ip"
OBJECT_FILE = "obj"
FUNCTION_NAME = "fn"
SRC_FILE_DIR = "dir"
SRC_FILE_NAME = "file"
SRC_LINE = "line"


def gather_frames(node, source_dir):
    frame_dict = lambda frame: {
        INSTRUCTION_POINTER: get_text_of(frame, INSTRUCTION_POINTER),
        OBJECT_FILE: get_text_of(frame, OBJECT_FILE),
        FUNCTION_NAME: get_text_of(frame, FUNCTION_NAME),
        SRC_FILE_DIR: get_text_of(frame, SRC_FILE_DIR),
        SRC_FILE_NAME: get_text_of(frame, SRC_FILE_NAME),
        SRC_LINE: get_text_of(frame, SRC_LINE)}

    return [frame_dict(frame) for frame in node.getElementsByTagName("frame")]


class ValgrindError:

    def __init__(self, executive, source_dir, error_node):
        self._executive = executive
        self._kind = get_text_of(error_node, "kind")
        self._backtraces = []
        self._suppression = None
        self._additional = []

        # Iterate through the nodes, parsing <what|auxwhat><stack> pairs.
        description = None
        for node in error_node.childNodes:
            if node.localName == "what" or node.localName == "auxwhat":
                description = "".join([n.data for n in node.childNodes
                                       if n.nodeType == n.TEXT_NODE])
            elif node.localName == "xwhat":
                description = get_text_of(node, "text")
            elif node.localName == "stack":
                assert description
                self._backtraces.append([description, gather_frames(node, source_dir)])
                description = None
            elif node.localName == "origin":
                description = get_text_of(node, "what")
                stack = node.getElementsByTagName("stack")[0]
                frames = gather_frames(stack, source_dir)
                self._backtraces.append([description, frames])
                description = None
                stack = None
                frames = None
            elif description and node.localName != None:
                # The lastest description has no stack, e.g. "Address 0x28 is unknown".
                self._additional.append(description)
                description = None

            if node.localName == "suppression":
                self._suppression = get_CDATA_of(node, "rawtext")

    def __str__(self):
        output = self._kind + "\n"
        for backtrace in self._backtraces:
            output += backtrace[0] + "\n"

            buf = ""
            for frame in backtrace[1]:
                buf += (frame[FUNCTION_NAME] or frame[INSTRUCTION_POINTER]) + "\n"

            input = buf.encode('latin-1').split(b"\n")
            demangled_names = [self._executive.run_command(['c++filt', '-n', name]) for name in input if name]

            i = 0
            for frame in backtrace[1]:
                output += ("  " + demangled_names[i])
                i = i + 1

                if frame[SRC_FILE_DIR] != "":
                    output += (" (" + frame[SRC_FILE_DIR] + "/" + frame[SRC_FILE_NAME] +
                               ":" + frame[SRC_LINE] + ")")
                else:
                    output += " (" + frame[OBJECT_FILE] + ")"
                output += "\n"

        for additional in self._additional:
            output += additional + "\n"

        assert self._suppression != None, "Your Valgrind doesn't generate " \
                                           "suppressions - is it too old?"

        output += "Suppression (error hash=#%016X#):\n" % self.error_hash()

        # Widen the suppressions slightly.
        supp = self._suppression
        supp = supp.replace("fun:_Znwj", "fun:_Znw*")
        supp = supp.replace("fun:_Znwm", "fun:_Znw*")
        supp = supp.replace("fun:_Znaj", "fun:_Zna*")
        supp = supp.replace("fun:_Znam", "fun:_Zna*")

        # Split into lines so we can enforce length limits.
        supplines = supp.split("\n")
        supp = None  # to avoid re-use

        # Truncate at line 26 (VG_MAX_SUPP_CALLERS plus 2 for name and type)
        # (https://bugs.kde.org/show_bug.cgi?id=199468 proposes raising
        # VG_MAX_SUPP_CALLERS, but we're probably fine with it as is.)
        newlen = min(26, len(supplines))

        if (len(supplines) > newlen):
            supplines = supplines[0:newlen]
            supplines.append("}")

        for frame in range(len(supplines)):
            # Replace the always-changing anonymous namespace prefix with "*".
            m = re.match(r"( +fun:)_ZN.*_GLOBAL__N_.*\.cc_" +
                          "[0-9a-fA-F]{8}_[0-9a-fA-F]{8}(.*)",
                          supplines[frame])
            if m:
                supplines[frame] = "*".join(m.groups())

        return output + "\n".join(supplines) + "\n"

    def unique_string(self):
        rep = self._kind + " "
        for backtrace in self._backtraces:
            for frame in backtrace[1]:
                rep += frame[FUNCTION_NAME]

                if frame[SRC_FILE_DIR] != "":
                    rep += frame[SRC_FILE_DIR] + "/" + frame[SRC_FILE_NAME]
                else:
                    rep += frame[OBJECT_FILE]
        return rep

    def error_hash(self):
        # This is a device-independent hash identifying the suppression.
        # By printing out this hash we can find duplicate reports between tests and
        # different shards running on multiple buildbots
        return int(hashlib.md5(encode_if_necessary(self.unique_string())).hexdigest()[:16], 16)

    def __hash__(self):
        return hash(self.unique_string())

    def __eq__(self, rhs):
        return self.unique_string() == rhs


class LeakDetectorValgrind(object):

    def __init__(self, executive, filesystem, source_dir):
        self._executive = executive
        self._filesystem = filesystem
        self._source_dir = source_dir

        # Contains the set of unique errors.
        self._errors = set()
        # Contains all suppressions used.
        self._suppressions = defaultdict(int)

    def _parse_leaks_output(self, leaks_output):
        try:
            parsed_string = parseString(leaks_output)
        except ExpatError as e:
            parse_failed = True
            _log.error("could not parse %s: %s" % (decode_for(leaks_output, str), e))
            return

        cur_report_errors = set()

        commandline = None
        preamble = parsed_string.getElementsByTagName("preamble")[0]
        for node in preamble.getElementsByTagName("line"):
            if node.localName == "line":
                for x in node.childNodes:
                    if x.nodeType == node.TEXT_NODE and "Command" in x.data:
                        commandline = x.data
                        break

        raw_errors = parsed_string.getElementsByTagName("error")
        for raw_error in raw_errors:
            # Ignore "possible" leaks and InvalidRead/Write by default.
            if (get_text_of(raw_error, "kind") != "Leak_PossiblyLost") and \
                (get_text_of(raw_error, "kind") != "Leak_StillReachable") and \
                (get_text_of(raw_error, "kind") != "InvalidWrite") and \
                (get_text_of(raw_error, "kind") != "InvalidRead"):
                error = ValgrindError(self._executive, self._source_dir, raw_error)
                if error not in cur_report_errors:
                    # We haven't seen such errors doing this report yet...
                    if error in self._errors:
                        # ... but we saw it in earlier reports, e.g. previous UI test
                        cur_report_errors.add("This error was already printed in "
                                              "some other test, see 'hash=#%016X#'" % \
                            error.error_hash())
                    else:
                        # ... and we haven't seen it in other tests as well
                        self._errors.add(error)
                        cur_report_errors.add(error)

        suppcountlist = parsed_string.getElementsByTagName("suppcounts")
        if len(suppcountlist) > 0:
            suppcountlist = suppcountlist[0]
            for node in suppcountlist.getElementsByTagName("pair"):
                count = get_text_of(node, "count")
                name = get_text_of(node, "name")
                self._suppressions[name] += int(count)

        return cur_report_errors

    def leaks_files_in_results_directory(self):
        return self._filesystem.glob(self._filesystem.join(self._source_dir, "drt-*-leaks.xml"))

    def clean_leaks_files_from_results_directory(self):
        # Remove old Valgrind xml files before starting this run.
        leaks_files = self.leaks_files_in_results_directory()
        for f in leaks_files:
            self._filesystem.remove(f)

    def parse_and_print_leaks_detail(self, leaks_files):
        for f in leaks_files:
            leaks_output = self._filesystem.read_binary_file(f)
            detected_leaks = self._parse_leaks_output(leaks_output)

        _log.info("-----------------------------------------------------")
        _log.info("Suppressions used:")
        _log.info("  count name")
        for (name, count) in sorted(self._suppressions.items(), key=lambda pair: (pair[1], pair[0])):
            _log.info("%7d %s" % (count, name))
        _log.info("-----------------------------------------------------")

        if self._errors:
            _log.info("Valgrind detected %s leaks:" % len(self._errors))
            # Force the same order in Python 2 and Python 3
            for leak in sorted(self._errors, key=lambda error: error.unique_string()):
                _log.info(leak)
