# 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.
"""A recipe to create synthethic builds for non-Luci builds.

This recipe is meant to be triggered by other recipes that process results from
non-Luci build and test infrastructure. It can be used to provide that
infrastructure with a Luci builder that can be shown on Luci consoles (Milo).

Builds will have the outcome passed to this recipe as an input property and a
link to the external build results (also an input property).
"""

from recipe_engine import post_process

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.recipes.dart.dart.external_build import ExternalBuild

DEPS = [
    'recipe_engine/buildbucket',
    'recipe_engine/properties',
    'recipe_engine/step',
]
PROPERTIES = ExternalBuild


def RunSteps(api, properties):
  result = properties.result
  assert (result)
  url = properties.url
  assert (url)
  api.step('process properties', None)
  api.step.active_result.presentation.links['results'] = url
  api.step.active_result.presentation.properties['got_revision'] = (
      api.buildbucket.gitiles_commit.id)
  if result != common_pb2.SUCCESS:
    failure_summary = 'Failed build: <a href="%s">details</a>' % url
    raise api.step.StepFailure(failure_summary)


def GenTests(api):
  yield api.test(
      'success',
      api.properties(
          ExternalBuild(
              result=common_pb2.Status.Value('SUCCESS'),
              url='https://www.example.com')),
      api.buildbucket.ci_build(
          revision='3456abce78ef',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart'),
      api.post_process(post_process.StatusSuccess),
  )
  yield api.test(
      'failure',
      api.properties(
          ExternalBuild(
              result=common_pb2.Status.Value('FAILURE'),
              url='https://www.example.com')),
      api.buildbucket.ci_build(
          revision='3456abce78ef',
          git_repo='https://dart.googlesource.com/sdk',
          project='dart'),
      api.post_process(post_process.StatusFailure),
  )
