# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for testing Recipes."""

import fnmatch
import os

from PB.go.chromium.org.luci.buildbucket.proto import build as build_pb2
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from recipe_engine.recipe_api import Property

from RECIPE_MODULES.fuchsia.utils.api import memoize

DEPS = [
    'fuchsia/build_input_resolver',
    'fuchsia/buildbucket_util',
    'fuchsia/checkout',
    'fuchsia/commit_queue',
    'fuchsia/gerrit',
    'fuchsia/git',
    'fuchsia/gitiles',
    'fuchsia/status_check',
    'fuchsia/swarming_retry',
    'fuchsia/spec',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/json',
    'recipe_engine/led',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/python',
    'recipe_engine/raw_io',
    'recipe_engine/step',
    'recipe_engine/swarming',
    'recipe_engine/time',
]

PROPERTIES = {
    'project':
        Property(kind=str, help='Jiri remote manifest project', default=None),
    'manifest':
        Property(kind=str, help='Jiri manifest to use'),
    'remote':
        Property(kind=str, help='Remote manifest repository'),
    # If this build is being triggered from a change to this recipe, we need
    # to explicitly pass a CL. The most recent passing run of
    # fuchsia.try/recipes could take anywhere from about three to 200 minutes,
    # and the three minute version does not test much of what this recipe
    # actually does. In that case alter the recipes build to run on a specific
    # CL that modifies the cobalt recipe alone. (The cobalt build usually
    # takes less than 10 minutes.)
    'selftest_cl':
        Property(
            kind=str,
            help='CL to test with when this file changes',
            default='https://fuchsia-review.googlesource.com/c/303171'),
    'unittest_only':
        Property(kind=bool, help='Finish after unit tests', default=False),
}

ONE_DAY = 24 * 60 * 60
MAX_BUILD_AGE_SECONDS = 4 * 7 * ONE_DAY


def get_affected_recipes(api):
  """Collect affected recipes. For now assume we care about all recipes."""

  with api.step.nest('get_affected_recipes') as parent_step:
    recipes_root = api.path['start_dir'].join('infra').join('recipes')
    recipes_dir = recipes_root.join('recipes')
    recipe_files = api.file.listdir('ls-recipes', recipes_dir, recursive=True)

    all_recipes = []
    for recipe_file in recipe_files:
      path = os.path.relpath(
          api.path.realpath(recipe_file), api.path.realpath(recipes_dir))
      # Files inside folders that end in ".resources" are never recipes.
      if os.path.dirname(path).endswith('.resources'):
        continue

      name, ext = os.path.splitext(path)
      if ext == '.py':
        all_recipes.append(name)

    parent_step.presentation.logs['all recipes'] = all_recipes

    # Note that this command looks at the differences present in the most
    # recent commit. It ignores any local changes.
    # TODO(IN-1239) do something intelligent if local changes are present
    with api.context(cwd=recipes_root):
      changed_files = api.git.get_changed_files(commit='HEAD')
    parent_step.presentation.logs['changed files (raw)'] = changed_files

    def is_expected_json(path):
      # We want to ignore expected JSON files--they won't affect how recipes
      # run. It's possible there are JSON files used as data for recipes
      # instead of as expected test outputs, so determine which files to
      # ignore very narrowly.
      return (os.path.splitext(path)[1] == '.json' and
              os.path.dirname(path).endswith('.expected'))

    def is_python_test_file(path):
      # We want to ignore test_api.py files--they won't affect how recipes
      # run in led, they only affect how recipes run in
      # './recipes test run', and we test that every time any recipe is
      # changed.
      if (os.path.basename(path) == 'test_api.py' and
          os.path.dirname(os.path.dirname(path)) == 'recipe_modules'):
        return True

      # Also ignore test definitions themselves. By convention these are
      # given the filename 'full.py' in Fuchsia, but there is no
      # guarantee this will remain the case.
      if (os.path.splitext(path)[1] == '.py' and
          os.path.basename(os.path.dirname(path)) in ('tests', 'examples')):
        return True

      return False

    def is_ignored_file(path):
      return is_expected_json(path) or is_python_test_file(path)

    filtered_changed_files = [
        x for x in changed_files if not is_ignored_file(x)
    ]
    parent_step.presentation.logs['changed files (filtered)'] = (
        filtered_changed_files or ['no changed files'])

    res = api.step('recipes-analyze', [
        recipes_root.join('recipes.py'), 'analyze',
        api.json.input({
            'recipes': all_recipes,
            'files': filtered_changed_files
        }),
        api.json.output()
    ])

    affected_recipes = res.json.output['recipes']

    def should_test_all_recipes(path):
      globs = (
          'infra/config/recipes.cfg',
          # We particularly care about running CQ for fuchsia.proto changes.
          'recipe_proto/*.proto',
      )
      return any(fnmatch.fnmatch(path, glob) for glob in globs)

    special_changed_files = [
        f for f in changed_files if should_test_all_recipes(f)
    ]
    if special_changed_files:
      step = api.step('mark all recipes as affected', None)
      step.presentation.step_summary_text = 'because these files were changed:'
      step.presentation.step_text = '\n' + '\n'.join(special_changed_files)
      affected_recipes = all_recipes

    parent_step.presentation.logs['affected recipes'] = affected_recipes

    return affected_recipes


