#!/usr/bin/env python3
# -*- 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

HAS_FAILURE = 1
ALL_FAILED = 2


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')

  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, encoding='utf-8'), 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)

  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))

  ret = runner.Run()
  if ret == HAS_FAILURE:
    raise RuntimeError('One or more benchmarks failed.')
  if ret == ALL_FAILED:
    raise RuntimeError('All benchmarks failed to 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)
