#!/usr/bin/env python
#
# Copyright (C) 2011 Apple Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# 1.  Redistributions of source code must retain the above copyright
#     notice, this list of conditions and the following disclaimer.
# 2.  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.
# 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
#     its contributors may be used to endorse or promote products derived
#     from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY APPLE AND ITS 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 APPLE OR ITS 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.

import sys
import getopt
from optparse import OptionParser

oneK = 1024
oneM = 1024 * 1024
oneG = 1024 * 1024 * 1024

hotspot = False
scaleSize = True
showBars = True

def byteString(bytes):
    if scaleSize:
        format = '  %4d   '
        val = bytes

        if bytes >= oneG:
            format = '%8.1fG'
            val = float(bytes) / oneG
        elif bytes >= oneM:
            format = '%8.1fM'
            val = float(bytes) / oneM
        elif bytes >= oneK:
            format = '%8.1fK'
            val = float(bytes) / oneK

        return format % val
    if hotspot:
        return '%d' % bytes
    return '%12d' % bytes

class Node:
    def __init__(self, name, level = 0, bytes = 0):
        self.name = name
        self.level = level
        self.children = {}
        self.totalBytes = bytes

    def hasChildren(self):
        return len(self.children) > 0

    def getChild(self, name):
        if not name in self.children:
            newChild = Node(name, self.level + 1)
            self.children[name] = newChild

        return self.children[name]

    def getBytes(self):
        return self.totalBytes

    def addBytes(self, bytes):
        self.totalBytes = self.totalBytes + bytes

    def processLine(self, bytes, line):
        sep = line.find('|')
        if sep < 0:
            childName = line.strip()
            line = ''
        else:
            childName = line[:sep].strip()
            line = line[sep+1:]

        child = self.getChild(childName)
        child.addBytes(bytes)

        if len(line) > 0:
            child.processLine(bytes, line)

    def printNode(self, prefix = ' '):
        global hotspot
        global scaleSize
        global showBars

        if self.hasChildren():
            byteStr = byteString(self.totalBytes)

            if hotspot:
                print('    %s%s %s' % (self.level * ' ', byteString(self.totalBytes), self.name))
            else:
                print('%s %s%s' % (byteString(self.totalBytes), prefix[:-1], self.name))

            sortedChildren = sorted(self.children.values(), key=sortKeyByBytes, reverse=True)

            if showBars and len(self.children) > 1:
                newPrefix = prefix + '|'
            else:
                newPrefix = prefix + ' '

            childrenLeft = len(sortedChildren)
            for child in sortedChildren:
                if childrenLeft <= 1:
                    newPrefix = prefix + ' '
                else:
                    childrenLeft = childrenLeft - 1
                child.printNode(newPrefix)
        else:
            byteStr = byteString(self.totalBytes)

            if hotspot:
                print('    %s%s %s' % (self.level * ' ', byteString(self.totalBytes), self.name))
            else:
                print('%s %s%s' % (byteString(self.totalBytes), prefix[:-1], self.name))

def sortKeyByBytes(node):
    return node.getBytes();

def main():
    global hotspot
    global scaleSize
    global showBars

    # parse command line options
    parser = OptionParser(usage='malloc-tree [options] [malloc_history-file]',
                          description='Format malloc_history output as a nested tree',
                          epilog='stdin used if malloc_history-file is missing')

    parser.add_option('-n', '--nobars', action='store_false', dest='showBars',
                      default=True, help='don\'t show bars lining up siblings in tree');
    parser.add_option('-b', '--size-in-bytes', action='store_false', dest='scaleSize',
                      default=None, help='show sizes in bytes');
    parser.add_option('-s', '--size-scale', action='store_true', dest='scaleSize',
                      default=None, help='show sizes with appropriate scale suffix [K,M,G]');
    parser.add_option('-t', '--hotspot', action='store_true', dest='hotspot',
                      default=False, help='output in HotSpotFinder format, implies -b');

    (options, args) = parser.parse_args()

    hotspot = options.hotspot
    if options.scaleSize is None:
        if hotspot:
            scaleSize = False
        else:
            scaleSize = True
    else:
        scaleSize = options.scaleSize
    showBars = options.showBars

    if len(args) < 1:
        inputFile = sys.stdin
    else:
        inputFile = open(args[0], "r")

    line = inputFile.readline()

    rootNodes = {}

    while line:
        firstSep = line.find('|')
        if firstSep > 0:
            firstPart = line[:firstSep].strip()
            lineRemain = line[firstSep+1:]
            bytesSep = firstPart.find('bytes:')
            if bytesSep >= 0:
                name = firstPart[bytesSep+7:]
                stats = firstPart.split(' ')
                bytes = int(stats[3].replace(',', ''))

                if not name in rootNodes:
                    node = Node(name, 0, bytes);
                    rootNodes[name] = node
                else:
                    node = rootNodes[name]
                    node.addBytes(bytes)

                node.processLine(bytes, lineRemain)

        line = inputFile.readline()

    sortedRootNodes = sorted(rootNodes.values(), key=sortKeyByBytes, reverse=True)

    print 'Call graph:'
    try:
        for node in sortedRootNodes:
            node.printNode()
            print
    except:
        pass

if __name__ == "__main__":
    main()
