#!/usr/bin/env python
#
#  Copyright 2009 University Of Southern California
#
#  Licensed under the Apache License, Version 2.0 (the "License");
#  you may not use this file except in compliance with the License.
#  You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
#  Unless required by applicable law or agreed to in writing,
#  software distributed under the License is distributed on an "AS IS" BASIS,
#  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#  See the License for the specific language governing permissions and
#  limitations under the License.

"""Parses the output of pprof and produces summary runtime statistics."""

__author__ = "Gideon Juve <juve@usc.edu>"
__all__ = []
__version__ = "1.0"

import sys, os, re
from stats import Variable
from analysis import Analysis, sorteditems

class Executable:
	def __init__(self,xform,name):
		self.xform = xform
		self.name = name
		self.runtime = Variable()

class Transformation:
	def __init__(self,name):
		self.name = name
		self.runtime = Variable()

class RuntimeAnalysis(Analysis):
	def __init__(self):
		self.exes = {}
		self.xforms = {}
		self.file_re = re.compile("\.err(\.[0-9]{3})?$")

	def print_stats(self):
		print ",,runtime"
		print "transformation,executable,count,min,max,avg,stddev,sum"
		for exe in sorteditems(self.exes):
			print "%s,%s,%s" % (exe.xform,exe.name,exe.runtime)

		print "\n"

		print ",runtime"
		print "transformation,count,min,max,avg,stddev,sum"
		for xform in sorteditems(self.xforms):
			print "%s,%s" % (xform.name,xform.runtime)

	def is_datafile(self, file):
		return self.file_re.search(file) is not None

	def process_datafile(self,file):
		f = open(file,'r')
		line = f.readline()
		while line:
			if 'xform' in line:
				self.process_invocation(f)
			line = f.readline()
		f.close()

	def process_invocation(self,file):
		xfn = None
		xform_start = 1.0e100
		xform_stop = 0.0

		# Read lines
		line = file.readline()
		while line:
			# Skip lines
			if 'xform' in line:
				file.seek(len(line) * -1, os.SEEK_CUR)
				break
			if 'WARNING' in line:
				line = file.readline()
				continue
			if 'PTRACE_' in line:
				line = file.readline()
				continue
	
			#xform pid ppid exe lstart lstop tstart tstop vmpeak rsspeak utime stime wtime cutime cstime
			tok = line.split(' ')
			if len(tok) != 15:
				line = file.readline()
				continue
	
			if xfn is not None:
				if xfn != tok[0]:
					raise Exception("Transformation changed")
			else:
				xfn = tok[0]
	
			exn = os.path.basename(tok[3])
			exe_start = float(tok[6])
			exe_stop = float(tok[7])

			id = xfn+"$"+exn
			if id in self.exes:
				exe = self.exes[id]
			else:
				exe = Executable(xfn,exn)
				self.exes[id] = exe
	
			exe.runtime.update(exe_stop - exe_start)
	
			xform_start = min(exe_start, xform_start)
			xform_stop = max(exe_stop, xform_stop)
	
			line = file.readline()
		#end of loop
	
		if xfn in self.xforms:
			xform = self.xforms[xfn]
		else:
			xform = Transformation(xfn)
			self.xforms[xfn] = xform
	
		xform.runtime.update(xform_stop - xform_start)
	

if __name__ == '__main__':
	RuntimeAnalysis().analyze()
