#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# Copyright 2011 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.

"""The driver script for running performance benchmarks on ChromeOS."""

from __future__ import print_function

import argparse
import atexit
import os
import signal
import sys

from experiment_runner import ExperimentRunner
from experiment_runner import MockExperimentRunner
from experiment_factory import ExperimentFactory
from experiment_file import ExperimentFile
from settings_factory import GlobalSettings

# This import causes pylint to warn about "No name 'logger' in module
# 'cros_utils'". I do not understand why. The import works fine in python.
# pylint: disable=no-name-in-module
from cros_utils import logger

import test_flag


def SetupParserOptions(parser):
  """Add all options to the parser."""
  parser.add_argument(
      '--dry_run',
      dest='dry_run',
      help=('Parse the experiment file and '
            'show what will be done'),
      action='store_true',
      default=False)
  # Allow each of the global fields to be overridden by passing in
  # options. Add each global field as an option.
  option_settings = GlobalSettings('')
  for field_name in option_settings.fields:
    field = option_settings.fields[field_name]
    parser.add_argument(
        '--%s' % field.name,
        dest=field.name,
        help=field.description,
        action='store')


def ConvertOptionsToSettings(options):
  """Convert options passed in into global settings."""
  option_settings = GlobalSettings('option_settings')
  for option_name in options.__dict__:
    if (options.__dict__[option_name] is not None and
        option_name in option_settings.fields):
      option_settings.SetField(option_name, options.__dict__[option_name])
  return option_settings


def Cleanup(experiment):
  """Handler function which is registered to the atexit handler."""
  experiment.Cleanup()


def CallExitHandler(signum, _):
  """Signal handler that transforms a signal into a call to exit.

  This is useful because functionality registered by "atexit" will
  be called. It also means you can "catch" the signal by catching
  the SystemExit exception.
  """
  sys.exit(128 + signum)


def RunCrosperf(argv):
  parser = argparse.ArgumentParser()

  parser.add_argument(
      '--noschedv2',
      dest='noschedv2',
      default=False,
      action='store_true',
      help=('Do not use new scheduler. '
            'Use original scheduler instead.'))
  parser.add_argument(
      '-l',
      '--log_dir',
      dest='log_dir',
      default='',
      help='The log_dir, default is under <crosperf_logs>/logs')
  parser.add_argument(
      '--no_hwp',
      default=False,
      action='store_true',
      help='Disable intel_pstate on Intel CPU with HWP support.')

  SetupParserOptions(parser)
  options, args = parser.parse_known_args(argv)

  # Convert the relevant options that are passed in into a settings
  # object which will override settings in the experiment file.
  option_settings = ConvertOptionsToSettings(options)
  log_dir = os.path.abspath(os.path.expanduser(options.log_dir))
  logger.GetLogger(log_dir)

  if len(args) == 2:
    experiment_filename = args[1]
  else:
    parser.error('Invalid number arguments.')

  working_directory = os.getcwd()
  if options.dry_run:
    test_flag.SetTestMode(True)

  experiment_file = ExperimentFile(
      open(experiment_filename, 'rb'), option_settings)
  if not experiment_file.GetGlobalSettings().GetField('name'):
    experiment_name = os.path.basename(experiment_filename)
    experiment_file.GetGlobalSettings().SetField('name', experiment_name)
  experiment = ExperimentFactory().GetExperiment(experiment_file,
                                                 working_directory, log_dir)
  if options.no_hwp:
    experiment.intel_pstate = 'no_hwp'

  json_report = experiment_file.GetGlobalSettings().GetField('json_report')

  signal.signal(signal.SIGTERM, CallExitHandler)
  atexit.register(Cleanup, experiment)

  if options.dry_run:
    runner = MockExperimentRunner(experiment, json_report)
  else:
    runner = ExperimentRunner(
        experiment, json_report, using_schedv2=(not options.noschedv2))

  runner.Run()


def Main(argv):
  try:
    RunCrosperf(argv)
  except Exception:
    # Flush buffers before exiting to avoid out of order printing
    sys.stdout.flush()
    # Raise exception prints out traceback
    raise


if __name__ == '__main__':
  Main(sys.argv)
