#!/usr/bin/env python
# Copyright 2015 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.

"""Toolbox to manage all the json files in this directory.

It can reformat them in their canonical format or ensures they are well
formatted.
"""

import argparse
import ast
import collections
import glob
import json
import os
import subprocess
import sys


THIS_DIR = os.path.dirname(os.path.abspath(__file__))
SRC_DIR = os.path.dirname(os.path.dirname(THIS_DIR))
BLINK_DIR = os.path.join(SRC_DIR, 'third_party', 'WebKit')
sys.path.insert(0, os.path.join(SRC_DIR, 'third_party', 'colorama', 'src'))

import colorama


SKIP = {
  # These are not 'builders'.
  'compile_targets', 'gtest_tests', 'filter_compile_builders',
  'non_filter_builders', 'non_filter_tests_builders',

  # These are not supported on Swarming yet.

  # Android Cloud is still experimental and involves spinning up an Android
  # instance on GCE.  Swarming doesn't work in that environment yet.
  'Android Cloud Tests',

  # Recipes don't promise execution on jelly bean.  This could work if the
  # OS dimensions go into the recipe, they're set in the json file, and
  # jelly bean devices are in the pool.  For now, just blacklist.
  'Jelly Bean Tester',
  'Lollipop Consumer Tester',
  'Lollipop Low-end Tester',

  # Android bots need custom dimension_sets entries for swarming, and capacity
  # is not there yet -- so don't let manage.py add swarming automatically there.
  'Android User Builder Tests',
  'Android GN',

  # http://crbug.com/441429
  'Linux Trusty (32)', 'Linux Trusty (dbg)(32)',

  # Swarming may not work on Mac10.10,11,12; need to
  # re-investigate and confirm.
  'WebKit Mac10.10',
  'WebKit Mac10.11',
  'WebKit Mac10.12',
  'WebKit Mac10.11 (dbg)',
  'WebKit Mac10.12 (retina)',
  'Chromium Mac10.10 Tests',
  'Chromium Mac10.11 Tests',

  # One off builders. Note that Swarming does support ARM.
  'Linux ARM Cross-Compile',
  'Site Isolation Android',
  'Site Isolation Linux',
  'Site Isolation Win',
}


SKIP_GN_ISOLATE_MAP_TARGETS = {
  # This target is magic and not present in gn_isolate_map.pyl.
  'all',
  'remoting/client:client',
  'remoting/host:host',

  # These targets are listed only in build-side recipes.
  'All_syzygy',
  'blink_tests',
  'cast_shell',
  'cast_shell_apk',
  'chrome_official_builder',
  'chrome_official_builder_no_unittests',
  'chromium_builder_asan',
  'chromium_builder_perf',
  'chromiumos_preflight',
  'mini_installer',
  'previous_version_mini_installer',

  # iOS tests are listed in //ios/build/bots.
  'cronet_test',
  'cronet_unittests_ios',
  'ios_chrome_adaptive_toolbar_egtests',
  'ios_chrome_bookmarks_egtests',
  'ios_chrome_integration_egtests',
  'ios_chrome_payments_egtests',
  'ios_chrome_reading_list_egtests',
  'ios_chrome_settings_egtests',
  'ios_chrome_smoke_egtests',
  'ios_chrome_ui_egtests',
  'ios_chrome_unittests',
  'ios_chrome_web_egtests',
  'ios_components_unittests',
  'ios_net_unittests',
  "ios_remoting_unittests",
  'ios_showcase_egtests',
  'ios_web_inttests',
  'ios_web_shell_egtests',
  'ios_web_unittests',
  'ios_web_view_inttests',
  'ios_web_view_unittests',
  'ocmock_support_unittests',

  # These are listed in Builders that are skipped for other reasons.
  'chrome_junit_tests',
  'components_background_task_scheduler_junit_tests',
  'components_gcm_driver_junit_tests',
  'components_invalidation_impl_junit_tests',
  'components_policy_junit_tests',
  'components_variations_junit_tests',
  'components_web_restrictions_junit_tests',
  'content_junit_tests',
  'content_junit_tests',
  'device_junit_tests',
  'junit_unit_tests',
  'media_router_e2e_tests',
  'media_router_perf_tests',
  'motopho_latency_test',
  'net_junit_tests',
  'net_junit_tests',
  'service_junit_tests',
  'system_webview_apk',
  'ui_junit_tests',
  'vrcore_fps_test',
  'vr_common_perftests',
  'vr_perf_tests',
  'webapk_client_junit_tests',
  'webapk_shell_apk_junit_tests',

  # These tests are only run on WebRTC CI.
  'AppRTCMobileTest',
  'android_junit_tests',
  'audio_decoder_unittests',
  'common_audio_unittests',
  'common_video_unittests',
  'frame_analyzer',
  'libjingle_peerconnection_android_unittest',
  'modules_tests',
  'modules_unittests',
  'peerconnection_unittests',
  'rtc_media_unittests',
  'rtc_pc_unittests',
  'rtc_stats_unittests',
  'rtc_unittests',
  'system_wrappers_unittests',
  'test_support_unittests',
  'tools_unittests',
  'video_engine_tests',
  'voice_engine_unittests',
  'webrtc_nonparallel_tests',
  'xmllite_xmpp_unittests',

  # isolate is currently too slow for this target.
  # http://crbug.com/524758
  'webkit_layout_tests',
  'webkit_layout_tests_exparchive',

  # These are only run on V8 CI.
  'pdfium_test',
  'postmortem-metadata',
}


