#! /usr/bin/env ruby

# == Synopsis
#
# Profiles a Ruby program.
#
# == Usage
#
# ruby_prof [options] <script.rb> [options-for-script]
#
# Options:
#     -p, --printer=printer            Select a printer:
#                                        flat - Prints a flat profile as text (default).
#                                        graph - Prints a graph profile as text.
#                                        graph_html - Prints a graph profile as html.
#     -f, --file=path                  Output results to a file instead of standard out.
#     -c, --clock-mode=clock_mode      Select a clock mode:
#                                        process - Use process time (default).
#                                        wall - Use wall time.
#                                        cpu - Use the CPU clock counter
#                                              (only supported on Pentium and PowerPCs).
#     -h, --help                       Show help message
#         --version                    Show version
# 
#
# See also: {flat profiles}[link:files/examples/flat_txt.html], {graph profiles}[link:files/examples/graph_txt.html], {html graph profiles}[link:files/examples/graph_html.html]
#


require 'ostruct'
require 'optparse'
require 'ruby-prof'

options = OpenStruct.new
options.clock_mode = RubyProf::PROCESS_TIME
options.printer = RubyProf::FlatPrinter
options.min_percent = 0
options.file = nil

opts = OptionParser.new do |opts|
	opts.banner = "ruby_prof #{RubyProf::VERSION}\n" +
	              "Usage: ruby_prof [options] <script.rb> [--extra-options-for-script]"
 
	opts.separator ""
	opts.separator "Options:"

		
	opts.on('-p printer', '--printer=printer', [:flat, :graph, :graph_html],
					'Select a printer:',
					'  flat - Prints a flat profile as text (default).',
					'  graph - Prints a graph profile as text.',
					'  graph_html - Prints a graph profile as html.') do |printer|
					
		case printer
			when :flat
				options.printer = RubyProf::FlatPrinter
			when :graph
				options.printer = RubyProf::GraphPrinter
			when :graph_html
				options.printer = RubyProf::GraphHtmlPrinter
		end
	end
		
	opts.on('-m min_percent', '--min_percent=min_percent', Float,
					'The minimum percent a method must take before ',
					'  being included in output reports') do |min_percent|
		options.min_percent = min_percent
	end

	opts.on('-f path', '--file=path',
				'Output results to a file instead of standard out.') do |file|
		options.file = file
	end
		
	opts.on('-c clock_mode', '--clock-mode=clock_mode',
			[:process, :wall, :cpu],
			'Select a clock mode:',
			'  process - Use process time (default).',
			'  wall - Use wall time.',
			'  cpu - Use the CPU clock counter',
			'        (only supported on Pentium and PowerPCs).') do |clock_mode|
			
			case
			when :process
				options.clock_mode = RubyProf::PROCESS_TIME			
			when :wall
				options.clock_mode = RubyProf::WALL_TIME			
			when :cpu
				options.clock_mode = RubyProf::CPU_TIME
			end
	end
		
	opts.on_tail("-h", "--help", "Show help message") do
			puts opts
			exit
	end
	opts.on_tail("-v", "--version", "Show version") do
			puts "ruby_prof " + RubyProf::VERSION
			exit
	end
end

begin
	opts.parse! ARGV
rescue OptionParser::InvalidOption, OptionParser::InvalidArgument,
       OptionParser::MissingArgument => e
	puts opts
  puts
  puts e.message
  exit(-1)
end

# Make sure the user specified at least one file
if ARGV.length < 1
	puts opts
	puts ""
	puts "Must specify a script to run"
  exit(-1)
end


# Install at_exit handler.  It is important that we do this 
# before loading the scripts so our at_exit handler run
# *after* any other one that will be installed. 

at_exit {
  # Stop profiling
	result = RubyProf.stop

	# Create a printer
	printer = options.printer.new(result)

	# Get output
	if options.file
		File.open(options.file, 'w') do |file|
			printer.print(file, options.min_percent)
		end
	else
		# Print out results	
		printer.print(STDOUT, options.min_percent)
	end
}

# Now set clock mode
RubyProf.clock_mode = options.clock_mode

# Get the script we will execute
script = ARGV.shift

# Start profiling
RubyProf.start 

# Load the script
load script
