#!/usr/bin/python

# This is code is released under the GNU GPL v3 license.

__author__ = 'Aaron S. Joyner <aaron@joyner.ws>'

import optparse
import os
import random
import sys
import time


def ParseOptions():
  """Parse the command line options.  Return optparse output."""
  usage = ('usage: %prog [options] [a command to benchmark]\n\n'
           'If no command is given, a standard set of benchmarks is run.')
  parser = optparse.OptionParser(usage)
  parser.add_option('-r', '--repetitions', type='int', default=100,
                    help='Number of repetitions of the benchmark')
  parser.add_option('-s', '--short_output', action='store_const',
                    dest='output_format', const='short',
                    help='Output short, but human-readable strings')
  parser.add_option('-m', '--machine_readable', action='store_const',
                    dest='output_format', const='machine',
                    help='Output just the times, in machine friendly format')
  parser.add_option('-i', '--inputdir', default='.',
                    help='Directory to benchmark in')
  return parser.parse_args()


def BenchmarkCommand(cmd, repetitions):
  """Run the given command repetitions times, report mean time taken."""
  start_time = time.time()
  for i in xrange(0, repetitions):
    os.system('%s > /dev/null 2>/dev/null' % cmd)
  return (time.time() - start_time) / repetitions


def ReportTime(cmd, repetitions, elapsed_time, output_format):
  """Report how long a test took."""
  if output_format == 'machine':
    print '%7.3f ' % (elapsed_time),
  elif output_format == 'short':
    print '%7.3f: %s' % (elapsed_time, cmd)
  else:
    print ('Executing "%s" %s times, mean %7.3f seconds per run'
           % (cmd, repetitions, elapsed_time))


def PickAFile():
  """Pick a file from the current directory to operate on."""
  return random.choice(os.listdir('.'))


def TestVariousCommands(repetitions, random_file, output_format):
  """Run a battery of various tests against a random file in the directory."""
  cmds = ['/bin/ls %(random_file)s',
          '/bin/ls',
          '/bin/ls -l',
          '/bin/ls --color=always %(random_file)s',
          '/bin/ls --color=always',
          '/bin/ls --color=always -l',
          '/usr/bin/md5sum %(random_file)s',
         ]
  for cmd in cmds:
    cmd = cmd % {'random_file': random_file}
    elapsed_time = BenchmarkCommand(cmd, repetitions)
    ReportTime(cmd, repetitions, elapsed_time, output_format)


def main():
  (options, args) = ParseOptions()
  os.chdir(options.inputdir)
  if args:
    cmd = ' '.join(args)
    elapsed_time = BenchmarkCommand(cmd, options.repetitions)
    ReportTime(cmd, options.repetitions, elapsed_time, options.output_format)
  else:
    TestVariousCommands(options.repetitions, PickAFile(), options.output_format)

  if options.output_format == 'machine':
    print

if __name__ == '__main__':
  main()
