#!/usr/bin/python2
# call-graph-from-postgresql.py: create call-graph from postgresql database
# Copyright (c) 2014, Intel Corporation.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms and conditions of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
# more details.

# To use this script you will need to have exported data using the
# export-to-postgresql.py script.  Refer to that script for details.
#
# Following on from the example in the export-to-postgresql.py script, a
# call-graph can be displayed for the pt_example database like this:
#
#	python tools/perf/scripts/python/call-graph-from-postgresql.py pt_example
#
# Note this script supports connecting to remote databases by setting hostname,
# port, username, password, and dbname e.g.
#
#	python tools/perf/scripts/python/call-graph-from-postgresql.py "hostname=myhost username=myuser password=mypassword dbname=pt_example"
#
# The result is a GUI window with a tree representing a context-sensitive
# call-graph.  Expanding a couple of levels of the tree and adjusting column
# widths to suit will display something like:
#
#                                         Call Graph: pt_example
# Call Path                          Object      Count   Time(ns)  Time(%)  Branch Count   Branch Count(%)
# v- ls
#     v- 2638:2638
#         v- _start                  ld-2.19.so    1     10074071   100.0         211135            100.0
#           |- unknown               unknown       1        13198     0.1              1              0.0
#           >- _dl_start             ld-2.19.so    1      1400980    13.9          19637              9.3
#           >- _d_linit_internal     ld-2.19.so    1       448152     4.4          11094              5.3
#           v-__libc_start_main@plt  ls            1      8211741    81.5         180397             85.4
#              >- _dl_fixup          ld-2.19.so    1         7607     0.1            108              0.1
#              >- __cxa_atexit       libc-2.19.so  1        11737     0.1             10              0.0
#              >- __libc_csu_init    ls            1        10354     0.1             10              0.0
#              |- _setjmp            libc-2.19.so  1            0     0.0              4              0.0
#              v- main               ls            1      8182043    99.6         180254             99.9
#
# Points to note:
#	The top level is a command name (comm)
#	The next level is a thread (pid:tid)
#	Subsequent levels are functions
#	'Count' is the number of calls
#	'Time' is the elapsed time until the function returns
#	Percentages are relative to the level above
#	'Branch Count' is the total number of branches for that function and all
#       functions that it calls

import sys
from PySide.QtCore import *
from PySide.QtGui import *
from PySide.QtSql import *
from decimal import *

class TreeItem():

	def __init__(self, db, row, parent_item):
		self.db = db
		self.row = row
		self.parent_item = parent_item
		self.query_done = False;
		self.child_count = 0
		self.child_items = []
		self.data = ["", "", "", "", "", "", ""]
		self.comm_id = 0
		self.thread_id = 0
		self.call_path_id = 1
		self.branch_count = 0
		self.time = 0
		if not parent_item:
			self.setUpRoot()

	def setUpRoot(self):
		self.query_done = True
		query = QSqlQuery(self.db)
		ret = query.exec_('SELECT id, comm FROM comms')
		if not ret:
			raise Exception("Query failed: " + query.lastError().text())
		while query.next():
			if not query.value(0):
				continue
			child_item = TreeItem(self.db, self.child_count, self)
			self.child_items.append(child_item)
			self.child_count += 1
			child_item.setUpLevel1(query.value(0), query.value(1))

	def setUpLevel1(self, comm_id, comm):
		self.query_done = True;
		self.comm_id = comm_id
		self.data[0] = comm
		self.child_items = []
		self.child_count = 0
		query = QSqlQuery(self.db)
		ret = query.exec_('SELECT thread_id, ( SELECT pid FROM threads WHERE id = thread_id ), ( SELECT tid FROM threads WHERE id = thread_id ) FROM comm_threads WHERE comm_id = ' + str(comm_id))
		if not ret:
			raise Exception("Query failed: " + query.lastError().text())
		while query.next():
			child_item = TreeItem(self.db, self.child_count, self)
			self.child_items.append(child_item)
			self.child_count += 1
			child_item.setUpLevel2(comm_id, query.value(0), query.value(1), query.value(2))

	def setUpLevel2(self, comm_id, thread_id, pid, tid):
		self.comm_id = comm_id
		self.thread_id = thread_id
		self.data[0] = str(pid) + ":" + str(tid)

	def getChildItem(self, row):
		return self.child_items[row]

	def getParentItem(self):
		return self.parent_item

	def getRow(self):
		return self.row

	def timePercent(self, b):
		if not self.time:
			return "0.0"
		x = (b * Decimal(100)) / self.time
		return str(x.quantize(Decimal('.1'), rounding=ROUND_HALF_UP))

	def branchPercent(self, b):
		if not self.branch_count:
			return "0.0"
		x = (b * Decimal(100)) / self.branch_count
		return str(x.quantize(Decimal('.1'), rounding=ROUND_HALF_UP))

	def addChild(self, call_path_id, name, dso, count, time, branch_count):
		child_item = TreeItem(self.db, self.child_count, self)
		child_item.comm_id = self.comm_id
		child_item.thread_id = self.thread_id
		child_item.call_path_id = call_path_id
		child_item.branch_count = branch_count
		child_item.time = time
		child_item.data[0] = name
		if dso == "[kernel.kallsyms]":
			dso = "[kernel]"
		child_item.data[1] = dso
		child_item.data[2] = str(count)
		child_item.data[3] = str(time)
		child_item.data[4] = self.timePercent(time)
		child_item.data[5] = str(branch_count)
		child_item.data[6] = self.branchPercent(branch_count)
		self.child_items.append(child_item)
		self.child_count += 1

	def selectCalls(self):
		self.query_done = True;
		query = QSqlQuery(self.db)
		ret = query.exec_('SELECT id, call_path_id, branch_count, call_time, return_time, '
				  '( SELECT name FROM symbols WHERE id = ( SELECT symbol_id FROM call_paths WHERE id = call_path_id ) ), '
				  '( SELECT short_name FROM dsos WHERE id = ( SELECT dso_id FROM symbols WHERE id = ( SELECT symbol_id FROM call_paths WHERE id = call_path_id ) ) ), '
				  '( SELECT ip FROM call_paths where id = call_path_id ) '
				  'FROM calls WHERE parent_call_path_id = ' + str(self.call_path_id) + ' AND comm_id = ' + str(self.comm_id) + ' AND thread_id = ' + str(self.thread_id) +
				  'ORDER BY call_path_id')
		if not ret:
			raise Exception("Query failed: " + query.lastError().text())
		last_call_path_id = 0
		name = ""
		dso = ""
		count = 0
		branch_count = 0
		total_branch_count = 0
		time = 0
		total_time = 0
		while query.next():
			if query.value(1) == last_call_path_id:
				count += 1
				branch_count += query.value(2)
				time += query.value(4) - query.value(3)
			else:
				if count:
					self.addChild(last_call_path_id, name, dso, count, time, branch_count)
				last_call_path_id = query.value(1)
				name = query.value(5)
				dso = query.value(6)
				count = 1
				total_branch_count += branch_count
				total_time += time
				branch_count = query.value(2)
				time = query.value(4) - query.value(3)
		if count:
			self.addChild(last_call_path_id, name, dso, count, time, branch_count)
		total_branch_count += branch_count
		total_time += time
		# Top level does not have time or branch count, so fix that here
		if total_branch_count > self.branch_count:
			self.branch_count = total_branch_count
			if self.branch_count:
				for child_item in self.child_items:
					child_item.data[6] = self.branchPercent(child_item.branch_count)
		if total_time > self.time:
			self.time = total_time
			if self.time:
				for child_item in self.child_items:
					child_item.data[4] = self.timePercent(child_item.time)

	def childCount(self):
		if not self.query_done:
			self.selectCalls()
		return self.child_count

	def columnCount(self):
		return 7

	def columnHeader(self, column):
		headers = ["Call Path", "Object", "Count ", "Time (ns) ", "Time (%) ", "Branch Count ", "Branch Count (%) "]
		return headers[column]

	def getData(self, column):
		return self.data[column]

