# 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.
""" fuchsia.py - Builds and optionally tests Fuchsia.

# Execution overview

## Configuration

This recipe uses a protocol buffer message called a spec for most of its
configuration. The only PROPERTIES are those required to acquire the spec.
The recipe fetches the spec from the git repo |spec_remote|. It determines
the correct revision to use from the BuildBucket build input to ensure it
retrieves the correct config for a pending change vs a committed change.

## Checkout + Build

This recipe triggers a child build which runs the fuchsia/build recipe.
That recipe checks out the source code and builds it. This recipe
retrieves the data required to orchestrate tests via Isolate.

## Test

If configured to run tests, this recipe uses the test orchestration data to run tests.
That logic is in the testing recipe module. Under the hood, that module
triggers Swarming tasks that do the actual testing, waits for them, and
reports the results.
"""

from google.protobuf import json_format
from google.protobuf import text_format

from recipe_engine.recipe_api import Property

from PB.go.chromium.org.luci.buildbucket.proto import build as build_pb2
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.go.chromium.org.luci.buildbucket.proto import rpc as rpc_pb2
from PB.infra.fuchsia import Fuchsia
from PB.recipe_modules.recipe_engine.led.properties import InputProperties as LedInputProperties

DEPS = [
    'fuchsia/artifacts',
    'fuchsia/build',
    'fuchsia/build_input_resolver',
    'fuchsia/buildbucket_util',
    'fuchsia/checkout',
    'fuchsia/fuchsia',
    'fuchsia/gitiles',
    'fuchsia/spec',
    'fuchsia/testing',
    'fuchsia/testing_requests',
    'fuchsia/testsharder',
    'recipe_engine/buildbucket',
    'recipe_engine/file',
    'recipe_engine/isolated',
    'recipe_engine/json',
    'recipe_engine/led',
    'recipe_engine/path',
    'recipe_engine/properties',
    'recipe_engine/step',
    'recipe_engine/swarming',
]

PROPERTIES = {
    'spec_remote':
        Property(
            kind=str,
            help='URL of the specs git repository',
            default='http://fuchsia.googlesource.com/integration'),
    # TODO(ihuh): Remove once the experimental feature is working.
    'experimental':
        Property(
            kind=bool,
            help='Whether to use experimental codepath',
            default=False),
}


def RunSteps(api, spec_remote, experimental):
  # Resolve the build input to always contain a Gitiles commit.
  bb_build = api.buildbucket.build
  api.build_input_resolver.resolve(
      bb_build.input,
      default_project_url='https://fuchsia.googlesource.com/fuchsia')

  with api.step.nest('load spec') as presentation:
    presentation.step_text = 'loading spec'
    try:
      spec, spec_revision = api.spec.get_spec_revision_from_build(
          build=bb_build,
          spec_remote=spec_remote,
          Type=Fuchsia,
      )
    except api.spec.ParseError as e:
      raise api.step.StepFailure('failed to parse spec: %s' % str(e))

    presentation.logs['textproto'] = text_format.MessageToString(spec).split(
        '\n')
    # The artifacts tool relies on this output property.
    # This design has been fragile. Please don't add more dependencies on any
    # additional output properties.
    presentation.properties['gcs_bucket'] = spec.gcs_bucket

  orchestrator_id = api.buildbucket_util.id
  if not spec.build.run_tests:
    raise api.step.InfraFailure(
        'if not running tests, use the fuchsia/build recipe directly')

  with api.step.nest('build') as presentation:
    child_build = run_build_steps(api, presentation, spec_remote, spec_revision,
                                  orchestrator_id, experimental)
    child_props = json_format.MessageToDict(child_build.output.properties)
    orchestration_inputs = collect_test_orchestration_inputs(api, child_props)
    # Copy to our own properties so the results uploader in google3 can find
    # it without knowing about the child.
    rev_count_prop = api.checkout.REVISION_COUNT_PROPERTY
    if rev_count_prop in child_props:
      presentation.properties[rev_count_prop] = child_props[rev_count_prop]

  # Configure context of uploaded artifacts for test task construction.
  api.artifacts.gcs_bucket = spec.artifact_gcs_bucket
  api.artifacts.uuid = orchestrator_id

  run_test_steps(api, orchestration_inputs, spec)