def get_last_green_build(api, builder):
  """Returns the build proto for a builder's most recent successful build.

  If no build younger than `MAX_BUILD_AGE_SECONDS` is found, returns None.
  """
  project, bucket, builder = builder.split('/')
  # "infra.recipe" is not returned by default, so we have to specify it.
  required_fields = {'infra.recipe'}.union(api.buildbucket.DEFAULT_FIELDS)
  build = api.buildbucket_util.last_build(
      project,
      bucket,
      builder,
      fields=required_fields,
      status=common_pb2.SUCCESS)
  if not build:
    return None

  age_seconds = api.time.time() - build.end_time.seconds
  if age_seconds > MAX_BUILD_AGE_SECONDS:
    return None
  return build


def create_led_build(api, orig_build, selftest_cl):

  class Build(api.swarming_retry.LedTask):

    def include_cl(self, cl):
      self._led_data = self._led_data.then('edit-cr-cl', cl)

    def include_recipe_bundle(self):
      self._led_data = self._led_data.then('edit-recipe-bundle')

  builder = orig_build.builder.builder
  led_data = api.led('get-build', orig_build.id)
  led_data.result['top_level']['name'] = 'recipes-cq:%s' % builder
  build = Build(api=api, name=builder, led_data=led_data)

  if orig_build.infra.recipe.name == 'recipes':
    build.include_cl(selftest_cl)
  elif orig_build.input.gerrit_changes:
    orig_cl = orig_build.input.gerrit_changes[0]
    cl_id = get_latest_cl(api, orig_cl.host, orig_cl.project)
    # Setting the CL to a more recent CL helps avoid rebase errors, but if
    # unable to find a recent CL, keep the original. It usually works.
    if cl_id:
      build.include_cl('https://%s/c/%d' % (orig_cl.host, cl_id))

  return build


@memoize
def get_latest_cl(api, gerrit_host, project):
  """Returns the integer change number for a project's most recently landed CL.

  Args:
    gerrit_host (str): E.g., fuchsia-review.googlesource.com
    project (str): The name of the project in gerrit, e.g. "fuchsia"

  Returns:
    The integer change number for the CL corresponding to the commit at the
    tip of the master branch.
  """
  gitiles_host = gerrit_host.replace('-review', '')
  remote = 'https://%s/%s' % (gitiles_host, project)
  log = api.gitiles.log(
      remote, 'refs/heads/master', limit=10, step_name='log %s' % project)

  for log_entry in log:
    commit_hash = log_entry['id']
    change = api.gerrit.change_details(
        'latest change details for %s' % project,
        commit_hash,
        test_data=api.json.test_api.output({'_number': 12345}),
        ok_ret='any')
    # Commits that are committed directly without code review don't have
    # Gerrit change details.
    if change:
      return change['_number']
  return None


def RunSteps(api, project, manifest, remote, selftest_cl, unittest_only):
  # Resolve the build input to always contain a Gitiles commit.
  api.build_input_resolver.resolve()

  with api.context(infra_steps=True):
    api.checkout.with_options(
        path=api.path['start_dir'],
        manifest=manifest,
        remote=remote,
        project=project,
        build_input=api.buildbucket.build.input,
    )

  # Run the recipe unit tests.
  recipes_path = api.path['start_dir'].join('infra', 'recipes')
  with api.context(cwd=recipes_path):
    api.python('test', api.context.cwd.join('recipes.py'), args=['test', 'run'])

  if unittest_only:
    return

  builders = sorted(x for x in api.commit_queue.all_tryjobs())
  step = api.step('normalized_tryjobs', None)
  step.presentation.logs['tryjobs'] = builders

  affected_recipes = get_affected_recipes(api)

  builds = []
  with api.step.nest('get builders') as nest:
    with api.context(cwd=recipes_path):
      for builder in builders:
        with api.step.nest(builder) as parent_step:
          orig_build = get_last_green_build(api, builder)
          if not orig_build:
            parent_step.step_summary_text = 'no recent builds found'
            continue

          recipe = orig_build.infra.recipe.name
          assert recipe
          if recipe in affected_recipes:
            parent_step.step_summary_text = 'SELECTED'
            builds.append(create_led_build(api, orig_build, selftest_cl))
          else:
            parent_step.step_summary_text = 'skipped'
          parent_step.presentation.logs['recipe_used'] = recipe

    nest.step_summary_text = 'selected {} builds'.format(len(builds))

  if not builds:
    return

  # Configure child builds.
  with api.step.nest('configure builds') as nest:
    for build in builds:
      with api.step.nest(build.name) as parent_step:
        with api.context(cwd=recipes_path):
          build.include_recipe_bundle()

  with api.swarming_retry.retry(tasks=builds) as retry:
    retry.run_tasks()
    retry.present_tasks()