class TreeModel(QAbstractItemModel):

	def __init__(self, db, parent=None):
		super(TreeModel, self).__init__(parent)
		self.db = db
		self.root = TreeItem(db, 0, None)

	def columnCount(self, parent):
		return self.root.columnCount()

	def rowCount(self, parent):
		if parent.isValid():
			parent_item = parent.internalPointer()
		else:
			parent_item = self.root
		return parent_item.childCount()

	def headerData(self, section, orientation, role):
		if role == Qt.TextAlignmentRole:
			if section > 1:
				return Qt.AlignRight
		if role != Qt.DisplayRole:
			return None
		if orientation != Qt.Horizontal:
			return None
		return self.root.columnHeader(section)

	def parent(self, child):
		child_item = child.internalPointer()
		if child_item is self.root:
			return QModelIndex()
		parent_item = child_item.getParentItem()
		return self.createIndex(parent_item.getRow(), 0, parent_item)

	def index(self, row, column, parent):
		if parent.isValid():
			parent_item = parent.internalPointer()
		else:
			parent_item = self.root
		child_item = parent_item.getChildItem(row)
		return self.createIndex(row, column, child_item)

	def data(self, index, role):
		if role == Qt.TextAlignmentRole:
			if index.column() > 1:
				return Qt.AlignRight
		if role != Qt.DisplayRole:
			return None
		index_item = index.internalPointer()
		return index_item.getData(index.column())

class MainWindow(QMainWindow):

	def __init__(self, db, dbname, parent=None):
		super(MainWindow, self).__init__(parent)

		self.setObjectName("MainWindow")
		self.setWindowTitle("Call Graph: " + dbname)
		self.move(100, 100)
		self.resize(800, 600)
		style = self.style()
		icon = style.standardIcon(QStyle.SP_MessageBoxInformation)
		self.setWindowIcon(icon);

		self.model = TreeModel(db)

		self.view = QTreeView()
		self.view.setModel(self.model)

		self.setCentralWidget(self.view)

if __name__ == '__main__':
	if (len(sys.argv) < 2):
		print >> sys.stderr, "Usage is: call-graph-from-postgresql.py <database name>"
		raise Exception("Too few arguments")

	dbname = sys.argv[1]

	db = QSqlDatabase.addDatabase('QPSQL')

	opts = dbname.split()
	for opt in opts:
		if '=' in opt:
			opt = opt.split('=')
			if opt[0] == 'hostname':
				db.setHostName(opt[1])
			elif opt[0] == 'port':
				db.setPort(int(opt[1]))
			elif opt[0] == 'username':
				db.setUserName(opt[1])
			elif opt[0] == 'password':
				db.setPassword(opt[1])
			elif opt[0] == 'dbname':
				dbname = opt[1]
		else:
			dbname = opt

	db.setDatabaseName(dbname)
	if not db.open():
		raise Exception("Failed to open database " + dbname + " error: " + db.lastError().text())

	app = QApplication(sys.argv)
	window = MainWindow(db, dbname)
	window.show()
	err = app.exec_()
	db.close()
	sys.exit(err)
