# 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.go.chromium.org.luci.buildbucket.proto import build as build_pb2
from PB.go.chromium.org.luci.buildbucket.proto import builder as builder_pb2
from PB.go.chromium.org.luci.buildbucket.proto import builds_service as builds_service_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/main'

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',
  )
  revision = commits[0]['commit']
  head = common_pb2.GitilesCommit(
      host=HOST,
      project=REPO,
      id=revision,
      ref=REF,
  )
  predicate = builds_service_pb2.BuildPredicate(tags=[
      common_pb2.StringPair(
          key='buildset',
          value='commit/gitiles/dart.googlesource.com/sdk/+/%s' % revision)
  ])
  previous_builds = api.buildbucket.search(
      predicate, fields=["builder"], step_name='find previous builds')
  previous_builders = set()
  for build in previous_builds:
    if build.builder.bucket == BUCKET:
      previous_builders.add(build.builder.builder)
  requests = []
  for builder in builders:
    if builder not in previous_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 _schedules_builder(name, must_schedule):

  def validate(check, step_odict, step):
    input = str(step_odict[step].stdin)
    check((('"builder": "%s"' % name) in input) == must_schedule)

  return validate


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(
      'skip-duplicate-build',
      api.properties(Builders(builders=['cross', 'msan'])),
      api.step_data('get latest commit',
                    api.gitiles.make_log_test_data('HEAD', n=1)),
      api.buildbucket.simulated_search_results(
          [
              build_pb2.Build(
                  builder=builder_pb2.BuilderID(
                      project=PROJECT, bucket=BUCKET, builder='msan')),
              # Return a build from an unrelated bucket to test that it is not
              # used to filter out a builder in our bucket.
              build_pb2.Build(
                  builder=builder_pb2.BuilderID(
                      project=PROJECT, bucket="another_bucket", builder='cross')
              ),
          ],
          step_name='find previous builds'),
      api.post_process(_schedules_builder('cross', True), 'schedule builds'),
      api.post_process(_schedules_builder('msan', False), 'schedule builds'),
      api.post_process(post_process.MustRun, 'schedule builds'),
      api.post_process(post_process.StatusSuccess),
      api.post_process(post_process.Filter('schedule builds')),
  )

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