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

DEPS = [
    'flutter/monorepo',
    'flutter/repo_util',
    'recipe_engine/buildbucket',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/json',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
]


def RunSteps(api):
  flutter_checkout_path = api.path['start_dir'].join('flutter')
  api.repo_util.get_branch(flutter_checkout_path)
  api.repo_util.is_release_candidate_branch(flutter_checkout_path)
  api.repo_util.release_candidate_branch(flutter_checkout_path)
  api.repo_util.checkout(
      'flutter', flutter_checkout_path, ref='refs/heads/master'
  )
  api.repo_util.checkout(
      'engine', api.path['start_dir'].join('engine'), ref='refs/heads/main'
  )
  api.repo_util.checkout(
      'cocoon', api.path['start_dir'].join('cocoon'), ref='refs/heads/main'
  )
  api.repo_util.checkout(
      'packages', api.path['start_dir'].join('packages'), ref='refs/heads/main'
  )
  # we need an override because all of the previous step calls on checkout directly overrides the ref variable
  api.repo_util.checkout(
      'flutter', flutter_checkout_path, ref='refs/heads/beta'
  )
  api.repo_util.run_flutter_doctor()
  api.repo_util.get_env_ref()

  env, env_paths = api.repo_util.engine_environment(flutter_checkout_path)
  env, env_paths = api.repo_util.flutter_environment(flutter_checkout_path)
  api.repo_util.in_release_and_main(flutter_checkout_path)
  checkout_path = api.path['start_dir']
  if api.monorepo.is_monorepo_ci_build or api.monorepo.is_monorepo_try_build:
    api.file.ensure_directory('ensure directory', checkout_path)
    api.repo_util.monorepo_checkout(checkout_path, {}, {})
  else:
    api.file.ensure_directory('ensure directory', checkout_path.join('engine'))
    api.repo_util.engine_checkout(checkout_path.join('engine'), {}, {})
  with api.context(env=env, env_prefixes=env_paths):
    api.repo_util.sdk_checkout_path()


def GenTests(api):
  yield (
      api.test(
          'basic',
          api.properties(
              git_branch='beta',
              gn_artifacts='true',
              git_url='https://github.com/flutter/engine',
              git_ref='refs/pull/1/head',
              clobber=True,
              package_sharding='shard1',
          ), api.repo_util.flutter_environment_data(),
          api.step_data(
              'Identify branches.git rev-parse',
              stdout=api.raw_io.output_text('abchash')
          ),
          api.step_data(
              'Identify branches.git branch',
              stdout=api.raw_io.output_text('branch1\nbranch2\nflutter-3.2-candidate.5')
          ),
          api.step_data(
              'Identify branches (2).git branch',
              stdout=api.raw_io.output_text('branch1\nbranch2\nflutter-3.2-candidate.5')
          ),
          api.step_data(
              'Identify branches (3).git branch',
              stdout=api.raw_io.output_text('branch1\nbranch2\nflutter-3.2-candidate.5')
          )
      )
  )
  yield api.test(
      'failed_flutter_environment',
      api.properties(
          git_url='https://github.com/flutter/engine',
          git_ref='refs/pull/1/head'
      )
  )
  yield api.test(
      'monorepo_release', api.repo_util.flutter_environment_data(),
      api.properties(git_branch='beta', clobber=True),
      api.monorepo.ci_build(git_ref='refs/heads/beta')
  )
  yield api.test(
      'monorepo', api.repo_util.flutter_environment_data(),
      api.monorepo.ci_build()
  )
  yield api.test(
      'monorepo_tryjob', api.repo_util.flutter_environment_data(),
      api.properties(clobber=True), api.monorepo.try_build()
  )
  yield api.test(
      'monorepo_wrong_host', api.repo_util.flutter_environment_data(),
      api.buildbucket.ci_build(
          git_repo='https://not-dart.googlesource.com/monorepo',
          git_ref='refs/heads/main'
      ), api.expect_exception('ValueError')
  )
  yield api.test(
      'monorepo_first_bot_update_failed',
      api.repo_util.flutter_environment_data(),
      api.properties(clobber=True),
      api.monorepo.ci_build(),
      # Next line force a fail condition for the bot update
      # first execution.
      api.step_data("Checkout source code.bot_update", retcode=1)
  )
  yield (
      api.test(
          'bot_update',
          api.properties(
              git_url='https://github.com/flutter/engine',
              git_ref='refs/pull/1/head'
          )
      ) + api.repo_util.flutter_environment_data()
  )
  yield (
      api.test(
          'first_bot_update_failed',
          api.properties(
              git_url='https://github.com/flutter/engine',
              git_ref='refs/pull/1/head'
          )
      ) +
      # Next line force a fail condition for the bot update
      # first execution.
      api.step_data("Checkout source code.bot_update", retcode=1) +
      api.repo_util.flutter_environment_data()
  )
  yield (
      api.test(
          'first_bot_update_revision_not_found',
          api.properties(
              git_url='https://github.com/flutter/engine',
              git_ref='refs/pull/1/head'
          )
      ) +
      # Next line force a fail condition for the bot update
      # first execution.
      api.path.exists(
          api.path['cache'].join('git'), api.path['start_dir'].join('engine')
      ) + api.override_step_data(
          "Checkout source code.bot_update",
          api.json.output({
              'properties': {'got_revision': 'BOT_UPDATE_NO_REV_FOUND'}
          }),
          retcode=0
      ) + api.repo_util.flutter_environment_data()
  )
