#!/usr/bin/python
# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Script to bisect a VR perf regression.

This is only meant to be used on a developer's workstation, not on bots or any
other sort of automated infrastructure. This is to help reduce the amount of
work necessary to bisect VR perf regressions until the perf dashboard supports
automatic bisects on devices outside of the Telemetry lab.

As a result, this is a bit crude and makes a number of assumptions.
"""


import argparse
import json
import os
import shutil
import subprocess
import sys
import tempfile
import time


SUPPORTED_JSON_RESULT_FORMATS = {
  'chartjson': 'The standard JSON output format for Telemetry.',
  'printedjson': ('The JSON output format generated from parsing stdout from '
                 'a test. This is the format used by tests that use '
                 '//testing/perf/perf_test.h'),
}
# The revision that changed the way perf tests are run on swarming.
PERF_FORMAT_CHANGE_REVISION = '0d271f583489024e3c163f0538d1ec29097b3615'


class TempDir():
  """Context manager for temp dirs since Python 2 doesn't have one."""
  def __enter__(self):
    self._dirpath = tempfile.mkdtemp()
    return self._dirpath

  def __exit__(self, type, value, traceback):
    shutil.rmtree(self._dirpath)


class SwitchDirsIfNotChromiumBisect():
  """Context manager for switching between another repo and Chromium src.

  No-op if the --bisect-repo option is not used, otherwise changes directories
  to the specified repo's directory, then returns to the original directory when
  the context is left.
  """
  def __init__(self, args):
    self.starting_directory = os.getcwd()
    self.target_directory = args.bisect_repo

  def __enter__(self):
    if self.target_directory:
      os.chdir(self.target_directory)

  def __exit__(self, type, value, traceback):
    if self.target_directory:
      os.chdir(self.starting_directory)


def VerifyCwd():
  """Checks that the script is being run from the Chromium root directory.

  Not robust in the slightest, but should catch common issues like running the
  script from the directory that it's located in.
  """
  if os.path.basename(os.getcwd()) != 'src':
    raise RuntimeError('Script must be run from the Chromium root directory')


