# Copyright 2019 The Fuchsia 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 coordinating Fuchsia SDK build triggers.

TODO(atyfto): This recipe is unused as of Oct. 2019 but may be useful in the
future. Consider deleting the recipe if it becomes a maintenance burden
before we have a concrete plan to use it.
"""

from recipe_engine.config import List
from recipe_engine.recipe_api import Property

DEPS = [
    'fuchsia/buildbucket_util',
    'fuchsia/checkout',
    'fuchsia/fuchsia',
    'fuchsia/gsutil',
    'fuchsia/jiri',
    'recipe_engine/buildbucket',
    'recipe_engine/file',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
    'recipe_engine/swarming',
]

PROPERTIES = {
    'project':
        Property(kind=str, help='Jiri remote manifest project'),
    'manifest':
        Property(kind=str, help='Jiri manifest to use'),
    'remote':
        Property(kind=str, help='Remote manifest repository'),
    'checkout_snapshot':
        Property(
            kind=bool,
            help='Whether or not to checkout from a Jiri snapshot.'
            ' Snapshot is expected to be found at the location specified by'
            ' BuildBucket input.',
            default=False),
    'sdk_builders':
        Property(
            kind=List(basestring),
            help='List of SDK builders to trigger.',
            default=[]),
}


def RunSteps(api, project, manifest, remote, checkout_snapshot, sdk_builders):
  build = api.buildbucket.build

  sdk_id = str(build.id)

  properties = {'sdk_id': sdk_id}

  sdk_schedule_reqs = []

  for sdk_builder in sdk_builders:
    sdk_schedule_reqs.append(
        api.buildbucket.schedule_request(
            builder=sdk_builder,
            properties=properties,
            swarming_parent_run_id=api.swarming.task_id))

  if checkout_snapshot:
    if api.buildbucket_util.is_tryjob:
      assert len(build.input.gerrit_changes) == 1
      api.checkout.from_patchset_snapshot(
          path=api.path['start_dir'],
          gerrit_change=build.input.gerrit_changes[0])
    else:
      api.checkout.from_commit_snapshot(
          path=api.path['start_dir'], gitiles_commit=build.input.gitiles_commit)
  else:
    assert manifest
    assert remote
    api.checkout.fuchsia_with_options(
        path=api.path['start_dir'],
        build=build,
        manifest=manifest,
        remote=remote,
        project=project,
    )

  # To avoid write conflicts, only upload a snapshot if this is the top-level
  # build for this version of the SDK. Sub-builds will have the sdk_id set to
  # something other than build_id.
  snapshot_file = api.path['cleanup'].join('jiri.snapshot')
  api.jiri.snapshot(snapshot_file)
  api.gsutil.upload(
      bucket='fuchsia-snapshots',
      src=snapshot_file,
      dst=sdk_id,
      link_name='jiri.snapshot',
      name='upload jiri.snapshot')


def GenTests(api):
  topaz_properties = api.properties(
      project='integration',
      manifest='fuchsia/topaz/topaz',
      remote='https://fuchsia.googlesource.com/integration',
      sdk_builders=['core-x64', 'core-arm64'])

  topaz_local_ci = topaz_properties + api.buildbucket.ci_build(
      git_repo='https://fuchsia.googlesource.com/topaz',)

  topaz_local_cq = topaz_properties + api.buildbucket.try_build()

  yield (api.test('local_ci') + topaz_local_ci)
  yield (api.test('local_cq') + topaz_local_cq)
  yield (api.test('snapshot_ci') + topaz_local_ci +
         api.properties(checkout_snapshot=True))
  yield (api.test('snapshot_cq') + topaz_local_cq +
         api.properties(checkout_snapshot=True))
