# Copyright 2020 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.
""" sdk_orchestrator.py -- Orchestrates and publishes Fuchsia SDKs.

# Execution overview

## Schedule SDK archive subbuilds

This recipe schedules sdk.py subbuilds, which in turn are responsible for
generating, merging, and testing SDK archives. Each sdk.py subbuild should be
a unique SDK flavor. The primary motivation for orchestrating the subbuilds
is to 1) unify the SDK IDs and 2) unify the publishing logic across SDK
flavors.

## Schedule companion image subbuilds

TODO: Move companion image logic here from sdk.py.

This recipe will optionally schedule companion image subbuilds, which in turn
are responsible for generating Fuchsia images. Each fuchsia/build.py subbuild
should be a unique product.board configuration which is compatible with the
SDK flavors from the above step.

## Publish

TODO: Move publish logic here from sdk.py.

If publishing is enabled, this recipe will relocate the various artifacts
generated in the above steps to Fuchsia SDK namespaces in GCS and CIPD.
"""

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

DEPS = [
    'fuchsia/build_input_resolver',
    'fuchsia/buildbucket_util',
    'fuchsia/gitiles',
    'recipe_engine/buildbucket',
    'recipe_engine/properties',
    'recipe_engine/step',
    'recipe_engine/swarming',
]

PROPERTIES = {
    'subbuilders':
        Property(
            kind=List(basestring),
            help='sdk.py subbuilder names to generate merged SDK archives.',
        ),
    'companion_images':
        Property(
            kind=List(dict),
            help='The Fuchsia images built with this version of the SDK.'
            ' Each object should have 3 properties:'
            '   name (str): name of the image referred to in the SDK.'
            '   builder (str): name of the fuchsia/build.py builder.'
            '   bucket (str): GCS bucket where the image should be installed.',
            default=[]),
    'sdk_id':
        Property(kind=str, help='The SDK version ID.', default=''),
}


def RunSteps(api, subbuilders, companion_images, sdk_id):
  api.build_input_resolver.resolve(
      default_project_url='https://fuchsia.googlesource.com/fuchsia')
  # By default the SDK ID is set to this build's buildbucket ID. This will
  # change when we have a real SDK versioning scheme.
  sdk_id = sdk_id if sdk_id else api.buildbucket_util.id
  # The same SDK ID should be shared by all sdk.py subbuilds.
  properties = {'sdk_id': sdk_id}

  # Schedule archive subbuilds.
  archive_schedule_reqs = []
  for subbuilder in subbuilders:
    req = api.buildbucket.schedule_request(
        builder=subbuilder,
        properties=properties,
        swarming_parent_run_id=api.swarming.task_id,
        priority=None)  # Avoid overriding priority from configs.
    archive_schedule_reqs.append(req)
  archive_subbuilds = api.buildbucket.schedule(
      archive_schedule_reqs, step_name='schedule archive subbuilds')

  # Collect and display archive subbuilds status.
  archive_subbuilds = api.buildbucket.collect_builds(
      build_ids=[subbuild.id for subbuild in archive_subbuilds],
      step_name='collect archive subbuilds')
  api.buildbucket_util.display_builds(
      step_name='display archive subbuilds',
      builds=archive_subbuilds.values(),
      raise_on_failure=True)


def GenTests(api):
  subbuilders = ['sdk-core-linux', 'sdk-core-mac']

  yield (api.test('ci') + api.buildbucket.ci_build() +
         api.properties(subbuilders=subbuilders))
  yield (api.test('cq') + api.buildbucket.try_build() +
         api.properties(subbuilders=subbuilders) +
         api.build_input_resolver.set_gerrit_branch() +
         api.gitiles.refs('refs', ['refs/heads/master', 'deadbeef']))
