#!/usr/bin/pyton

# Copyright 2017 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os
import sys
import subprocess
import multiprocessing

from argparse import ArgumentParser


README = """
Simply run
\033[36m
    python {0} TEST_GIT_BRANCH
\033[0m
to see if TEST_GIT_BRANCH has performance regressions against master in 8888.

To compare a specific config with svg and skp resources included, add --config
and --extraarg option. For exampe,
\033[36m
    python {0} TEST_GIT_BRANCH --config gl \\
        --extraarg "--svgs ~/Desktop/bots/svgs --skps ~/Desktop/bots/skps"
\033[0m
For more options, please see

    python {0} --help
""".format(__file__)


CURRENT_DIR = os.path.dirname(os.path.abspath(__file__))
AB_SCRIPT = "ab.py"


def parse_args():
  if len(sys.argv) <= 1 or sys.argv[1] == '-h' or sys.argv[1] == '--help':
    print README

  parser = ArgumentParser(
    description='Noiselessly (hence calm) becnhmark a git branch against ' +
                'another baseline branch (e.g., master) using multiple ' +
                ' nanobench runs.'
  )

  default_threads = max(1, multiprocessing.cpu_count() / 2);
  default_skiadir = os.path.normpath(CURRENT_DIR + "/../../")

  config_help = (
      'nanobench config; we currently support only one config '
      'at a time (default: %(default)s)')
  reps_help = (
      'initial repititions of the nanobench run; this may be '
      'overridden when we have many threads (default: %(default)s)')
  extraarg_help = (
      'nanobench args (example: --svgs ~/Desktop/bots/svgs --skps '
      '~/Desktop/bots/skps)')
  baseline_help = (
      'baseline branch to compare against (default: %(default)s)')
  basearg_help = (
      'nanobench arg for the baseline branch; if not given, we use '
      ' the same arg for both the test branch and the baseline branch')
  threads_help = (
      'number of threads to be used (default: %(default)s); '
      'for GPU config, this will always be 1')
  no_compile_help = (
      'whether NOT to compile nanobench and copy it to WRITEDIR '
      '(i.e., reuse previous nanobench compiled)')
  skip_base_help = (
      'whether NOT to run nanobench on baseline branch '
      '(i.e., reuse previous baseline measurements)')
  noinit_help = (
      'whether to skip initial nanobench runs (default: %(default)s)')
  branch_help = (
      "the test branch to benchmark; if it's 'modified', we'll benchmark the "
      "current modified code against 'git stash'.")

  definitions = [
    # argname, type, default value, help
    ['--config',    str, '8888', config_help],
    ['--skiadir',   str, default_skiadir, 'default: %(default)s'],
    ['--ninjadir',  str, 'out/Release', 'default: %(default)s'],
    ['--writedir',  str, '/var/tmp', 'default: %(default)s'],
    ['--extraarg',  str, '', extraarg_help],
    ['--baseline',  str, 'master', baseline_help],
    ['--basearg',   str, '', basearg_help],
    ['--reps',      int, 2, reps_help],
    ['--threads',   int, default_threads, threads_help],
  ]

  for d in definitions:
    parser.add_argument(d[0], type=d[1], default=d[2], help=d[3])

  parser.add_argument('branch', type=str, help=branch_help)
  parser.add_argument('--no-compile', dest='no_compile', action="store_true",
      help=no_compile_help)
  parser.add_argument('--skip-base', dest='skipbase', action="store_true",
      help=skip_base_help)
  parser.add_argument('--noinit', dest='noinit', action="store_true",
      help=noinit_help)
  parser.add_argument('--concise', dest='concise', action="store_true",
      help="If set, no verbose thread info will be printed.")
  parser.set_defaults(no_compile=False);
  parser.set_defaults(skipbase=False);
  parser.set_defaults(noinit=False);
  parser.set_defaults(concise=False);

  # Additional args for bots
  BHELP = "bot specific options"
  parser.add_argument('--githash', type=str, help=BHELP)
  parser.add_argument('--keys', type=str, default=[], nargs='+', help=BHELP)

  args = parser.parse_args()
  if not args.basearg:
    args.basearg = args.extraarg

  return args


def nano_path(args, branch):
  return args.writedir + '/nanobench_' + branch


def compile_branch(args, branch):
  print "Compiling branch %s" % args.branch

  commands = [
    ['git', 'checkout', branch],
    ['ninja', '-C', args.ninjadir, 'nanobench'],
    ['cp', args.ninjadir + '/nanobench', nano_path(args, branch)]
  ]
  for command in commands:
    subprocess.check_call(command, cwd=args.skiadir)


def compile_modified(args):
  print "Compiling modified code"
  subprocess.check_call(
      ['ninja', '-C', args.ninjadir, 'nanobench'], cwd=args.skiadir)
  subprocess.check_call(
      ['cp', args.ninjadir + '/nanobench', nano_path(args, args.branch)],
      cwd=args.skiadir)

  print "Compiling stashed code"
  stash_output = subprocess.check_output(['git', 'stash'], cwd=args.skiadir)
  if 'No local changes to save' in stash_output:
    subprocess.check_call(['git', 'reset', 'HEAD^', '--soft'])
    subprocess.check_call(['git', 'stash'])

  subprocess.check_call(['gclient', 'sync'], cwd=args.skiadir)
  subprocess.check_call(
      ['ninja', '-C', args.ninjadir, 'nanobench'], cwd=args.skiadir)
  subprocess.check_call(
      ['cp', args.ninjadir + '/nanobench', nano_path(args, args.baseline)],
      cwd=args.skiadir)
  subprocess.check_call(['git', 'stash', 'pop'], cwd=args.skiadir)

def compile_nanobench(args):
  if args.branch == 'modified':
    compile_modified(args)
  else:
    compile_branch(args, args.branch)
    compile_branch(args, args.baseline)


def main():
  args = parse_args()

  # copy in case that it will be gone after git branch switching
  orig_ab_name = CURRENT_DIR + "/" + AB_SCRIPT
  temp_ab_name = args.writedir + "/" + AB_SCRIPT
  subprocess.check_call(['cp', orig_ab_name, temp_ab_name])

  if not args.no_compile:
    compile_nanobench(args)

  command = [
    'python',
    temp_ab_name,
    args.writedir,
    args.branch + ("_A" if args.branch == args.baseline else ""),
    args.baseline + ("_B" if args.branch == args.baseline else ""),
    nano_path(args, args.branch),
    nano_path(args, args.baseline),
    args.extraarg,
    args.basearg,
    str(args.reps),
    "true" if args.skipbase else "false",
    args.config,
    str(args.threads if args.config in ["8888", "565"] else 1),
    "true" if args.noinit else "false"
  ]

  if args.githash:
    command += ['--githash', args.githash]
  if args.keys:
    command += (['--keys'] + args.keys)

  if args.concise:
    command.append("--concise")

  p = subprocess.Popen(command, cwd=args.skiadir)
  try:
    p.wait()
  except KeyboardInterrupt:
    try:
      p.terminate()
    except OSError as e:
      print e


if __name__ == "__main__":
  main()
