# 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 = {
    '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, 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,
    )

  # 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))