def ParseArgsAndAssertValid():
  """Parses all the provided arguments and ensures everything is valid."""
  parser = argparse.ArgumentParser();

  # Arguments related to the actual bisection
  parser.add_argument_group('bisect arguments')
  parser.add_argument('--binary-size-bisect', action='store_true',
                      default=False,
                      help='Bisect a binary size regression instead of a '
                           'regular perf regression.')
  parser.add_argument('--good-revision', required=True,
                      help='A known good Git revision')
  parser.add_argument('--bad-revision', required=True,
                      help='A known bad Git revision')
  parser.add_argument('--metric', required=True,
                      help='The perf metric being bisected')
  parser.add_argument('--story', required=True,
                      help='The perf story to check the affected metric in')
  parser.add_argument('--good-value', type=float,
                      help='The value of the metric at the good revision. If '
                           'not defined, an extra test iteration will be run '
                           'to determine the value')
  parser.add_argument('--bad-value', type=float,
                      help='The value of the metric at the bad revision. If '
                           'not defined, an extra test iteration will be run '
                           'to determine the value')
  def comma_separated(arg):
    split_arg = arg.split(',')
    if len(split_arg) != 2:
      raise argparse.ArgumentError(
          'Expected two comma-separated strings but '
          'received %d' % len(split_arg))
    return {split_arg[0]: split_arg[1]}
  parser.add_argument('--checkout-override', action='append',
                      type=comma_separated, default=[],
                      dest='checkout_overrides',
                      help='A comma-separated path/revision key/value pair. '
                           'Each git checkout at the specified path will be '
                           'synced to the specified revision after the normal '
                           'sync. For example, passing '
                           'third_party/android_ndk,abcdefg would cause the '
                           'checkout in //third_party/android_ndk to be synced '
                           'to revision abcdefg.')
  parser.add_argument('--bisect-repo',
                      help='A path to the repo that will be bisected instead '
                           'the Chromium src repo. Meant to be used for '
                           'bisecting rolls of DEPS (e.g V8 or Skia) after '
                           'an initial bisect finds that a roll is the culprit '
                           'CL. Using this option will disable any syncing of '
                           'the Chromium src repo, so ensure that you are '
                           'synced to the correct src revision before running '
                           'with this option.')
  parser.add_argument('--reset-before-sync', action='store_true',
                      default=False,
                      help='When set, runs "git reset --hard HEAD" before '
                           'syncing. This has the potential to accidentally '
                           'delete any uncommitted changes, but can help avoid '
                           'random bisect failures.')
  parser.add_argument('--num-attempts-before-marking-good', type=int, default=1,
                      help='The number of times the test will be run before '
                           'a revision can be marked as good. If all runs are '
                           'found to be good, then the revision is good, '
                           'otherwise bad. Overriding this can help when '
                           'bisecting flaky metrics that fluctuate between '
                           'good/bad values, but can significantly increase '
                           'bisect time.')
  parser.add_argument('--expected-json-result-format', default='chartjson',
                      help='The data format the JSON results from the test are '
                           'expected to be in. Supported values are: ' +
                           (', '.join(SUPPORTED_JSON_RESULT_FORMATS.keys())))
  parser.add_argument('--manual-mode', action='store_true', default=False,
                      help='Does not automatically run gclient sync and waits '
                           'for user input before starting the build/run '
                           'process. Useful if a bisect needs to be run within '
                           'a range where some change breaks gclient sync and '
                           'a patch needs to be applied at each step before '
                           'syncing.')
  parser.add_argument('--apply-stash-before-sync',
                      help='Applies the given stash entry (e.g. "stash@{0}"), '
                           'commits it, and syncs to the new revision during '
                           'each iteration. Primary use case for this is '
                           'fixing bad DEPS entries in the revision range.')
  parser.add_argument('--benchmark',
                      help='The benchmark to run when bisecting a perf test. '
                           'This will be automatically translated to the '
                           'correct format and passed to the test, as the '
                           'format is different depending on when the '
                           'regression occured.')

  parser.add_argument_group('swarming arguments')
  parser.add_argument('--swarming-server',
                      help='The swarming server to trigger the test on')
  parser.add_argument('--isolate-server',
                      help='The isolate server to upload the test to')
  parser.add_argument('--dimension', action='append', type=comma_separated,
                      default=[], dest='dimensions',
                      help='A comma-separated swarming dimension key/value '
                           'pair. At least one must be provided.')
  parser.add_argument('--isolate-target',
                      help='The target to isolate. Defaults to the build '
                           'target')

  parser.add_argument_group('compile arguments')
  parser.add_argument('-j', '--parallel-jobs', type=int, default=1000,
                      help='The number of parallel jobs ninja will compile '
                           'with')
  parser.add_argument('-l', '--load-limit', type=int, default=70,
                      help='Don\'t start new ninja jobs if the average CPU '
                           'is above this')
  parser.add_argument('--build-output-dir',
                      default=os.path.join('out', 'Release'),
                      help='The directory that builds will take place in. '
                           'Assumes that gn args have already been generated '
                           'for the provided directory. Must be relative to '
                           'the Chromium src/ directory, e.g. out/Release. '
                           'When using --binary-size-bisect, this should be '
                           'the output directory for the base build.')
  parser.add_argument('--diff-build-output-dir',
                      default=os.path.join('out', 'Release_diff'),
                      help='Only used when --binary-size-bisect is set. The '
                           'same as --build-output-dir, but for the diff '
                           'build.')
  parser.add_argument('--regenerate-args-after-sync', action='store_true',
                      default=False,
                      help='Causes the build output directory to be deleted '
                           'and re-created using the same gn args after each '
                           'sync. Normally not necessary, but can work around '
                           'weird issues like the build target not being '
                           'available unless the directory is re-created.')
  parser.add_argument('--build-target', required=True,
                      help='The target to build for testing')
  parser.add_argument('--apk-name',
                      help='Only used when --binary-size-bisect is set. The '
                            'name of the APK that will be diffed.')

  args, unknown_args = parser.parse_known_args()

  if args.binary_size_bisect:
    if not args.apk_name:
      raise RuntimeError(
          '--apk-name must be set when using --binary-size-bisect.')

    if not args.diff_build_output_dir:
      raise RuntimeError('--diff-build-output-dir must be set when using '
                         '--binary-size-bisect.')

  else:
    # Set defaults.
    if not args.isolate_target:
      args.isolate_target = args.build_target

    # Make sure we have at least one swarming dimension.
    if len(args.dimensions) == 0:
      raise RuntimeError('No swarming dimensions provided')

    if not args.benchmark:
      raise RuntimeError('No benchmark provided with --benchmark')

    # Make sure we have all the information we need in order to run on Swarming.
    if not (args.swarming_server and args.isolate_server):
      raise RuntimeError('--swarming-server and --isolate-server must be set '
                         'when running a non-binary-size bisection.')

    # Make sure we're set to run at least one attempt per revision
    if args.num_attempts_before_marking_good < 1:
      raise RuntimeError(
          '--num-attempts-before-marking-good set to invalid value %d' %
          args.num_attempts_before_marking_good)

    # Make sure the provided data format is supported.
    if args.expected_json_result_format not in SUPPORTED_JSON_RESULT_FORMATS:
      raise RuntimeError(
          '--expected-json-result-format set to invalid value %s' %
          args.expected_json_result_format)

    # Determining initial values is not currently supported if we're bisecting a
    # roll. Since bisecting a roll is almost always a product of a normal bisect
    # pointing to a roll anyways, the user should have the good/bad values
    # already.
    if args.bisect_repo and (args.good_value is None or args.bad_value is None):
      raise RuntimeError(
          '--bisect-repo requires good and bad values to be set.')

  return (args, unknown_args)


