#
# ***********************************************************************
#  Warning: This file is auto-generated from main.py.in - edit it there.
# ***********************************************************************
#
#  pybootchartgui is free software: you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation, either version 3 of the License, or
#  (at your option) any later version.

#  pybootchartgui is distributed in the hope that 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.

#  You should have received a copy of the GNU General Public License
#  along with pybootchartgui. If not, see <http://www.gnu.org/licenses/>.

from __future__ import print_function

import sys
import os
import optparse

from . import parsing
from . import batch

def _mk_options_parser():
	"""Make an options parser."""
	usage = "%prog [options] /path/to/tmp/buildstats/<recipe-machine>/<BUILDNAME>/"
	version = "%prog v1.0.0"
	parser = optparse.OptionParser(usage, version=version)
	parser.add_option("-i", "--interactive", action="store_true", dest="interactive", default=False, 
			  help="start in active mode")
	parser.add_option("-f", "--format", dest="format", default="png", choices=["png", "svg", "pdf"],
			  help="image format (png, svg, pdf); default format png")
	parser.add_option("-o", "--output", dest="output", metavar="PATH", default=None,
			  help="output path (file or directory) where charts are stored")
	parser.add_option("-s", "--split", dest="num", type=int, default=1,
			  help="split the output chart into <NUM> charts, only works with \"-o PATH\"")
	parser.add_option("-m", "--mintime", dest="mintime", type=int, default=8,
			  help="only tasks longer than this time will be displayed")
	parser.add_option("-M", "--minutes", action="store_true", dest="as_minutes", default=False,
			  help="display time in minutes instead of seconds")
#	parser.add_option("-n", "--no-prune", action="store_false", dest="prune", default=True,
#			  help="do not prune the process tree")
	parser.add_option("-q", "--quiet", action="store_true", dest="quiet", default=False,
			  help="suppress informational messages")
#	parser.add_option("-t", "--boot-time", action="store_true", dest="boottime", default=False,
#			  help="only display the boot time of the boot in text format (stdout)")	
	parser.add_option("--very-quiet", action="store_true", dest="veryquiet", default=False,
			  help="suppress all messages except errors")
	parser.add_option("--verbose", action="store_true", dest="verbose", default=False,
			  help="print all messages")
#	parser.add_option("--profile", action="store_true", dest="profile", default=False,
#			  help="profile rendering of chart (only useful when in batch mode indicated by -f)")
#	parser.add_option("--show-pid", action="store_true", dest="show_pid", default=False,
#			  help="show process ids in the bootchart as 'processname [pid]'")
	parser.add_option("--show-all", action="store_true", dest="show_all", default=False,
			  help="show all processes in the chart")
#	parser.add_option("--crop-after", dest="crop_after", metavar="PROCESS", default=None,
#			  help="crop chart when idle after PROCESS is started")
#	parser.add_option("--annotate", action="append", dest="annotate", metavar="PROCESS", default=None,
#			  help="annotate position where PROCESS is started; can be specified multiple times. " +
#			       "To create a single annotation when any one of a set of processes is started, use commas to separate the names")
#	parser.add_option("--annotate-file", dest="annotate_file", metavar="FILENAME", default=None,
#			  help="filename to write annotation points to")
	parser.add_option("-T", "--full-time", action="store_true", dest="full_time", default=False,
			  help="display the full time regardless of which processes are currently shown")
	return parser

class Writer:
	def __init__(self, write, options):
		self.write = write
		self.options = options
		
	def error(self, msg):
		self.write(msg)

	def warn(self, msg):
		if not self.options.quiet:
			self.write(msg)

	def info(self, msg):
		if self.options.verbose:
			self.write(msg)

	def status(self, msg):
		if not self.options.quiet:
			self.write(msg)

def _mk_writer(options):
	def write(s):
		print(s)
	return Writer(write, options)
	
def _get_filename(path):
	"""Construct a usable filename for outputs"""
	dname = "."
	fname = "bootchart"
	if path != None:
		if os.path.isdir(path):
			dname = path
		else:
			fname = path
	return os.path.join(dname, fname)

def main(argv=None):
	try:
		if argv is None:
			argv = sys.argv[1:]
	
		parser = _mk_options_parser()
		options, args = parser.parse_args(argv)

		# Default values for disabled options
		options.prune = True
		options.boottime = False
		options.profile = False
		options.show_pid = False
		options.crop_after = None
		options.annotate = None
		options.annotate_file = None

		writer = _mk_writer(options)

		if len(args) == 0:
			print("No path given, trying /var/log/bootchart.tgz")
			args = [ "/var/log/bootchart.tgz" ]

		res = parsing.Trace(writer, args, options)

		if options.interactive or options.output == None:
			from . import gui
			gui.show(res, options)
		elif options.boottime:
			import math
			proc_tree = res.proc_tree
			if proc_tree.idle:
			    duration = proc_tree.idle
			else:
			    duration = proc_tree.duration
			dur = duration / 100.0
			print('%02d:%05.2f' % (math.floor(dur/60), dur - 60 * math.floor(dur/60)))
		else:
			if options.annotate_file:
				f = open (options.annotate_file, "w")
				try:
					for time in res[4]:
						if time is not None:
							# output as ms
							print(time * 10, file=f)
						else:
							print(file=f)
				finally:
					f.close()
			filename = _get_filename(options.output)
			res_list = parsing.split_res(res, options)
			n = 1
			width = len(str(len(res_list)))
			s = "_%%0%dd." % width
			for r in res_list:
				if len(res_list) == 1:
					f = filename + "." + options.format
				else:
					f = filename + s % n + options.format
					n = n + 1
				def render():
					batch.render(writer, r, options, f)
				if options.profile:
					import cProfile
					import pstats
					profile = '%s.prof' % os.path.splitext(filename)[0]
					cProfile.runctx('render()', globals(), locals(), profile)
					p = pstats.Stats(profile)
					p.strip_dirs().sort_stats('time').print_stats(20)
				else:
					render()

		return 0
	except parsing.ParseError as ex:
		print(("Parse error: %s" % ex))
		return 2


if __name__ == '__main__':
	sys.exit(main())
