# 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.

from recipe_engine import post_process
from recipe_engine.types import freeze

DEPS = [
  'chromium',
  'chromium_checkout',
  'chromium_tests',
  'depot_tools/bot_update',
  'depot_tools/gclient',
  'depot_tools/gerrit',
  'depot_tools/tryserver',
  'filter',
  'gn',
  'recipe_engine/context',
  'recipe_engine/file',
  'recipe_engine/json',
  'recipe_engine/path',
  'recipe_engine/platform',
  'recipe_engine/properties',
  'recipe_engine/python',
  'recipe_engine/raw_io',
  'recipe_engine/step',
]

BUILDERS = freeze({
  'tryserver.chromium.linux': {
    'builders': {
      'linux-libfuzzer-asan-rel': {
        'chromium_config': 'chromium',
        'gclient_config': 'chromium',
        'chromium_config_kwargs': {
          'BUILD_CONFIG': 'Release',
          'TARGET_PLATFORM': 'linux',
          'TARGET_BITS': 64,
        },
      },
    },
  },
  'tryserver.chromium.win': {
    'builders': {
      'win-libfuzzer-asan-rel': {
        'chromium_config': 'chromium_clang',
        'gclient_config': 'chromium',
        'chromium_config_kwargs': {
          'BUILD_CONFIG': 'Release',
          'TARGET_PLATFORM': 'win',
          'TARGET_BITS': 64,
        },
      },
    },
  },
})

INCLUDED_FUZZ_TARGETS = ['//testing/libfuzzer:libfuzzer_main']
EXCLUDED_FUZZ_TARGETS = ['//testing/libfuzzer:no_clusterfuzz']


def RunSteps(api):
  assert api.tryserver.is_tryserver

  with api.chromium.chromium_layout():
    mastername = api.m.properties['mastername']
    buildername, bot_config = api.chromium.configure_bot(BUILDERS, ['mb'])

    bot_config = {}
    api.chromium_checkout.ensure_checkout(bot_config)
    checkout_dir = api.chromium_checkout.get_checkout_dir(bot_config).join(
        'src')
    with api.context(cwd=checkout_dir):
      outdir = api.chromium.output_dir

      api.chromium.runhooks()
      api.chromium.ensure_goma()
      api.chromium.mb_gen(mastername, buildername, use_goma=True)

      # Calculate the GN labels of all fuzz targets.
      all_fuzz_labels = api.gn.refs(
          outdir, INCLUDED_FUZZ_TARGETS, output_type='executable',
          step_name='calculate all_fuzzers', output_format='label')
      excluded_fuzz_labels = api.gn.refs(
          outdir, EXCLUDED_FUZZ_TARGETS, output_type='executable',
          step_name='calculate no_fuzzers', output_format='label')
      fuzz_labels = list(all_fuzz_labels - excluded_fuzz_labels)

      # Filter out all targets that the patch doesn't affect.
      affected_files = api.chromium_checkout.get_files_affected_by_patch()
      test_targets, compile_targets = api.filter.analyze(
          affected_files, None, fuzz_labels, 'trybot_analyze_config.json')
      affected_fuzz_labels = test_targets + compile_targets
      if not affected_fuzz_labels:
        return

      # Run MB one more time since filter calls above wipes out the specified
      # goma dir.
      api.chromium.mb_gen(
          mastername, buildername, use_goma=True, gn_args_location=api.gn.LOGS)

      # Convert the GN labels to ninja targets and pass them into compile.
      affected_fuzz_targets = list(api.gn.ls(
          outdir, affected_fuzz_labels, output_format='output'))
      api.chromium.compile(targets=affected_fuzz_targets, use_goma_module=True)


def GenTests(api):
  yield (
    api.test('basic_linux_tryjob') +
    api.properties.tryserver(mastername='tryserver.chromium.linux',
                             buildername='linux-libfuzzer-asan-rel') +
    api.step_data('calculate all_fuzzers',
        stdout=api.raw_io.output_text(
            '//foo/bar:target1\n//foo/bar:target2\n//foo/bar:target3')) +
    api.step_data('calculate no_fuzzers',
        stdout=api.raw_io.output_text('//foo/bar:target1'))
  )

  yield (
    api.test('basic_linux_tryjob_with_compile') +
    api.properties.tryserver(mastername='tryserver.chromium.linux',
                             buildername='linux-libfuzzer-asan-rel') +
    api.step_data('calculate all_fuzzers',
        stdout=api.raw_io.output_text(
            '\n'.join(['//foo/bar:target1', '//foo/bar:target2',
                       '//foo/bar:target3']))) +
    api.step_data('calculate no_fuzzers',
        stdout=api.raw_io.output_text('//foo/bar:target1')) +
    api.override_step_data(
        'analyze',
        api.json.output({
            'status': 'Found dependency',
            'compile_targets': ['//foo/bar:target2'],
            'test_targets': []})) +
    api.step_data('list gn targets',
        stdout=api.raw_io.output_text('target2'))
  )