def VerifyInput(args, unknown_args):
  """Verifies with the user that the provided args are satisfactory.

  Args:
    args: The known args parsed by the argument parser
    unknown_args: The unknown args parsed by the argument parser
  """
  print '======'
  if args.manual_mode:
    print ('Script is running in manual mode - you must manually run gclient '
          'sync on each revision')
  if args.bisect_repo:
    print ('Script is set to bisect %s instead of Chromium src. gclient sync '
           'will not be run, so ensure you are synced to the correct revision '
           'and any patches, etc. you need are applied before running.' %
           args.bisect_repo)
  if args.binary_size_bisect:
    print 'Script is running in binary size bisect mode.'
  print 'This will start a bisect for a for:'
  print 'Metric: %s' % args.metric
  print 'Story: %s' % args.story
  if args.benchmark:
    print 'In the benchmark %s' % args.benchmark
  if args.good_value == None and args.bad_value == None:
    print 'The good and bad values at %s and %s will be determined' % (
        args.good_revision, args.bad_revision)
  elif args.good_value == None:
    print ('The good value at %s will be determined, and the bad value of %f '
           'at %s will be used' % (args.good_revision, args.bad_value,
            args.bad_revision))
  elif args.bad_value == None:
    print ('The good value of %f at %s will be used, and the bad value at %s '
           'will be determined' % (args.good_value, args.good_revision,
            args.bad_revision))
  else:
    print 'Changing from %f at %s to %f at %s' % (args.good_value,
        args.good_revision, args.bad_value, args.bad_revision)
  if args.checkout_overrides:
    for pair in args.checkout_overrides:
      for key, val in pair.iteritems():
        print '%s will be synced to revision %s' % (key, val)
  if args.apply_stash_before_sync:
    print 'The stash entry %s will be applied before each sync' % (
        args.apply_stash_before_sync)
  if args.num_attempts_before_marking_good > 1:
    print ('Each revision must be found to be good %d times before actually '
           'being marked as good' % args.num_attempts_before_marking_good)
  print 'The data format that will be expected is %s: %s' % (
      args.expected_json_result_format,
      SUPPORTED_JSON_RESULT_FORMATS[args.expected_json_result_format])
  print '======'
  if args.binary_size_bisect:
    print '%s will be built in both %s and %s' % (args.build_target,
                                                  args.build_output_dir,
                                                  args.diff_build_output_dir)
  else:
    print 'The test target %s will be built to %s' % (args.build_target,
                                                      args.build_output_dir)
  print '%d parallel jobs will be used with a load limit of %d' % (
      args.parallel_jobs, args.load_limit)
  if args.regenerate_args_after_sync:
    print 'The build output directory will be recreated after each sync'
  print '======'
  if not args.binary_size_bisect:
    print 'The target %s will be isolated and uploaded to %s' % (
        args.isolate_target, args.isolate_server)
    print 'The test will be triggered on %s with the following dimensions:' % (
        args.swarming_server)
    for pair in args.dimensions:
      for key, val in pair.iteritems():
        print '%s = %s' % (key, val)
    print '======'
  print 'The test will be run with these additional arguments:'
  for extra_arg in unknown_args:
    print extra_arg
  print '======'
  if args.reset_before_sync:
    print '**WARNING** This will run git reset --hard HEAD'
    print 'If you have any uncommitted changes, commit or stash them beforehand'
  if raw_input('Are these settings correct? y/N').lower() != 'y':
    print 'Aborting'
    sys.exit(1)