def GenTests(api):
  # yapf:disable
  def build_data(name, recipe, age_seconds=ONE_DAY, cl_cached=False,
                 skip=False, num_log_entries=1):
    # This time is taken from the time recipe_engine module. I see no way
    # of getting it programmatically.
    curr_time = 1337000000
    end_time = curr_time - age_seconds

    build = build_pb2.Build(id=37, status=common_pb2.SUCCESS)
    build.end_time.seconds = end_time
    build.builder.builder = name
    build.infra.recipe.name = recipe
    cl = build.input.gerrit_changes.add()
    cl.host = 'fuchsia-review.googlesource.com'
    cl.project = 'fuchsia'

    result = api.buildbucket.simulated_search_results(
        [build],
        'get builders.{}.buildbucket.search'.format(name))

    if skip or age_seconds > MAX_BUILD_AGE_SECONDS:
      return result

    builder_data = {
        'top_level': {
            'name': 'led: bb-1-{}'.format(name),
        },
        'job_slices': [
            {
                'userland': {
                    'recipe_properties': {
                        'recipe': recipe,
                    },
                },
            },
        ],
    }
    result += api.step_data(
        'get builders.{}.led get-build'.format(name),
        stdout=api.json.output(builder_data))

    if recipe != 'recipes' and not cl_cached:
      result += api.gitiles.log(
          'get builders.{}.log {}'.format(name, cl.project), 'A', n=num_log_entries)

    return result

  def no_build(name):
    return api.buildbucket.simulated_search_results(
        [],
        'get builders.{}.buildbucket.search'.format(name))

  def affected_recipes_data(affected_recipes,
                            recipe_files=None,
                            changed_files=None,
                            error=None,
                            invalid_recipes=(),
                            step_name='get_affected_recipes.recipes-analyze'):
    if not recipe_files:
      recipe_files = ['foo', 'fuchsia.py', 'recipes.py', 'sdk.expected']
    res = api.step_data(
        'get_affected_recipes.ls-recipes',
        stdout=api.raw_io.output(
            ''.join('{}\n'.format(x) for x in recipe_files)))

    if not changed_files:
      changed_files = [
          'recipes/fuchsia.py',
          'recipes/foo',
          'recipes/non_expected_json_file.json',
          'recipe_modules/foo/examples/full.expected/bar.json',
          'recipe_modules/foo/examples/full.py',
          'recipe_modules/foo/test_api.py',
      ]
    res += api.step_data(
        'get_affected_recipes.git diff-tree',
        stdout=api.raw_io.output(
            ''.join('{}\0'.format(x) for x in changed_files)))

    output = {
        'recipes': list(affected_recipes),
        'error': error or '',
        'invalidRecipes': list(invalid_recipes),
    }
    retcode = -1 if error else 0
    res += api.step_data(step_name, api.json.output(output), retcode=retcode)

    return res

  yield (api.status_check.test('cq_try') +
         api.build_input_resolver.set_gerrit_branch() +
         api.gitiles.refs('refs', ['refs/heads/master', 'c' * 40]) +
         api.commit_queue.test_data() +
         affected_recipes_data(['none']) +
         build_data('fuchsia/try/fuchsia-x64-debug', 'fuchsia', skip=True) +
         build_data('fuchsia/try/fuchsia-arm64-debug', 'fuchsia', skip=True) +
         build_data('fuchsia/try/cobalt-x64-linux', 'cobalt', skip=True) +
         api.buildbucket.try_build(
             git_repo='https://fuchsia.googlesource.com/infra/recipes') +
         api.properties(
             manifest='manifest/minimal',
             remote='https://fuchsia.googlesource.com/infra/recipes',
         ))

  def props(unittest_only=False):
    return api.properties(
        project='garnet',
        manifest='manifest/garnet',
        remote='https://fuchsia.googlesource.com/garnet',
        import_in='manifest/third_party',
        import_from='zircon',
        unittest_only=unittest_only)

  ci_build = api.buildbucket.ci_build(
      project='infra/recipes',
      git_repo='https://fuchsia.googlesource.com/infra/recipes',
  )

  def task_result(task_id, name, failed=False):
    return api.swarming.task_result(
        id=task_id,
        name='recipes-cq:%s' % name,
        state=None if not name else api.swarming.TaskState.COMPLETED,
        failure=failed,
    )

  yield (
      api.status_check.test('recursive_ls') +
      props() +
      ci_build +
      api.commit_queue.test_data('empty') +
      affected_recipes_data(
          affected_recipes=[],
          recipe_files=['fuchsia/fuchsia.py', 'abc.resources/bar.py', 'abc.py'],
      )
  )

  yield (
      api.status_check.test('recipes_cfg') +
      props() +
      ci_build +
      api.commit_queue.test_data('empty') +
      affected_recipes_data(
          affected_recipes=[],
          recipe_files=['a.py', 'b.py', 'c.py', 'd.py', 'e.py'],
          changed_files=['infra/config/recipes.cfg'],
      )
  )

  yield (
      api.status_check.test('recipe_proto') +
      props() +
      ci_build +
      api.commit_queue.test_data() +
      affected_recipes_data(
          affected_recipes=[],
          changed_files=['recipe_proto/infra/fuchsia.proto'],
      )
  )

  yield (
      api.status_check.test('no_build_old_build_ignored_build') +
      props() +
      ci_build +
      api.commit_queue.test_data() +
      affected_recipes_data(['fuchsia']) +
      build_data('fuchsia/try/cobalt-x64-linux', 'cobalt',
                 age_seconds=MAX_BUILD_AGE_SECONDS - ONE_DAY, skip=True) +
      build_data('fuchsia/try/fuchsia-x64-debug', 'fuchsia',
                 age_seconds=MAX_BUILD_AGE_SECONDS + ONE_DAY) +
      no_build('fuchsia/try/fuchsia-arm64-debug')
  )

  yield (
      api.status_check.test('two_pass_one_skip') +
      props() +
      ci_build +
      api.commit_queue.test_data() +
      affected_recipes_data(['fuchsia']) +
      build_data('fuchsia/try/cobalt-x64-linux', 'cobalt', skip=True) +
      build_data('fuchsia/try/fuchsia-arm64-debug', 'fuchsia') +
      api.swarming_retry.led_data('fuchsia/try/fuchsia-arm64-debug',
                                  task_id=200) +
      build_data('fuchsia/try/fuchsia-x64-debug', 'fuchsia', cl_cached=True) +
      api.swarming_retry.led_data('fuchsia/try/fuchsia-x64-debug',
                                  task_id=100) +
      api.swarming_retry.collect_data([
          task_result(100, 'fuchsia/try/fuchsia-x64-debug'),
          task_result(200, 'fuchsia/try/fuchsia-arm64-debug'),
      ])
  )

  yield (
      api.status_check.test('fuchsia_recipe_unaffected') +
      props() +
      ci_build +
      api.commit_queue.test_data() +
      affected_recipes_data(['qemu']) +
      build_data('fuchsia/try/cobalt-x64-linux', 'cobalt', skip=True) +
      build_data('fuchsia/try/fuchsia-x64-debug', 'fuchsia', skip=True) +
      build_data('fuchsia/try/fuchsia-arm64-debug', 'fuchsia', skip=True)
  )

  yield (
      api.status_check.test('recipes') +
      props() +
      ci_build +
      api.commit_queue.test_data('recipes-only') +
      affected_recipes_data(['recipes']) +
      build_data('fuchsia/try/recipes', 'recipes') +
      api.swarming_retry.led_data('fuchsia/try/recipes', task_id=100) +
      api.swarming_retry.collect_data(
          [task_result(100, 'fuchsia/try/recipes')])
  )

  yield (
      api.status_check.test('unittest_only') +
      props(unittest_only=True) +
      ci_build
  )

  yield (
    api.status_check.test('no_latest_cl') +
    props() +
    ci_build +
    api.commit_queue.test_data() +
    affected_recipes_data(['fuchsia']) +
    build_data('fuchsia/try/fuchsia-arm64-debug', 'fuchsia', num_log_entries=0) +
    api.swarming_retry.led_data('fuchsia/try/fuchsia-arm64-debug',
                                task_id=200) +
    build_data('fuchsia/try/fuchsia-x64-debug', 'fuchsia', cl_cached=True) +
    api.swarming_retry.led_data('fuchsia/try/fuchsia-x64-debug',
                                task_id=100) +
    api.swarming_retry.collect_data([
        task_result(100, 'fuchsia/try/fuchsia-x64-debug'),
        task_result(200, 'fuchsia/try/fuchsia-arm64-debug'),
    ])
  )
  # yapf:enable
