#!/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 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()