def SetupBisect(args):
  """Does all the one-time setup for a bisect.

  Args
    args: The parsed args from argparse
  Returns:
    The first revision to sync to
  """
  with SwitchDirsIfNotChromiumBisect(args):
    subprocess.check_output(['git', 'bisect', 'start'])
    subprocess.check_output(['git', 'bisect', 'good', args.good_revision])
    output = subprocess.check_output(
        ['git', 'bisect', 'bad', args.bad_revision])
    print output
    # Get the revision, which is between []
    revision = output.split('[', 1)[1].split(']', 1)[0]
  return revision


def RunTestOnSwarming(args, unknown_args, output_dir, use_new_perf_format):
  """Isolates the test target and runs it on swarming to get perf results.

  Args:
    args: The known args parsed by the argument parser
    unknown_args: The unknown args parsed by the argument parser
    output_dir: The directory to save swarming results to
    use_new_perf_format: Whether to use the new perf format that came with
        revision 0d271f583489024e3c163f0538d1ec29097b3615 or not.
  """
  print "=== Isolating and running target %s ===" % args.isolate_target
  print 'Isolating'
  subprocess.check_output(['python', os.path.join('tools', 'mb', 'mb.py'),
                           'isolate',
                           '//%s' % args.build_output_dir, args.isolate_target])
  print 'Uploading'
  output = subprocess.check_output([
      'python', os.path.join('tools', 'swarming_client', 'isolate.py'),
      'batcharchive', '--isolate-server', args.isolate_server,
      os.path.join(args.build_output_dir,
                   '%s.isolated.gen.json' % args.isolate_target)])
  isolate_hash = output.split(' ')[0]

  swarming_args = [
    'python', os.path.join('tools', 'swarming_client', 'swarming.py'), 'run',
    '--isolated', isolate_hash,
    '--isolate-server', args.isolate_server,
    '--swarming', args.swarming_server,
    '--task-output-dir', output_dir,
  ]
  for pair in args.dimensions:
    for key, val in pair.iteritems():
      swarming_args.extend(['--dimension', key, val])

  # Temporary workaround for https://crbug.com/812428. We could get the same
  # effect by isolating/uploading/running using "mb.py run -s", but that has
  # the issue of apparently not having a way to specify a task output directory.
  # So instead, manually append the additional arguments that running that way
  # would do for us to work around the vpython issues until they're fixed.
  # TODO(https://crbug.com/819719): Remove this when possible.
  cipd_packages = [
    '.swarming_module:infra/python/cpython/'
    '${platform}:version:2.7.14.chromium14',

    '.swarming_module:infra/tools/luci/logdog/butler/'
    '${platform}:git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c',

    '.swarming_module:infra/tools/luci/vpython-native/'
    '${platform}:git_revision:b6cdec8586c9f8d3d728b1bc0bd4331330ba66fc',

    '.swarming_module:infra/tools/luci/vpython/'
    '${platform}:git_revision:b6cdec8586c9f8d3d728b1bc0bd4331330ba66fc',
  ]
  for package in cipd_packages:
    swarming_args.extend(['--cipd-package', package])
  swarming_args.extend([
    '--named-cache',
    'swarming_module_cache_vpython', '.swarming_module_cache/vpython',

    '--env-prefix', 'PATH', '.swarming_module',
    '--env-prefix', 'PATH', '.swarming_module/bin',
    '--env-prefix', 'VPYTHON_VIRTUALENV_ROOT', '.swarming_module_cache/vpython',
  ])

  swarming_args.append('--')
  # Determine how we're supposed to pass the benchmark to run to the test
  if use_new_perf_format:
    # Telemetry tests in the new format use --benchmarks, non-Telemetry use
    # --gtest-benchmark-name. Non-Telemetry tests need to have --non-telemetry
    # passed to them in order to work, so check for the presence of that flag.
    is_non_telemetry = False
    for arg in unknown_args:
      if '--non-telemetry' in arg:
        is_non_telemetry = True
        break
    if is_non_telemetry:
      swarming_args.append('--gtest-benchmark-name=%s' % args.benchmark)
    else:
      swarming_args.append('--benchmarks=%s' % args.benchmark)

  else:
    # The old perf format simply passed the benchmark to run as the first
    # positional argument
    swarming_args.append(args.benchmark)

  swarming_args.extend(unknown_args)
  swarming_args.extend([
      '--isolated-script-test-output',
      '${ISOLATED_OUTDIR}/output.json',
      '--isolated-script-test-perf-output',
      '${ISOLATED_OUTDIR}/perftest-output.json',
      '--output-format', 'chartjson',
      '--chromium-output-directory', args.build_output_dir])
  print 'Running test %s' % (
      '(new format)' if use_new_perf_format else '(old format)')
  subprocess.check_output(swarming_args)