def _BuildWithLed(api, builder_name, properties, presentation):
  parent = api.buildbucket.build.builder
  led_data = api.led(
      'get-builder',
      'luci.%s.%s:%s' % (parent.project, parent.bucket, builder_name))
  edit_args = []
  for k, v in properties.items():
    edit_args.extend(['-p', '%s=%s' % (k, api.json.dumps(v))])
  led_data = led_data.then('edit', *edit_args)
  bb_input = api.buildbucket.build_input
  if bb_input.gerrit_changes:
    gerrit_change = bb_input.gerrit_changes[0]
    led_data = led_data.then(
        'edit-cr-cl', 'https://%s/c/%s/+/%d' %
        (gerrit_change.host, gerrit_change.project, gerrit_change.change))
  led_data = api.led.inject_input_recipes(led_data)
  launch_res = led_data.then('launch')
  task_id = launch_res.result['swarming']['task_id']
  swarming_result = api.swarming.collect(
      'collect', [task_id], output_dir=api.path['cleanup'])[0]
  # Led launch ensures this file is present in the task root dir.
  build_proto_path = swarming_result.output_dir.join('build.proto.json')
  build_proto_json = api.file.read_text('read build.proto.json',
                                        build_proto_path)
  build_proto = build_pb2.Build()
  presentation.logs['build.proto.json'] = build_proto_json.splitlines()
  try:
    json_format.Parse(build_proto_json, build_proto)
  except json_format.ParseError as e:
    build_proto.status = common_pb2.INFRA_FAILURE
    build_proto.summary_markdown = 'Failed to parse build.proto.json: %s' % e

  url = 'https://ci.chromium.org/swarming/task/%s?server=%s' % (
      task_id, launch_res.result['swarming']['host_name'])
  return build_proto, url


def _BuildWithBuildBucket(api, builder_name, properties):
  req = api.buildbucket.schedule_request(
      builder=builder_name,
      properties=properties,
      swarming_parent_run_id=api.swarming.task_id,
      priority=None,  # Leave unset to avoid overriding priority from configs.
  )
  build_id = api.buildbucket.schedule([req], step_name='schedule')[0].id
  # As of 2019-11-18, timeout defaults to something too short.
  # We never want this step to time out. We'd rather the whole build time out.
  builds_dict = api.buildbucket.collect_builds([build_id],
                                               timeout=24 * 60 * 60,
                                               step_name='collect')
  return builds_dict[build_id], 'https://ci.chromium.org/b/%s' % build_id


def run_build_steps(api, presentation, spec_remote, spec_revision,
                    orchestrator_id, experimental):
  if experimental:
    parent_properties = api.properties.thaw()
    # These are reserved by kitchen and swarming. See
    # https://chromium.googlesource.com/infra/infra/+/2c2389a00fcdb93d90a628f941814f2abd34428e/go/src/infra/tools/kitchen/cook.go#266
    # and https://chromium.googlesource.com/infra/infra/+/7fcd559afa7a866a5ad039019e6ef6a91922e09c/appengine/cr-buildbucket/validation.py#36
    reject_keys = {
        '$recipe_engine/path', '$recipe_engine/step', 'bot_id', 'path_config',
        'buildbucket', '$recipe_engine/buildbucket', 'buildername', 'branch',
        'repository', '$recipe_engine/runtime'
    }
    properties = {
        key: val
        for key, val in parent_properties.items()
        if key and key not in reject_keys
    }
    properties.update({
        'spec_revision': spec_revision,
        'parent_id': orchestrator_id,
    })
  else:
    properties = {
        'spec_remote': spec_remote,
        'spec_revision': spec_revision,
        'parent_id': orchestrator_id,
    }
  builder_name = '{}-subbuild'.format(api.buildbucket.build.builder.builder)
  # If this task was launched by led, we launch the child with led as well.
  # This lets us ensure that the parent and child use the same version of
  # the recipes code, which is needed for testing.
  if api.led.launched_by_led:
    output_build, build_url = _BuildWithLed(api, builder_name, properties,
                                            presentation)
  else:
    output_build, build_url = _BuildWithBuildBucket(api, builder_name,
                                                    properties)
  presentation.links[builder_name] = build_url
  if output_build.status != common_pb2.SUCCESS:
    raise api.step.StepFailure('build failed')
  return output_build


