#! /usr/bin/python

# Copyright (C) 2019 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.
#
# THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 re
import sys

icStatRecord = re.compile(r" +(\w+)\(([^,]+), ([^)]+)\)([^:]*): (\d+)")
getByIdPrefix = "OperationGetById"
putByIdPrefix = "OperationPutById"


class ICStats:
    def __init__(self):
        self.combinedRecords = {}
        self.slowGetById = {}
        self.slowPutById = {}
        self.totalSlowGetById = 0
        self.totalSlowPutById = 0

    def parse(self, file):
        for line in file:
            match = re.match(icStatRecord, line)
            if match:
                operation = match.group(1)
                base = match.group(2)
                property = match.group(3)
                location = match.group(4).strip()
                count = int(match.group(5))
                recordKey = (operation, base, property, location)

                if recordKey not in self.combinedRecords:
                    self.combinedRecords[recordKey] = count
                else:
                    self.combinedRecords[recordKey] += count

                if operation.startswith(getByIdPrefix):
                    self.totalSlowGetById += count

                    slowGetByIdKey = (base, property)
                    if slowGetByIdKey not in self.slowGetById:
                        self.slowGetById[slowGetByIdKey] = count
                    else:
                        self.slowGetById[slowGetByIdKey] += count

                elif operation.startswith(putByIdPrefix):
                    self.totalSlowPutById += count

                    slowPutByIdKey = (base, property)
                    if slowPutByIdKey not in self.slowPutById:
                        self.slowPutById[slowPutByIdKey] = count
                    else:
                        self.slowPutById[slowPutByIdKey] += count

    def dumpStats(self):
        print("Total Slow getById = {0:>13,d}".format(self.totalSlowGetById))
        print("Total Slow putById = {0:>13,d}".format(self.totalSlowPutById))

        print("Operation                            Base                  Property                              Location          Count  % tot")
        print("-----------------------------------  --------------------  ------------------------------------  ------------  ---------   slow")

        keys = sorted(self.combinedRecords.keys(), key=lambda t: self.combinedRecords[t], reverse=True)
        for key in keys:
            count = self.combinedRecords[key]
            operation = key[0]
            base = key[1]
            property = key[2]

            if operation.startswith(getByIdPrefix):
                slowPercent = "  {0:>4.1f}%".format(float(self.slowGetById[(base, property)] * 100) / float(self.totalSlowGetById))
            elif operation.startswith(putByIdPrefix):
                slowPercent = "  {0:>4.1f}%".format(float(self.slowPutById[(base, property)] * 100) / float(self.totalSlowPutById))
            else:
                slowPercent = ""

            if len(property) > 36:
                property = property[0:32] + "..."

            print("{0:35}  {1:20}  {2:36}  {3:12}  {4:>9d}{5}".format(operation[0:34], base, property, key[3], count, slowPercent))


def usage():
    print("Usage: {0} [ic-stats-file]".format(sys.argv[0]))
    print("        Where <ic-stats-file> is the results of using the useICStats option.")
    exit(1)

if __name__ == "__main__":
    if len(sys.argv) > 1:
        if sys.argv[1] == "-h" or sys.argv[1].lower() == "--help" or sys.argv[1] == "-?":
            usage()
        try:
            file = open(sys.argv[1], "r")
        except IOError as e:
            print("Couldn't open {0}, {1}".format(sys.argv[1], e.strerror))
            usage()
        except:
            print("Unexpected error:", sys.exc_info()[0])
            usage()
    else:
        file = sys.stdin

    icStats = ICStats()
    icStats.parse(file)
    icStats.dumpStats()