def RunBinarySizeDiff(args, output_dir):
  """Locally runs a binary size diff on the two APKs specified by args.

  Args:
    args: The known args parsed from the argument parser
    output_dir: The directory to save diff results to
  """
  print 'Diffing APKs'
  subprocess.check_output(
      ['python', os.path.join('build', 'android', 'diff_resource_sizes.py'),
       '--base-apk', os.path.join(args.build_output_dir, 'apks', args.apk_name),
       '--chromium-output-directory-base', args.build_output_dir,
       '--diff-apk',
       os.path.join(args.diff_build_output_dir, 'apks', args.apk_name),
       '--chromium-output-directory-diff', args.diff_build_output_dir,
       '--include-intermediate-results',
       '--chartjson',
       '--output-dir', output_dir])


def GetSwarmingResult(args, output_dir, use_new_perf_format):
  """Extracts the value for the story/metric combo of interest from swarming.

  Args:
    args: The known args parsed from the argument parser
    output_dir: The directory where swarming results have been saved to
    use_new_perf_format: Whether to use the new perf format that came with
        revision 0d271f583489024e3c163f0538d1ec29097b3615 or not.

  Returns:
    The value for the story/metric combo that the last swarming run produced
  """
  outfile = os.path.join(output_dir, '0', 'perftest-output.json')
  if use_new_perf_format:
    outfile = os.path.join(output_dir, '0', args.benchmark, 'perf_results.json')
  return _GetResultsFromJson(args, outfile)


def GetBinarySizeResult(args, output_dir):
  """Extracts the value for the story/metric combo of interest locally.

  Args:
    args: The known args parsed from the argument parser
    output_dir: The directory where local results have been saved to

  Returns:
    The value for the story/metric combo that the last binary size diff produced
  """
  return _GetResultsFromJson(args,
                             os.path.join(output_dir, 'results-chart.json'))


def _GetResultsFromJson(args, filepath):
  with open(filepath, 'r') as infile:
    perf_results = json.load(infile)
    all_results = []
    if args.expected_json_result_format == 'chartjson':
      # Perf tests use a 'values' array, while binary size uses a single 'value'
      # field. So, check for both.
      story = perf_results.get(unicode('charts'), {}).get(
          unicode(args.metric), {}).get(unicode(args.story), {})
      all_results = story.get(unicode('values'), [])
      if 'value' in story:
        all_results = [story[unicode('value')]]
    elif args.expected_json_result_format == 'printedjson':
      all_results = perf_results.get(args.metric, {}).get('traces', {}).get(
          args.story, [])
    if len(all_results) == 0:
      raise RuntimeError('Got no results for the story/metric combo. '
                         'Is there a typo in one of them?')
    result = all_results[0]
    print 'Got result %s' % str(result)
  return float(result)