def run_test_steps(api, orchestration_inputs, spec):
  tryjob = api.buildbucket_util.is_tryjob

  # Handle illegal settings around secrets.
  if spec.test.requires_secrets:
    if tryjob or spec.test.device_type != 'QEMU':
      raise api.step.InfraFailure(
          'the secrets pipeline is only supported in CI and on QEMU')

  if spec.test.test_in_shards:
    all_results = api.testing.test_in_shards(
        collect_timeout_secs=spec.test.collect_timeout_secs,
        debug_symbol_gcs_bucket=spec.debug_symbol_gcs_bucket,
        orchestration_inputs=orchestration_inputs,
        max_attempts=spec.test.max_attempts)
  else:
    all_results = [
        api.testing.deprecated_test(
            spec.debug_symbol_gcs_bucket,
            spec.test.device_type,
            orchestration_inputs,
            max_attempts=spec.test.max_attempts)
    ]

  # Upload test results
  if spec.test.upload_results:
    assert spec.gcs_bucket, 'gcs_bucket must be set if test.upload_results is'
    for test_results in all_results:
      test_results.upload_results(
          gcs_bucket=spec.gcs_bucket,
          upload_to_catapult=(not tryjob and spec.test.upload_to_catapult),
      )

    # TODO(41752): Support processing test coverage.

  # Raise test failures
  with api.step.defer_results():
    api.testing.raise_failures()
    for test_results in all_results:
      test_results.raise_failures()


def collect_test_orchestration_inputs(api, build_props):
  """Downloads isolated orchestration inputs from a build.

    Args:
      build_props (dict): The properties of the build that produced the test
          orchestration inputs.

    Returns:
      FuchsiaBuildApi.TestOrchestrationInputs

    Raises:
      A StepFailure if the required HASH_PROPERTY is not found.
  """
  prop_name = api.build.TestOrchestrationInputs.HASH_PROPERTY
  orchestration_inputs_hash = build_props.get(prop_name)
  if not orchestration_inputs_hash:
    raise api.step.StepFailure('no `%s` property found' % prop_name)
  return api.build.TestOrchestrationInputs.download(api,
                                                    orchestration_inputs_hash)


