"""Class for printing reports on profiled python code."""

# Class for printing reports on profiled python code. rev 1.0  4/1/94
#
# Based on prior profile module by Sjoerd Mullender...
#   which was hacked somewhat by: Guido van Rossum
#
# see profile.doc and profile.py for more info.

# Copyright 1994, by InfoSeek Corporation, all rights reserved.
# Written by James Roskind
#
# Permission to use, copy, modify, and distribute this Python software
# and its associated documentation for any purpose (subject to the
# restriction in the following sentence) without fee is hereby granted,
# provided that the above copyright notice appears in all copies, and
# that both that copyright notice and this permission notice appear in
# supporting documentation, and that the name of InfoSeek not be used in
# advertising or publicity pertaining to distribution of the software
# without specific, written prior permission.  This permission is
# explicitly restricted to the copying and modification of the software
# to remain in Python, compiled Python, or other languages (such as C)
# wherein the modified or derived code is exclusively imported into a
# Python module.
#
# INFOSEEK CORPORATION DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
# SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
# FITNESS. IN NO EVENT SHALL INFOSEEK CORPORATION BE LIABLE FOR ANY
# SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
# RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
# CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
# CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.


import os
import time
import string
import marshal
import re

import fpformat

class Stats:
    """This class is used for creating reports from data generated by the
    Profile class.  It is a "friend" of that class, and imports data either
    by direct access to members of Profile class, or by reading in a dictionary
    that was emitted (via marshal) from the Profile class.

    The big change from the previous Profiler (in terms of raw functionality)
    is that an "add()" method has been provided to combine Stats from
    several distinct profile runs.  Both the constructor and the add()
    method now take arbitrarily many file names as arguments.

    All the print methods now take an argument that indicates how many lines
    to print.  If the arg is a floating point number between 0 and 1.0, then
    it is taken as a decimal percentage of the available lines to be printed
    (e.g., .1 means print 10% of all available lines).  If it is an integer,
    it is taken to mean the number of lines of data that you wish to have
    printed.

    The sort_stats() method now processes some additional options (i.e., in
    addition to the old -1, 0, 1, or 2).  It takes an arbitrary number of quoted
    strings to select the sort order.  For example sort_stats('time', 'name')
    sorts on the major key of "internal function time", and on the minor
    key of 'the name of the function'.  Look at the two tables in sort_stats()
    and get_sort_arg_defs(self) for more examples.

    All methods now return "self",  so you can string together commands like:
        Stats('foo', 'goo').strip_dirs().sort_stats('calls').\
                            print_stats(5).print_callers(5)
    """

    def __init__(self, *args):
        if not len(args):
            arg = None
        else:
            arg = args[0]
            args = args[1:]
        self.init(arg)
        apply(self.add, args).ignore()

    def init(self, arg):
        self.all_callees = None  # calc only if needed
        self.files = []
        self.fcn_list = None
        self.total_tt = 0
        self.total_calls = 0
        self.prim_calls = 0
        self.max_name_len = 0
        self.top_level = {}
        self.stats = {}
        self.sort_arg_dict = {}
        self.load_stats(arg)
        trouble = 1
        try:
            self.get_top_level_stats()
            trouble = 0
        finally:
            if trouble:
                print "Invalid timing data",
                if self.files: print self.files[-1],
                print


    def load_stats(self, arg):
        if not arg:  self.stats = {}
        elif type(arg) == type(""):
            f = open(arg, 'rb')
            self.stats = marshal.load(f)
            f.close()
            try:
                file_stats = os.stat(arg)
                arg = time.ctime(file_stats[8]) + "    " + arg
            except:  # in case this is not unix
                pass
            self.files = [ arg ]
        elif hasattr(arg, 'create_stats'):
            arg.create_stats()
            self.stats = arg.stats
            arg.stats = {}
        if not self.stats:
            raise TypeError,  "Cannot create or construct a " \
                      + `self.__class__` \
                      + " object from '" + `arg` + "'"
        return

    def get_top_level_stats(self):
        for func in self.stats.keys():
            cc, nc, tt, ct, callers = self.stats[func]
            self.total_calls = self.total_calls + nc
            self.prim_calls  = self.prim_calls  + cc
            self.total_tt    = self.total_tt    + tt
            if callers.has_key(("jprofile", 0, "profiler")):
                self.top_level[func] = None
            if len(func_std_string(func)) > self.max_name_len:
                self.max_name_len = len(func_std_string(func))

    def add(self, *arg_list):
        if not arg_list: return self
        if len(arg_list) > 1: apply(self.add, arg_list[1:])
        other = arg_list[0]
        if type(self) != type(other) or \
                  self.__class__ != other.__class__:
            other = Stats(other)
        self.files = self.files + other.files
        self.total_calls = self.total_calls + other.total_calls
        self.prim_calls = self.prim_calls + other.prim_calls
        self.total_tt = self.total_tt + other.total_tt
        for func in other.top_level.keys():
            self.top_level[func] = None

        if self.max_name_len < other.max_name_len:
            self.max_name_len = other.max_name_len

        self.fcn_list = None

        for func in other.stats.keys():
            if self.stats.has_key(func):
                old_func_stat = self.stats[func]
            else:
                old_func_stat = (0, 0, 0, 0, {},)
            self.stats[func] = add_func_stats(old_func_stat, \
                      other.stats[func])
        return self



    # list the tuple indices and directions for sorting,
    # along with some printable description
    sort_arg_dict_default = {\
              "calls"     : (((1,-1),              ), "call count"),\
              "cumulative": (((3,-1),              ), "cumulative time"),\
              "file"      : (((4, 1),              ), "file name"),\
              "line"      : (((5, 1),              ), "line number"),\
              "module"    : (((4, 1),              ), "file name"),\
              "name"      : (((6, 1),              ), "function name"),\
              "nfl"       : (((6, 1),(4, 1),(5, 1),), "name/file/line"), \
              "pcalls"    : (((0,-1),              ), "call count"),\
              "stdname"   : (((7, 1),              ), "standard name"),\
              "time"      : (((2,-1),              ), "internal time"),\
              }

    def get_sort_arg_defs(self):
        """Expand all abbreviations that are unique."""
        if not self.sort_arg_dict:
            self.sort_arg_dict = dict = {}
            std_list = dict.keys()
            bad_list = {}
            for word in self.sort_arg_dict_default.keys():
                fragment = word
                while fragment:
                    if not fragment:
                        break
                    if dict.has_key(fragment):
                        bad_list[fragment] = 0
                        break
                    dict[fragment] = self. \
                              sort_arg_dict_default[word]
                    fragment = fragment[:-1]
            for word in bad_list.keys():
                del dict[word]
        return self.sort_arg_dict


    def sort_stats(self, *field):
        if not field:
            self.fcn_list = 0
            return self
        if len(field) == 1 and type(field[0]) == type(1):
            # Be compatible with old profiler
            field = [ {-1: "stdname", \
                      0:"calls", \
                      1:"time", \
                      2: "cumulative" }  [ field[0] ] ]

        sort_arg_defs = self.get_sort_arg_defs()
        sort_tuple = ()
        self.sort_type = ""
        connector = ""
        for word in field:
            sort_tuple = sort_tuple + sort_arg_defs[word][0]
            self.sort_type = self.sort_type + connector + \
                      sort_arg_defs[word][1]
            connector = ", "

        stats_list = []
        for func in self.stats.keys():
            cc, nc, tt, ct, callers = self.stats[func]
            stats_list.append((cc, nc, tt, ct) + func_split(func) \
                               + (func_std_string(func), func,)  )

        stats_list.sort(TupleComp(sort_tuple).compare)

        self.fcn_list = fcn_list = []
        for tuple in stats_list:
            fcn_list.append(tuple[-1])
        return self


    def reverse_order(self):
        if self.fcn_list: self.fcn_list.reverse()
        return self

    def strip_dirs(self):
        oldstats = self.stats
        self.stats = newstats = {}
        max_name_len = 0
        for func in oldstats.keys():
            cc, nc, tt, ct, callers = oldstats[func]
            newfunc = func_strip_path(func)
            if len(func_std_string(newfunc)) > max_name_len:
                max_name_len = len(func_std_string(newfunc))
            newcallers = {}
            for func2 in callers.keys():
                newcallers[func_strip_path(func2)] = \
                          callers[func2]

            if newstats.has_key(newfunc):
                newstats[newfunc] = add_func_stats( \
                          newstats[newfunc],\
                          (cc, nc, tt, ct, newcallers))
            else:
                newstats[newfunc] = (cc, nc, tt, ct, newcallers)
        old_top = self.top_level
        self.top_level = new_top = {}
        for func in old_top.keys():
            new_top[func_strip_path(func)] = None

        self.max_name_len = max_name_len

        self.fcn_list = None
        self.all_callees = None
        return self



    def calc_callees(self):
        if self.all_callees: return
        self.all_callees = all_callees = {}
        for func in self.stats.keys():
            if not all_callees.has_key(func):
                all_callees[func] = {}
            cc, nc, tt, ct, callers = self.stats[func]
            for func2 in callers.keys():
                if not all_callees.has_key(func2):
                    all_callees[func2] = {}
                all_callees[func2][func]  = callers[func2]
        return

    #******************************************************************
    # The following functions support actual printing of reports
    #******************************************************************

    # Optional "amount" is either a line count, or a percentage of lines.

    def eval_print_amount(self, sel, list, msg):
        new_list = list
        if type(sel) == type(""):
            new_list = []
            for func in list:
                if re.search(sel, func_std_string(func)):
                    new_list.append(func)
        else:
            count = len(list)
            if type(sel) == type(1.0) and 0.0 <= sel < 1.0:
                count = int (count * sel + .5)
                new_list = list[:count]
            elif type(sel) == type(1) and 0 <= sel < count:
                count = sel
                new_list = list[:count]
        if len(list) != len(new_list):
            msg = msg + "   List reduced from " + `len(list)` \
                      + " to " + `len(new_list)` + \
                      " due to restriction <" + `sel` + ">\n"

        return new_list, msg



    def get_print_list(self, sel_list):
        width = self.max_name_len
        if self.fcn_list:
            list = self.fcn_list[:]
            msg = "   Ordered by: " + self.sort_type + '\n'
        else:
            list = self.stats.keys()
            msg = "   Random listing order was used\n"

        for selection in sel_list:
            list,msg = self.eval_print_amount(selection, list, msg)

        count = len(list)

        if not list:
            return 0, list
        print msg
        if count < len(self.stats):
            width = 0
            for func in list:
                if  len(func_std_string(func)) > width:
                    width = len(func_std_string(func))
        return width+2, list

    def print_stats(self, *amount):
        for filename in self.files:
            print filename
        if self.files: print
        indent = "        "
        for func in self.top_level.keys():
            print indent, func_get_function_name(func)

        print  indent, self.total_calls, "function calls",
        if self.total_calls != self.prim_calls:
            print "(" + `self.prim_calls`, "primitive calls)",
        print "in", fpformat.fix(self.total_tt, 3), "CPU seconds"
        print
        width, list = self.get_print_list(amount)
        if list:
            self.print_title()
            for func in list:
                self.print_line(func)
            print
            print
        return self


    def print_callees(self, *amount):
        width, list = self.get_print_list(amount)
        if list:
            self.calc_callees()

            self.print_call_heading(width, "called...")
            for func in list:
                if self.all_callees.has_key(func):
                    self.print_call_line(width, \
                              func, self.all_callees[func])
                else:
                    self.print_call_line(width, func, {})
            print
            print
        return self

    def print_callers(self, *amount):
        width, list = self.get_print_list(amount)
        if list:
            self.print_call_heading(width, "was called by...")
            for func in list:
                cc, nc, tt, ct, callers = self.stats[func]
                self.print_call_line(width, func, callers)
            print
            print
        return self

    def print_call_heading(self, name_size, column_title):
        print string.ljust("Function ", name_size) + column_title


    def print_call_line(self, name_size, source, call_dict):
        print string.ljust(func_std_string(source), name_size),
        if not call_dict:
            print "--"
            return
        clist = call_dict.keys()
        clist.sort()
        name_size = name_size + 1
        indent = ""
        for func in clist:
            name = func_std_string(func)
            print indent*name_size + name + '(' \
                      + `call_dict[func]`+')', \
                      f8(self.stats[func][3])
            indent = " "



    def print_title(self):
        print string.rjust('ncalls', 9),
        print string.rjust('tottime', 8),
        print string.rjust('percall', 8),
        print string.rjust('cumtime', 8),
        print string.rjust('percall', 8),
        print 'filename:lineno(function)'


    def print_line(self, func):  # hack : should print percentages
        cc, nc, tt, ct, callers = self.stats[func]
        c = `nc`
        if nc != cc:
            c = c + '/' + `cc`
        print string.rjust(c, 9),
        print f8(tt),
        if nc == 0:
            print ' '*8,
        else:
            print f8(tt/nc),
        print f8(ct),
        if cc == 0:
            print ' '*8,
        else:
            print f8(ct/cc),
        print func_std_string(func)


    def ignore(self):
        pass # has no return value, so use at end of line :-)