def RunBisectStep(args, unknown_args, revision, output_dir):
  """Runs a bisect step for a revision.

  This will run recursively until the culprit CL is found.

  Args:
    args: The known args parsed from the argument parser
    unknown_args: The unknown args parsed from the argument parser
    revision: The git revision to sync to and test
    output_dir: The directory to save swarming results to
  """
  revision_good = True
  for attempt in xrange(1, args.num_attempts_before_marking_good + 1):
    # Only bother syncing and building if this is our first attempt on this
    # revision.
    result = GetValueAtRevision(args, unknown_args, revision, output_dir,
        sync=(attempt == 1))
    # Regression was an increased value.
    if args.bad_value > args.good_value:
      # If we're greater than the provided bad value or between good and bad,
      # but closer to bad, we're still bad.
      if (result > args.bad_value or
          abs(args.bad_value - result) < abs(args.good_value - result)):
        print '=== Attempt %d found revision that is BAD ===' % attempt
        revision_good = False
        break
      else:
        print '=== Attempt %d found that revision is GOOD ===' % attempt
    # Regression was a decreased value.
    else:
      # If we're smaller than the provided bad value or between good and bad,
      # but closer to bad, we're still bad.
      if (result < args.bad_value or
          abs(args.bad_value - result) < abs(args.good_value - result)):
        print '=== Attempt %d found that revision is BAD ===' % attempt
        revision_good = False
        break
      else:
        print '=== Attempt %d found that revision is GOOD ===' % attempt

  output = ""
  with SwitchDirsIfNotChromiumBisect(args):
    if revision_good:
      print '=== Current revision is GOOD ==='
      output = subprocess.check_output(['git', 'bisect', 'good', revision])
    else:
      print '=== Current revision is BAD ==='
      output = subprocess.check_output(['git', 'bisect', 'bad', revision])

  print output
  if output.startswith('Bisecting:'):
    RunBisectStep(args, unknown_args, output.split('[', 1)[1].split(']', 1)[0],
        output_dir)


def BuildTarget(args):
  print 'Building'
  subprocess.check_output(['ninja', '-C', args.build_output_dir,
                           '-j', str(args.parallel_jobs),
                           '-l', str(args.load_limit), args.build_target])
  if args.binary_size_bisect:
    subprocess.check_output(['ninja', '-C', args.diff_build_output_dir,
                             '-j', str(args.parallel_jobs),
                             '-l', str(args.load_limit), args.build_target])


def RegenerateGnArgs(args):
  """Recreates the build output directory using existing GN args."""
  directories = [args.build_output_dir]
  if args.binary_size_bisect:
    directories.append(args.diff_build_output_dir)
  for d in directories:
    with open(os.path.join(d, 'args.gn'), 'r') as args_file:
      gn_args = args_file.read()
    shutil.rmtree(d)
    os.mkdir(d)
    with open(os.path.join(d, 'args.gn'), 'w') as args_file:
      args_file.write(gn_args)
    subprocess.check_output(['gn', 'gen', d])


def SyncAndBuild(args, unknown_args, revision):
  """Syncs to the given revision and builds the test target.

  Args:
    args: The known args parsed by the argument parser
    unknown_args: The unknown args parsed by the argument parser
    revision: The revision to sync to and build
  """
  if args.manual_mode:
    print ('=== Waiting on user input to start build/run process for %s ===' %
        revision)
    raw_input('Press any key to continue')
    print '=== Building ==='
  else:
    print '=== Syncing to revision %s and building ===' % revision
    # Sometimes random files show up as unstaged changes (???), so make sure
    # that isn't the case before we try to run gclient sync
    if args.reset_before_sync:
      subprocess.check_output(['git', 'reset', '--hard', 'HEAD'])
    sync_revision = revision
    if args.apply_stash_before_sync:
      print 'Applying stash entry %s' % args.apply_stash_before_sync
      subprocess.check_output(
          ['git', 'stash', 'apply', args.apply_stash_before_sync])
      subprocess.check_output(['git', 'add', '-u'])
      subprocess.check_output(['git', 'commit', '-m', 'Apply stash.'])
      sync_revision = 'HEAD'
    print 'Syncing'
    output = subprocess.check_output(['gclient', 'sync', '-r',
        'src@%s' % sync_revision])
    if ('error: Your local changes to the following files would be overwritten '
        'by checkout:' in output):
      raise RuntimeError('Could not run gclient sync due to uncommitted '
          'changes. If these changes are actually yours, please commit or '
          'stash them. If they are not, remove them and try again. If the '
          'issue persists, try running with --reset-before-sync')

  # Ensure that the VR assets are synced to the current revision since it isn't
  # guaranteed that gclient will handle it properly
  # TODO(https://crbug.com/823882): Remove this once asset downloading is more
  # robust in gclient.
  subprocess.check_output([
      'python', 'third_party/depot_tools/download_from_google_storage.py',
      '--bucket', 'chrome-vr-assets',
      '--recursive',
      '--directory', 'chrome/browser/resources/vr/assets/google_chrome'])

  # Checkout any specified revisions.
  cwd = os.getcwd()
  for override in args.checkout_overrides:
    for repo, rev in override.iteritems():
      os.chdir(repo)
      subprocess.check_output(['git', 'checkout', rev])
      os.chdir(cwd)
  if args.regenerate_args_after_sync:
    RegenerateGnArgs(args)
  BuildTarget(args)