class Error(Exception):
  """Processing error."""


def get_isolates():
  """Returns the list of all isolate files."""

  def git_ls_files(cwd):
    return subprocess.check_output(['git', 'ls-files'], cwd=cwd).splitlines()

  files = git_ls_files(SRC_DIR) + git_ls_files(BLINK_DIR)
  return [os.path.basename(f) for f in files if f.endswith('.isolate')]


def process_builder_convert(data, test_name):
  """Converts 'test_name' to run on Swarming in 'data'.

  Returns True if 'test_name' was found.
  """
  result = False
  for test in data['gtest_tests']:
    if test['test'] != test_name:
      continue
    test.setdefault('swarming', {})
    if not test['swarming'].get('can_use_on_swarming_builders'):
      test['swarming']['can_use_on_swarming_builders'] = True
    result = True
  return result


def process_builder_remaining(data, filename, builder, tests_location):
  """Calculates tests_location when mode is --remaining."""
  for test in data['gtest_tests']:
    name = test['test']
    if test.get('swarming', {}).get('can_use_on_swarming_builders'):
      tests_location[name]['count_run_on_swarming'] += 1
    else:
      tests_location[name]['count_run_local'] += 1
      tests_location[name]['local_configs'].setdefault(
          filename, []).append(builder)


def process_file(mode, test_name, tests_location, filepath, ninja_targets,
                 ninja_targets_seen):
  """Processes a json file describing what tests should be run for each recipe.

  The action depends on mode. Updates tests_location.

  Return False if the process exit code should be 1.
  """
  filename = os.path.basename(filepath)
  with open(filepath) as f:
    content = f.read()
  try:
    config = json.loads(content)
  except ValueError as e:
    raise Error('Exception raised while checking %s: %s' % (filepath, e))

  for builder, data in sorted(config.iteritems()):
    if builder in SKIP:
      # Oddities.
      continue
    if not isinstance(data, dict):
      raise Error('%s: %s is broken: %s' % (filename, builder, data))
    if ('gtest_tests' not in data and
        'isolated_scripts' not in data and
        'additional_compile_targets' not in data and
        'instrumentation_tests' not in data):
      continue

    for d in data.get('junit_tests', []):
      test = d['test']
      if (test not in ninja_targets and
          test not in SKIP_GN_ISOLATE_MAP_TARGETS):
        raise Error('%s: %s / %s is not listed in gn_isolate_map.pyl' %
                    (filename, builder, test))
      elif test in ninja_targets:
        ninja_targets_seen.add(test)

    for target in data.get('additional_compile_targets', []):
      if (target not in ninja_targets and
          target not in SKIP_GN_ISOLATE_MAP_TARGETS):
        raise Error('%s: %s / %s is not listed in gn_isolate_map.pyl' %
                    (filename, builder, target))
      elif target in ninja_targets:
        ninja_targets_seen.add(target)

    gtest_tests = data.get('gtest_tests', [])
    if not isinstance(gtest_tests, list):
      raise Error(
          '%s: %s is broken: %s' % (filename, builder, gtest_tests))
    if not all(isinstance(g, dict) for g in gtest_tests):
      raise Error(
          '%s: %s is broken: %s' % (filename, builder, gtest_tests))

    seen = set()
    for d in gtest_tests:
      test = d['test']
      if (test not in ninja_targets and
          test not in SKIP_GN_ISOLATE_MAP_TARGETS):
        raise Error('%s: %s / %s is not listed in gn_isolate_map.pyl.' %
                    (filename, builder, test))
      elif test in ninja_targets:
        ninja_targets_seen.add(test)

      name = d.get('name', d['test'])
      if name in seen:
        raise Error('%s: %s / %s is listed multiple times.' %
                    (filename, builder, name))
      seen.add(name)
      d.setdefault('swarming', {}).setdefault(
          'can_use_on_swarming_builders', False)

    if gtest_tests:
      config[builder]['gtest_tests'] = sorted(
          gtest_tests, key=lambda x: x['test'])

    for d in data.get('isolated_scripts', []):
      name = d['isolate_name']
      if (name not in ninja_targets and
          name not in SKIP_GN_ISOLATE_MAP_TARGETS):
        raise Error('%s: %s / %s is not listed in gn_isolate_map.pyl.' %
                    (filename, builder, name))
      elif name in ninja_targets:
        ninja_targets_seen.add(name)

    for d in data.get('instrumentation_tests', []):
      name = d['test']
      if (name not in ninja_targets and
          name not in SKIP_GN_ISOLATE_MAP_TARGETS):
        raise Error('%s: %s / %s is not listed in gn_isolate_map.pyl.' %
                    (filename, builder, name))
      elif name in ninja_targets:
        ninja_targets_seen.add(name)

    # The trick here is that process_builder_remaining() is called before
    # process_builder_convert() so tests_location can be used to know how many
    # tests were converted.
    if mode in ('convert', 'remaining'):
      process_builder_remaining(data, filename, builder, tests_location)
    if mode == 'convert':
      process_builder_convert(data, test_name)

  expected = json.dumps(
      config, sort_keys=True, indent=2, separators=(',', ': ')) + '\n'
  if content != expected:
    if mode in ('convert', 'write'):
      with open(filepath, 'wb') as f:
        f.write(expected)
      if mode == 'write':
        print('Updated %s' % filename)
    else:
      print('%s is not in canonical format' % filename)
      print('run `testing/buildbot/manage.py -w` to fix')
    return mode != 'check'
  return True


