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

"""Recipe for updating flutter/infra with ci.yaml changes."""

from PB.go.chromium.org.luci.common.proto.gerrit import gerrit as gerrit_pb2

DEPS = [
    'flutter/repo_util',
    'fuchsia/auto_roller',
    'recipe_engine/buildbucket',
    'recipe_engine/cipd',
    'recipe_engine/context',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/raw_io',
    'recipe_engine/step',
]

def _is_postsubmit(api):
  """Returns True if the current build is not in try, otherwise False."""
  return api.buildbucket.build.builder.bucket != 'try'


def _is_default_branch(branch):
  """Returns True if branch is master or main."""
  return branch in ("main", "master")

def RunSteps(api):
  """Steps to checkout infra, dependencies, and generate new config."""
  start_path = api.path['start_dir']
  cocoon_path = start_path.join('cocoon')
  flutter_path = start_path.join('flutter')
  infra_path = start_path.join('infra')

  # Checkout the stable version of Flutter.
  flutter_git_ref = 'refs/heads/master'
  api.repo_util.checkout('flutter', flutter_path, ref=flutter_git_ref)

  # Checkout latest version of flutter/cocoon.
  api.repo_util.checkout(
      'cocoon',
      cocoon_path,
      ref='refs/heads/main'
  )

  # Checkout latest version of flutter/infra
  api.repo_util.checkout(
      'infra',
      infra_path,
      ref='refs/heads/main'
  )

  # Install protoc to compile latest scheduler.proto
  protoc_path = start_path.join('protoc')
  api.cipd.ensure(
      protoc_path,
      api.cipd.EnsureFile().add_package(
          'infra/3pp/tools/protoc/${platform}', 'version:2@3.17.3'
      )
  )

  git_branch = api.properties.get('git_branch')
  repo = api.properties.get('git_repo')
  if _is_postsubmit(api):
    # gitiles commit info
    git_ref = api.buildbucket.gitiles_commit.id
  else:
    # github pull request info
    git_ref = 'main' # Default to master for LED runs
    for tag in api.buildbucket.build.tags:
      if 'sha/git/' in tag.value:
          git_ref = tag.value.replace('sha/git/', '')

  # The context adds dart-sdk tools to PATH and sets PUB_CACHE.
  env, env_prefixes = api.repo_util.flutter_environment(flutter_path)
  with api.context(env=env, env_prefixes=env_prefixes, cwd=cocoon_path.join('app_dart')):
    api.step('flutter doctor', cmd=['flutter', 'doctor'])
    api.step('dart pub get', cmd=['dart', 'pub', 'get'])
    generate_jspb_path = cocoon_path.join('app_dart', 'bin', 'generate_jspb.dart')
    config_name = '%s_config.json' % repo
    if git_branch and not _is_default_branch(git_branch):
      config_name = '%s_%s_config.json' % (repo, git_branch)
    infra_config_path = infra_path.join('config', 'generated', 'ci_yaml', config_name)
    # Generate_jspb
    jspb_step = api.step('generate jspb',
        cmd=['dart', generate_jspb_path, repo, git_ref],
        stdout=api.raw_io.output_text(), stderr=api.raw_io.output_text())
    api.file.write_raw('write jspb', infra_config_path, jspb_step.stdout)

  # Roll scheduler.proto
  with api.context(env_prefixes={'PATH': [protoc_path.join('bin')]}):
    scheduler_proto_src = cocoon_path.join('app_dart', 'lib', 'src', 'model',
        'proto', 'internal', 'scheduler.proto')
    scheduler_proto_dst = infra_path.join('config', 'lib', 'ci_yaml')
    api.step('Roll scheduler.proto', ['cp', scheduler_proto_src, scheduler_proto_dst])
    api.step('Compile scheduler.proto', ['bash', scheduler_proto_dst.join('compile_proto.sh')])

  with api.context(cwd=infra_path):
    # Generate luci configs
    api.step('luci generate', cmd=['lucicfg', 'generate', 'config/main.star'])
    # Validate luci configs
    api.step('luci validate', cmd=['lucicfg', 'validate', 'config/main.star'])
    # Only send rolls on postsubmit
    if _is_postsubmit(api):
        api.auto_roller.attempt_roll(
            api.auto_roller.Options(
                remote = 'https://flutter.googlesource.com/infra',
                cc_on_failure_emails = ['flutter-infra@grotations.appspotmail.com'],
                labels_to_set = {'Commit-Queue': 2},
                bot_commit = True,
            ),
            repo_dir = infra_path,
            commit_message = 'Roll %s to %s' % (repo, git_ref),
        )


def GenTests(api):
  yield api.test(
      'basic',
      api.buildbucket.ci_build(
          bucket='prod',
          git_repo='https://flutter.googlesource.com/mirrors/engine',
          revision = 'abc123'
      ),
      api.properties(
          git_branch='main',
          git_repo='engine'
      ),
      api.repo_util.flutter_environment_data(
          api.path['start_dir'].join('flutter')
      ),
      api.step_data('generate jspb', stdout=api.raw_io.output_text('{"hello": "world"}')),
      api.auto_roller.success()
  )
  yield api.test(
      'release',
      api.buildbucket.ci_build(
          bucket='prod',
          git_repo='https://flutter.googlesource.com/mirrors/engine',
          revision = 'abc123'
      ),
      api.properties(
          git_branch='dev',
          git_repo='engine'
      ),
      api.repo_util.flutter_environment_data(
          api.path['start_dir'].join('flutter')
      ),
      api.step_data('generate jspb', stdout=api.raw_io.output_text('{"hello": "world"}')),
      api.auto_roller.success()
  )
  yield api.test(
      'staging',
      api.buildbucket.ci_build(
          bucket='staging',
          git_repo='https://flutter.googlesource.com/mirrors/engine',
          revision = 'abc123'
      ),
      api.properties(
          git_branch='main',
          git_repo='engine'
      ),
      api.repo_util.flutter_environment_data(
          api.path['start_dir'].join('flutter')
      ),
      api.step_data('generate jspb', stdout=api.raw_io.output_text('{"hello": "world"}')),
      api.auto_roller.success()
  )
  yield api.test(
      'presubmit',
      api.buildbucket.try_build(
          bucket='try',
          tags=api.buildbucket.tags(
              buildset=['sha/git/def123', 'sha/pr/1']
          )
      ),
      api.properties(
          git_repo='engine'
      ),
      api.repo_util.flutter_environment_data(
          api.path['start_dir'].join('flutter')
      ),
  )