def BisectRegression(args, unknown_args):
  """Runs all steps necessary to bisect a perf regression.

  Intermediate steps and the culprit CL will be printed to stdout.

  Args:
    args: The known args parsed by the argument parser
    unknown_args: The unknown args parsed by the argument parser
  """
  with TempDir() as output_dir:
    # Ensure that we also sync any APKs we use
    os.environ['DOWNLOAD_VR_TEST_APKS'] = '1'
    try:
      if args.good_value == None:
        # Once we've run "git bisect start" and set the good/bad revisions,
        # we'll be in a detached head state before we sync. However, the git
        # bisect has to start after this point, so we can't use that behavior
        # here. So, manually sync to the revision to get into a detached state.
        subprocess.check_output(['git', 'checkout', args.good_revision])
        args.good_value = GetValueAtRevision(args, unknown_args,
            args.good_revision, output_dir)
        print '=== Got initial good value of %f ===' % args.good_value
      if args.bad_value == None:
        subprocess.check_output(['git', 'checkout', args.bad_revision])
        args.bad_value = GetValueAtRevision(args, unknown_args,
            args.bad_revision, output_dir)
        print '=== Got initial bad value of %f ===' % args.bad_value
      revision = SetupBisect(args)
      RunBisectStep(args, unknown_args, revision, output_dir)
    finally:
      with SwitchDirsIfNotChromiumBisect(args):
        subprocess.check_output(['git', 'bisect', 'reset'])


def GetValueAtRevision(args, unknown_args, revision, output_dir, sync=True):
  """Builds and runs the test at a particular revision.

  Args:
    args: The known args parsed by the argument parser
    unknown_args: The unknown args parsed by the argument parser
    revision: The revision to sync to and build
    output_dir: The directory to store swarming results to

  Returns:
    The value of the story/metric combo at the given revision
  """
  # In the case where we're bisecting a repo other than Chromium src,
  # "git bisect"'s automatic checkouts will be enough to ensure we're at the
  # correct revision, so we can just build immediately.
  if args.bisect_repo:
    print '=== Building with %s at revision %s ===' % (
        args.bisect_repo, revision)
    BuildTarget(args)
  elif sync:
    SyncAndBuild(args, unknown_args, revision)
  if args.binary_size_bisect:
    RunBinarySizeDiff(args, output_dir)
    return GetBinarySizeResult(args, output_dir)
  else:
    use_new_perf_format = _IsCurrentRevisionAfterFormatChange(revision)
    RunTestOnSwarming(args, unknown_args, output_dir, use_new_perf_format)
    return GetSwarmingResult(args, output_dir, use_new_perf_format)


def _IsCurrentRevisionAfterFormatChange(revision):
  """Determines whether we need to use the new or old perf format.

  With commit 0d271f583489024e3c163f0538d1ec29097b3615, the VR perf tests moved
  to use the newer run_performance_tests.py script. This changed the output
  file name and the way which benchmark to run is specified, so we need to
  know where we are in relation to that commit in order to know how to run
  tests.

  Args:
    revision: The currently synced revision

  Returns:
    True if the current revision comes after the commit that changed how perf
    tests are run, False otherwise
  """
  if revision == PERF_FORMAT_CHANGE_REVISION:
    return True
  # Check how many revisions after the format change revision we are - if it's
  # non-zero, we're at some point after the format got changed, otherwise we're
  # before.
  num_revisions_after = subprocess.check_output(
      ['git',
       'rev-list',
       '%s..%s' % (PERF_FORMAT_CHANGE_REVISION, revision),
       '--count'])
  return int(num_revisions_after) > 0


def main():
  VerifyCwd()
  args, unknown_args = ParseArgsAndAssertValid()
  VerifyInput(args, unknown_args)
  BisectRegression(args, unknown_args)

if __name__ == '__main__':
  main()