def print_convert(test_name, tests_location):
  """Prints statistics for a test being converted for use in a CL description.
  """
  data = tests_location[test_name]
  print('Convert %s to run exclusively on Swarming' % test_name)
  print('')
  print('%d configs already ran on Swarming' % data['count_run_on_swarming'])
  print('%d used to run locally and were converted:' % data['count_run_local'])
  for master, builders in sorted(data['local_configs'].iteritems()):
    for builder in builders:
      print('- %s: %s' % (master, builder))
  print('')
  print('Ran:')
  print('  ./manage.py --convert %s' % test_name)
  print('')
  print('R=')
  print('BUG=98637')


def print_remaining(test_name, tests_location):
  """Prints a visual summary of what tests are yet to be converted to run on
  Swarming.
  """
  if test_name:
    if test_name not in tests_location:
      raise Error('Unknown test %s' % test_name)
    for config, builders in sorted(
        tests_location[test_name]['local_configs'].iteritems()):
      print('%s:' % config)
      for builder in sorted(builders):
        print('  %s' % builder)
    return

  isolates = get_isolates()
  l = max(map(len, tests_location))
  print('%-*s%sLocal       %sSwarming  %sMissing isolate' %
      (l, 'Test', colorama.Fore.RED, colorama.Fore.GREEN,
        colorama.Fore.MAGENTA))
  total_local = 0
  total_swarming = 0
  for name, location in sorted(tests_location.iteritems()):
    if not location['count_run_on_swarming']:
      c = colorama.Fore.RED
    elif location['count_run_local']:
      c = colorama.Fore.YELLOW
    else:
      c = colorama.Fore.GREEN
    total_local += location['count_run_local']
    total_swarming += location['count_run_on_swarming']
    missing_isolate = ''
    if name + '.isolate' not in isolates:
      missing_isolate = colorama.Fore.MAGENTA + '*'
    print('%s%-*s %4d           %4d    %s' %
        (c, l, name, location['count_run_local'],
          location['count_run_on_swarming'], missing_isolate))

  total = total_local + total_swarming
  p_local = 100. * total_local / total
  p_swarming = 100. * total_swarming / total
  print('%s%-*s %4d (%4.1f%%)   %4d (%4.1f%%)' %
      (colorama.Fore.WHITE, l, 'Total:', total_local, p_local,
        total_swarming, p_swarming))
  print('%-*s                %4d' % (l, 'Total executions:', total))


