#!/usr/bin/python
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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
#
#   http://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.
#

#
# a tool for post-processing Valgrind output from the unit tests
# Use:
#    1) configure the build to use valgrind and output xml
#       $ cmake .. -DUSE_VALGRIND=Yes -DVALGRIND_XML=Yes
#    2) build and run the unit tests
#       $ make && make test
#    3) run grinder from your build directory.  It will look for valgrind xml
#       files named "valgrind-*.xml in the current directory and all
#       subdirectories and process them. Output is sent to stdout
#       $ ../bin/grinder
#
# Note: be sure to clean the build directory before running the unit tests
# to remove old valgrind-*.xml files
#

import logging
import os
import re
import sys
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import ParseError


class Frame(object):
    """
    Represents info for a single stack frame
    """
    FIELDS = ["fn", "dir", "file", "line"]
    def __init__(self, frame):
        self._fields = dict()
        for tag in self.FIELDS:
            _ = frame.find(tag)
            self._fields[tag] = _.text if _ is not None else "<none>"

    def __str__(self):
        return ("(%s) %s/%s:%s" %
                (self._fields['fn'],
                 self._fields['dir'],
                 self._fields['file'],
                 self._fields['line']))

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


class ErrorBase(object):
    """
    Base class representing a single valgrind error
    """
    def __init__(self, kind):
        self.kind = kind
        self.count = 1

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

    def __str__(self):
        return "kind = %s  (count=%d)" % (self.kind, self.count)

    def merge(self, other):
        self.count += other.count

    def __lt__(self, other):
        return self.count < other.count
    def __le__(self, other):
        return self.count <= other.count
    def __eq__(self, other):
        return self.count == other.count
    def __gt__(self, other):
        return self.count > other.count
    def __ge__(self, other):
        return self.count >= other.count


class GeneralError(ErrorBase):
    """
    For simple single stack errors
    """
    def __init__(self, error_xml):
        kind = error_xml.find("kind").text
        super(GeneralError, self).__init__(kind)
        w = error_xml.find("what")
        self._what = w.text if w is not None else "<none>"

        # stack
        self._stack = list()
        s = error_xml.find("stack")
        for frame in s.findall("frame"):
            self._stack.append(Frame(frame))

    def __hash__(self):
        h = super(GeneralError, self).__hash__()
        for f in self._stack:
            h += hash(f)
        return h

    def __str__(self):
        s = super(GeneralError, self).__str__() + "\n"
        if self._what:
            s += self._what + "\n"
        s += "Stack:"
        for frame in self._stack:
            s += "\n  %s" % str(frame)
        return s


class LeakError(ErrorBase):
    def __init__(self, error_xml):
        kind = error_xml.find("kind").text
        assert(kind.startswith("Leak_"))
        super(LeakError, self).__init__(kind)
        self._leaked_bytes = 0
        self._leaked_blocks = 0
        self._stack = list()

        # xwhat:
        #    leakedbytes
        #    leakedblocks
        lb = error_xml.find("xwhat/leakedbytes")
        if lb is not None:
            self._leaked_bytes = int(lb.text)
        lb = error_xml.find("xwhat/leakedblocks")
        if lb is not None:
            self._leaked_blocks = int(lb.text)

        # stack
        s = error_xml.find("stack")
        for frame in s.findall("frame"):
            self._stack.append(Frame(frame))

    def merge(self, other):
        super(LeakError, self).merge(other)
        self._leaked_bytes += other._leaked_bytes
        self._leaked_blocks += other._leaked_blocks

    def __hash__(self):
        h = super(LeakError, self).__hash__()
        for f in self._stack:
            h += hash(f)
        return h

    def __str__(self):
        s = super(LeakError, self).__str__() + "\n"
        s += "Leaked Bytes = %d Blocks = %d\n" % (self._leaked_bytes,
                                                  self._leaked_blocks)
        s += "Stack:"
        for frame in self._stack:
            s += "\n  %s" % str(frame)
        return s


class InvalidMemError(ErrorBase):
    def __init__(self, error_xml):
        kind = error_xml.find("kind").text
        super(InvalidMemError, self).__init__(kind)
        # expect
        #  what
        #  stack  (invalid access)
        #  followed by zero or more:
        #      aux what  (aux stack description)
        #      aux stack  (where alloced, freed)
        self._what = "<none>"
        self._stack = None
        self._auxwhat = list()
        self._aux_stacks = list()
        for child in error_xml:
            if child.tag == "what":
                self._what = child.text
            if child.tag == "auxwhat":
                self._auxwhat.append(child.text)
            if child.tag == "stack":
                stack = list()
                for frame in child.findall("frame"):
                    stack.append(Frame(frame))
                if self._stack == None:
                    self._stack = stack
                else:
                    self._aux_stacks.append(stack)

    def __hash__(self):
        # for now don't include what/auxwhat as it may
        # be different for the same codepath
        h = super(InvalidMemError, self).__hash__()
        for f in self._stack:
            h += hash(f)
        for s in self._aux_stacks:
            for f in s:
                h += hash(f)
        return h

    def __str__(self):
        s = super(InvalidMemError, self).__str__() + "\n"
        s += "%s\n" % self._what
        s += "Stack:"
        for frame in self._stack:
            s += "\n  %s" % str(frame)

        for what, stack in zip(self._auxwhat, self._aux_stacks):
            s += "\n%s:" % what
            for frame in stack:
                s += "\n  %s" % str(frame)
        return s