def GenTests(api):

  def ci_build_message(api, output_props=None, **kwargs):
    """Generates a Buildbucket Build message.

    Args:
      output_props (Dict): output properties to set on the build.
      kwargs: Forwarded to BuildbucketApi.ci_build_message.

    See BuildBucketTestApi.ci_build_message for full parameter documentation.
    """
    msg = api.buildbucket.ci_build_message(**kwargs)
    msg.output.properties.update(output_props if output_props else {})
    return msg

  def child_build_steps(api, build):
    """Generates step data to schedule and collect from a child build

    Args:
      build (build_pb2.Build): The build to schedule and collect from.
    """
    mock_schedule_data = api.buildbucket.simulated_schedule_output(
        step_name='build.schedule',
        batch_response=rpc_pb2.BatchResponse(
            responses=[dict(schedule_build=dict(id=build.id))],),
    )
    mock_collect_data = api.buildbucket.simulated_collect_output(
        step_name='build.collect',
        builds=[build],
    )
    return mock_schedule_data + mock_collect_data

  def child_led_steps(api, build, tryjob=False):
    """Generates step data to schedule and collect from a child build

    Args:
      build (build_pb2.Build): The build to schedule and collect from.
    """
    props = {
        'gcs_bucket': api.fuchsia.DEFAULT_GCS_BUCKET,
        'parent_id': build.id
    }
    change_prop = {
        '$recipe_engine/buildbucket': {
            'build': {
                'input': {
                    'gerritChanges': {
                        'change': '12345',
                        'host': 'fuchsia-review.googlesource.com',
                        'project': 'fuchsia'
                    }
                }
            }
        }
    }
    led_data = (
      api.led.get_builder(api, 'build.led get-builder')
             .edit_properties('build.led edit', **props)
    ) # yapf: disable
    if tryjob:
      led_data.edit_properties('build.led edit-cr-cl', **change_prop)
    led_data.edit_input_recipes(
        'build.led edit (2)',
        isolated_hash='new hash').launch('build.led launch')
    return led_data.step_data + api.step_data(
        'build.read build.proto.json',
        stdout=api.json.output(json_format.MessageToDict(build)))

  def download_step_data():
    task_request_jsonish = api.testing.task_request_jsonish(legacy_qemu=True)
    return api.testing_requests.shards_step_data(
        step_name='build.download test orchestration inputs.load test shards',
        shards=[
            api.testsharder.shard(
                name='QEMU',
                tests=api.testing_requests.default_tests(),
                dimensions=dict(device_type='QEMU'),
            ),
        ]) + api.testing.task_requests_step_data(
            [task_request_jsonish],
            'build.download test orchestration inputs.load task requests',
        )

  def test_step_data(test_in_shards=True):
    if test_in_shards:
      return download_step_data() + (
          api.testing.task_retry_step_data(
              [
                  api.swarming.task_result(
                      id='610',
                      name='QEMU',
                      outputs=['out.tar'],
                  ),
              ]) +
          api.testing.test_step_data(shard_name='QEMU'))  # yapf: disable

    return download_step_data() + (
        api.testing.task_step_data([
          api.swarming.task_result(
              id='610',
              name='QEMU',
              outputs=['out.tar'],
          ),
      ]) +
    api.testing.test_step_data())  # yapf: disable

  def spec_data(use_snapshot=False,
                variants=(),
                device_type='QEMU',
                run_tests=True,
                test_in_shards=True,
                requires_secrets=False,
                gcs_bucket=None,
                debug_symbol_gcs_bucket='debug-symbols'):
    test_spec = None
    if run_tests:
      test_spec = Fuchsia.Test(
          device_type=device_type,
          max_shard_size=0,
          timeout_secs=30 * 60,
          pool='fuchsia.tests',
          test_in_shards=test_in_shards,
          requires_secrets=requires_secrets,
          swarming_expiration_timeout_secs=10 * 60,
          swarming_io_timeout_secs=5 * 60,
          upload_results=bool(gcs_bucket),
          use_runtests=True,
      )

    return api.spec.spec_loaded_ok(
        step_name='load spec.build_init',
        message=Fuchsia(
            checkout=Fuchsia.Checkout(
                manifest='manifest',
                remote='remote',
                upload_results=bool(gcs_bucket),
                use_snapshot=use_snapshot,
            ),
            build=Fuchsia.Build(
                variants=variants,
                build_type='debug',
                run_tests=run_tests,
                board='boards/x64.gni',
                product='products/core.gni',
                target='x64',
                include_symbol_archive=False,
                include_breakpad_symbols=False,
                upload_results=bool(gcs_bucket),
            ),
            test=test_spec,
            debug_symbol_gcs_bucket=debug_symbol_gcs_bucket,
            gcs_bucket=gcs_bucket,
            artifact_gcs_bucket=gcs_bucket,
        ),
    )

  ci_build = api.buildbucket.ci_build(
      project='fuchsia', git_repo='https://fuchsia.googlesource.com/fuchsia')

  yield api.fuchsia.test(
      'successful_build_and_test',
      clear_default_steps=True,
      properties={'experimental': True},
      steps=[
          child_build_steps(
              api=api,
              build=ci_build_message(
                  api=api,
                  output_props={
                      'integration revision count': 1,
                      'test_orchestration_inputs_hash': 'abc',
                  },
                  status='SUCCESS',
              ),
          ),
          api.override_step_data(
              'launch/collect.0.collect',
              api.swarming.collect([
                  api.swarming.task_result(
                      id='610',
                      name='QEMU',
                      outputs=['out.tar'],
                  ),
              ])),
      ]) + spec_data(gcs_bucket='gcs-bucket') + test_step_data()

  yield api.fuchsia.test(
      'successful_build_and_test_not_in_shards',
      clear_default_steps=True,
      steps=[
          child_build_steps(
              api=api,
              build=ci_build_message(
                  api=api,
                  output_props={
                      'integration revision count': 1,
                      'test_orchestration_inputs_hash': 'abc',
                  },
                  status='SUCCESS',
              ),
          ),
          api.override_step_data(
              'run tests.attempt 0.collect',
              api.swarming.collect([
                  api.swarming.task_result(
                      id='610',
                      name='QEMU',
                      outputs=['out.tar'],
                  ),
              ])),
      ]) + spec_data(
          gcs_bucket='gcs-bucket',
          test_in_shards=False) + test_step_data(test_in_shards=False)

  yield api.fuchsia.test(
      'build_only_failed',
      status='infra_failure',
      clear_default_steps=True,
  ) + spec_data(run_tests=False)

  yield api.fuchsia.test(
      'build_with_led',
      status='failure',
      clear_default_steps=True,
      properties={
          '$recipe_engine/led':
              LedInputProperties(
                  led_run_id='led/user_example.com/abc123',
                  isolated_input=LedInputProperties.IsolatedInput(
                      hash='abc123',
                      namespace='default-gzip',
                      server='isolateserver.appspot.com')),
      },
      steps=[
          child_led_steps(
              api=api,
              build=ci_build_message(
                  api=api,
                  output_props={'test_orchestration_inputs_hash': 'abc'},
                  status='FAILURE',
              ),
          ),
      ]) + spec_data()

  yield api.fuchsia.test(
      'build_with_led_tryjob',
      status='failure',
      clear_default_steps=True,
      properties={
          '$recipe_engine/led':
              LedInputProperties(
                  led_run_id='led/user_example.com/abc123',
                  isolated_input=LedInputProperties.IsolatedInput(
                      hash='abc123',
                      namespace='default-gzip',
                      server='isolateserver.appspot.com')),
      },
      tryjob=True,
      steps=[
          child_led_steps(
              api=api,
              tryjob=True,
              build=ci_build_message(
                  api=api,
                  output_props={'test_orchestration_inputs_hash': 'abc'},
                  status='FAILURE',
              ),
          ),
      ]) + api.build_input_resolver.set_gerrit_branch() + api.gitiles.refs(
          'refs', [
              'refs/heads/master',
              'deadbeef',
          ]) + spec_data()

  yield api.fuchsia.test(
      'build_passed_but_hash_is_missing',
      status='failure',
      clear_default_steps=True,
      steps=[
          child_build_steps(
              api=api,
              build=ci_build_message(
                  api=api,
                  status='SUCCESS',
              ),
          )
      ]) + spec_data()

  yield api.fuchsia.test(
      'requires_secrets_illegally',
      status='infra_failure',
      clear_default_steps=True,
      steps=[
          child_build_steps(
              api=api,
              build=ci_build_message(
                  api=api,
                  status='SUCCESS',
                  output_props={'test_orchestration_inputs_hash': 'abc'},
              ),
          ),
      ]) + download_step_data() + spec_data(
          device_type='Not QEMU', requires_secrets=True)

  yield (api.test('spec_parse_error') + ci_build +
         api.spec.spec_parse_error(step_name='load spec.build_init'))