def main():
  colorama.init()
  parser = argparse.ArgumentParser(description=sys.modules[__name__].__doc__)
  group = parser.add_mutually_exclusive_group(required=True)
  group.add_argument(
      '-c', '--check', dest='mode', action='store_const', const='check',
      default='check', help='Only check the files')
  group.add_argument(
      '--convert', dest='mode', action='store_const', const='convert',
      help='Convert a test to run on Swarming everywhere')
  group.add_argument(
      '--remaining', dest='mode', action='store_const', const='remaining',
      help='Count the number of tests not yet running on Swarming')
  group.add_argument(
      '-w', '--write', dest='mode', action='store_const', const='write',
      help='Rewrite the files')
  parser.add_argument(
      'test_name', nargs='?',
      help='The test name to print which configs to update; only to be used '
           'with --remaining')
  args = parser.parse_args()

  if args.mode == 'convert':
    if not args.test_name:
      parser.error('A test name is required with --convert')
    if args.test_name + '.isolate' not in get_isolates():
      parser.error('Create %s.isolate first' % args.test_name)

  # Stats when running in --remaining mode;
  tests_location = collections.defaultdict(
      lambda: {
        'count_run_local': 0, 'count_run_on_swarming': 0, 'local_configs': {}
      })

  with open(os.path.join(THIS_DIR, "gn_isolate_map.pyl")) as fp:
    gn_isolate_map = ast.literal_eval(fp.read())
    ninja_targets = {k: v['label'] for k, v in gn_isolate_map.items()}

  try:
    result = 0
    ninja_targets_seen = set()
    for filepath in glob.glob(os.path.join(THIS_DIR, '*.json')):
      if not process_file(args.mode, args.test_name, tests_location, filepath,
                          ninja_targets, ninja_targets_seen):
        result = 1

    extra_targets = (set(ninja_targets) - ninja_targets_seen -
                     SKIP_GN_ISOLATE_MAP_TARGETS)
    if extra_targets:
      if len(extra_targets) > 1:
        extra_targets_str = ', '.join(extra_targets) + ' are'
      else:
        extra_targets_str = list(extra_targets)[0] + ' is'
      raise Error('%s listed in gn_isolate_map.pyl but not in any .json '
                  'files' % extra_targets_str)

    if args.mode == 'convert':
      print_convert(args.test_name, tests_location)
    elif args.mode == 'remaining':
      print_remaining(args.test_name, tests_location)
    return result
  except Error as e:
    sys.stderr.write('%s\n' % e)
    return 1


if __name__ == "__main__":
  sys.exit(main())
