# Copyright (c) 2020, the Dart project 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 PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2

from PB.recipes.dart.cron.builders import Builders

PROPERTIES = Builders

PROJECT = 'dart'
BUCKET = 'ci.sandbox'
HOST = 'dart.googlesource.com'
REPO = 'sdk'
REF = 'refs/heads/master'

DEPS = [
    'depot_tools/gitiles',
    'recipe_engine/buildbucket',
    'recipe_engine/properties',
]


def RunSteps(api, properties):
  builders = properties.builders
  assert builders, 'No builders to trigger'
  commits, _ = api.gitiles.log(
      'https://%s/%s' % (HOST, REPO),
      REF,
      limit=1,
      step_name='get latest commit',
  )
  head = common_pb2.GitilesCommit(
      host=HOST,
      project=REPO,
      id=commits[0]['commit'],
      ref=REF,
  )
  requests = []
  for builder in builders:
    requests.append(
        api.buildbucket.schedule_request(
            builder=builder,
            project=PROJECT,
            bucket=BUCKET,
            gitiles_commit=head,
            inherit_buildsets=False,
        ))
  api.buildbucket.schedule(requests, step_name='schedule builds')


def GenTests(api):
  yield api.test(
      'schedule-builds',
      api.properties(Builders(builders=['cross', 'msan'])),
      api.step_data('get latest commit',
                    api.gitiles.make_log_test_data('HEAD', n=1)),
      api.post_process(post_process.MustRun, 'schedule builds'),
      api.post_process(post_process.StatusSuccess),
  )

  yield api.test(
      'no-builds',
      api.expect_exception('AssertionError'),
      api.post_process(post_process.StatusException),
      api.post_process(post_process.DropExpectation),
  )