class SignalError(ErrorBase):
    def __init__(self, error_xml):
        super(SignalError, self).__init__("FatalSignal")
        # expects:
        #  signo
        #  signame
        #  stack
        self._signo = "<none>"
        sn = error_xml.find("signo")
        if sn is not None:
            self._signo = sn.text
        self._signame = "<none>"
        sn = error_xml.find("signame")
        if sn is not None:
            self._signame = sn.text

        self._stack = list()
        s = error_xml.find("stack")
        for frame in s.findall("frame"):
            self._stack.append(Frame(frame))

    def __hash__(self):
        # for now don't include what/auxwhat as it may
        # be different for the same codepath
        h = super(SignalError, self).__hash__()
        h += hash(self._signo)
        h += hash(self._signame)
        for f in self._stack:
            h += hash(f)
        return h

    def __str__(self):
        s = super(SignalError, self).__str__() + "\n"
        s += "Signal %s (%s)\n" % (self._signo, self._signame)
        s += "Stack:"
        for frame in self._stack:
            s += "\n  %s" % str(frame)
        return s


_ERROR_CLASSES = {
    'InvalidRead':         InvalidMemError,
    'InvalidWrite':        InvalidMemError,
    'Leak_DefinitelyLost': LeakError,
    'Leak_IndirectlyLost': LeakError,
    'Leak_PossiblyLost':   LeakError,
    'Leak_StillReachable': LeakError,
    'UninitCondition':     GeneralError,
    'SyscallParam':        GeneralError,
    'InvalidFree':         InvalidMemError,
    'FishyValue':          InvalidMemError,
    # TBD:
    'InvalidJump': None,
    'UninitValue': None,
}


def parse_error(error_xml):
    """
    Factory that returns an Error instance
    """
    kind = error_xml.find("kind").text
    e_cls = _ERROR_CLASSES.get(kind)
    if e_cls:
        return e_cls(error_xml)
    raise Exception("Unsupported error type %s, please update grinder"
                    " to handle it" % kind)


def parse_xml_file(filename, exe_name='qdrouterd'):
    """
    Parse out errors from a valgrind output xml file
    """
    logging.debug("Parsing %s", filename)
    error_list = list()
    try:
        root = ET.parse(filename).getroot()
    except ParseError as exc:
        if "no element found" not in str(exc):
            logging.warning("Error parsing %s: %s - skipping",
                            filename, str(exc))
        else:
            logging.debug("No errors found in: %s - skipping",
                          filename)
        return error_list

    pv = root.find('protocolversion')
    if pv is None or not "4" == pv.text:
        # unsupported xml format version
        logging.warning("Unsupported format version for %s, skipping...",
                      filename)
        return error_list

    pt = root.find('protocoltool')
    if pt is None or not "memcheck" == pt.text:
        logging.warning("Not a memcheck file %s, skipping...",
                        filename)
        return error_list

    if not exe_name in root.find('args/argv/exe').text:
        # not from the target executable, skip
        logging.debug("file %s is not generated from %s, skipping...",
                      filename, exe_name)
        return error_list

    for error in root.findall('error'):
        error_list.append(parse_error(error))

    # sigabort, etc classified as fatal_signal
    for signal in root.findall("fatal_signal"):
        error_list.append(SignalError(signal))
    return error_list


def main():
    errors_map = dict()
    file_name = re.compile("valgrind-[0-9]+\.xml")
    for dp, dn, fn in os.walk("."):
        for name in fn:
            if file_name.match(name):
                errors = parse_xml_file(os.path.join(dp, name))
                for e in errors:
                    h = hash(e)
                    if h in errors_map:
                        # coalesce duplicate errors
                        errors_map[h].merge(e)
                    else:
                        errors_map[h] = e

    # sort by # of occurances
    error_list = sorted([e for e in errors_map.values()], reverse=True)

    if error_list:
        for e in error_list:
            print("\n-----")
            print("%s" % str(e))
        print("\n\n-----")
        print("----- %s total issues detected" % len(error_list))
        print("-----")
    else:
        print("No Valgrind errors found! Congratulations ;)")


if __name__ == "__main__":
    sys.exit(main())