class TupleComp:
    """This class provides a generic function for comparing any two tuples.
    Each instance records a list of tuple-indices (from most significant
    to least significant), and sort direction (ascending or decending) for
    each tuple-index.  The compare functions can then be used as the function
    argument to the system sort() function when a list of tuples need to be
    sorted in the instances order."""

    def __init__(self, comp_select_list):
        self.comp_select_list = comp_select_list

    def compare (self, left, right):
        for index, direction in self.comp_select_list:
            l = left[index]
            r = right[index]
            if l < r:
                return -direction
            if l > r:
                return direction
        return 0



#**************************************************************************

def func_strip_path(func_name):
    file, line, name = func_name
    return os.path.basename(file), line, name

def func_get_function_name(func):
    return func[2]

def func_std_string(func_name): # match what old profile produced
    file, line, name = func_name
    return file + ":" + `line` + "(" + name + ")"

def func_split(func_name):
    return func_name

#**************************************************************************
# The following functions combine statists for pairs functions.
# The bulk of the processing involves correctly handling "call" lists,
# such as callers and callees.
#**************************************************************************

def add_func_stats(target, source):
    """Add together all the stats for two profile entries."""
    cc, nc, tt, ct, callers = source
    t_cc, t_nc, t_tt, t_ct, t_callers = target
    return (cc+t_cc, nc+t_nc, tt+t_tt, ct+t_ct, \
              add_callers(t_callers, callers))


def add_callers(target, source):
    """Combine two caller lists in a single list."""
    new_callers = {}
    for func in target.keys():
        new_callers[func] = target[func]
    for func in source.keys():
        if new_callers.has_key(func):
            new_callers[func] = source[func] + new_callers[func]
        else:
            new_callers[func] = source[func]
    return new_callers

def count_calls(callers):
    """Sum the caller statistics to get total number of calls received."""
    nc = 0
    for func in callers.keys():
        nc = nc + callers[func]
    return nc

#**************************************************************************
# The following functions support printing of reports
#**************************************************************************

def f8(x):
    return string.rjust(fpformat.fix(x, 3), 8)
