#!/usr/bin/python

# Copyright (c) 2010 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A command to display summary statistics from runs of 'bootperf'.

Command line options allow selecting from one of three sets of
performance statistics:  boot time statistics (selected by
--timestats) measure time spent since kernel startup; disk statistics
(selected by --diskstats) measure total bytes read from the boot
device since kernel startup; firmware time statistics (selected by
--firmware) measure time spent since CPU power on.

The various statistics are recorded as cumulative time (or disk read)
since kernel startup (or CPU power on), sampled when specific events
occur during boot.  Events include such things as 'startup', the
moment when the upstart 'startup' job begins running, and 'login',
when the Chrome OS login screen is displayed.  By default, all
recorded events are included in the output; command line options
allow restricting the view to a selected subset of events.

Separate command line options allow selecting from one of two
different display modes.  When --averages is selected, the display
shows the average value and sample standard deviation (as a percent
of the average) for all selected events.  The --averages display
also calculates the difference (in time or bytes) between adjacent
events, and shows the average and sample standard deviation of the
differences.

The --rawdata display shows the raw data value associated with each
event for each boot:  Each line of output represents the event values
for one boot cycle.

"""

import sys
import optparse

import perfprinter
import resultsdir
import resultset


_USAGE = "%prog [options] [results-directory ...]"
_DESCRIPTION = """\
Summarize boot time performance results.  The result directory
arguments are directories previously specified as output for the
'bootperf' script.
"""


def _SetupOptions():
  optparser = optparse.OptionParser(usage=_USAGE, description=_DESCRIPTION)

  optgroup = optparse.OptionGroup(
      optparser, "Selecting boot time or disk statistics (choose one)")
  optgroup.add_option(
      "-t", "--timestats", action="store_true",
      dest="use_timestats",
      help="use statistics for time since kernel startup (default)")
  optgroup.add_option(
      "-d", "--diskstats", action="store_true",
      dest="use_diskstats",
      help="use statistics for bytes read since kernel startup")
  optgroup.add_option(
      "-f", "--firmwarestats", action="store_true",
      dest="use_firmware",
      help="use statistics for firmware startup times")
  optparser.add_option_group(optgroup)
  optparser.set_defaults(use_diskstats=False)
  optparser.set_defaults(use_timestats=False)
  optparser.set_defaults(use_firmware=False)

  optgroup = optparse.OptionGroup(optparser, "Event selection")
  optgroup.add_option(
      "-e", "--event", action="append",
      dest="eventnames",
      help="restrict statistics to the comma-separated list of events")
  optparser.add_option_group(optgroup)

  optgroup = optparse.OptionGroup(
      optparser, "Display mode selection (choose one)")
  optgroup.add_option(
      "-a", "--averages", action="store_true",
      dest="print_averages",
      help="display a summary of the averages of chosen statistics (default)")
  optgroup.add_option(
      "-r", "--rawdata", action="store_true",
      dest="print_raw",
      help="display raw data from all boot iterations")
  optparser.add_option_group(optgroup)
  optparser.set_defaults(print_averages=False)
  optparser.set_defaults(print_raw=False)
  return optparser


def _ProcessDisplayOptions(options):
  display_count = 0
  if options.print_averages:
    display_count += 1
    printfunc = perfprinter.PrintStatisticsSummary
  if options.print_raw:
    display_count += 1
    printfunc = perfprinter.PrintRawData
  if display_count == 0:
    printfunc = perfprinter.PrintStatisticsSummary
  elif display_count > 1:
    print >>sys.stderr, "Can't use -a and -r together.\n"
    return None
  return printfunc


def _ProcessKeysetOptions(options):
  keyset_count = 0
  keyset_type = resultset.TestResultSet.BOOTTIME_KEYSET
  if options.use_timestats:
    keyset_count += 1
    keyset_type = resultset.TestResultSet.BOOTTIME_KEYSET
  if options.use_diskstats:
    keyset_count += 1
    keyset_type = resultset.TestResultSet.DISK_KEYSET
  if options.use_firmware:
    keyset_count += 1
    keyset_type = resultset.TestResultSet.FIRMWARE_KEYSET
  if keyset_count > 1:
    print >>sys.stderr, "Can use only one of -t, -d, or -f.\n"
    keyset_type = None
  return keyset_type


def _ProcessKeylistOptions(options):
  if not options.eventnames:
    return None
  keylist = []
  for kl in options.eventnames:
    keylist.extend(kl.split(','))
  return keylist


def main(argv):
  optparser = _SetupOptions()
  (options, args) = optparser.parse_args(argv)
  printfunc = _ProcessDisplayOptions(options)
  keyset_type = _ProcessKeysetOptions(options)
  keylist = _ProcessKeylistOptions(options)
  if printfunc is None or keyset_type is None:
    optparser.print_help()
    sys.exit(1)
  if not args:
    args = ["."]
  printfunc(resultsdir.ReadResultsDirectory,
            args, keyset_type, keylist)


if __name__ == "__main__":
  main(sys.argv[1:])
