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

import attr

import collections
import datetime

from recipe_engine import recipe_api
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 RECIPE_MODULES.fuchsia.utils import pluralize

# As of 2021-10-19, the `api.buildbucket.collect()` timeout defaults to
# something too short. We never want subbuild collection to timeout; we'd rather
# the whole build time out.
COLLECT_TIMEOUT = datetime.timedelta(hours=24)

# We implicitly rely on a select few properties being passed through
# from the parent build to the subbuild.
# NOTE: Only dynamically computed properties should be passed through
# automatically. Any static properties (i.e. properties that don't change
# between builds) should be configured explicitly on the subbuild's builder
# rather than implicitly passing them through.
PASS_THROUGH_PROPERTIES = {
    # Used by toolchain recipes to pass custom toolchain info.
    "$fuchsia/build",
    # Used by toolchain recipes to pass commit info.
    "$fuchsia/checkout",
    # recipe_bootstrap may pass some properties to subbuilds via this field.
    "$fuchsia/recipe_bootstrap",
    # If a parent build is running under recipe testing, then the
    # subbuild is as well, and it should be made aware of that.
    "$fuchsia/recipe_testing",
    # Needed for subbuilds to determine how the parent was invoked in CQ
    # (e.g. whether it's a dry run or full run).
    "$recipe_engine/cq",
    # Set by recipe_bootstrap. A subbuild should inherit the same
    # integration base revision as its parent so the two builds use the same
    # version of recipes and properties.
    "integration_base_revision",
    # Set by `led edit-recipe-bundle -property-only` to point to the uploaded
    # recipe bundle. It's then up to recipe_bootstrap to download the recipe
    # bundle and execute it. A led subbuild should use the same recipe bundle
    # version as its parent.
    "led_cas_recipe_bundle",
    # Set by recipe_engine on buildbucket builds.
    "$recipe_engine/buildbucket",
}


@attr.s
class SubbuildResult:
  """Subbuild result metadata."""

  builder = attr.ib(type=str)
  build_id = attr.ib(type=str, converter=str)
  url = attr.ib(type=str, default=None)
  build_proto = attr.ib(type=build_pb2.Build, default=None)


@attr.s
class _SplitBuilder:
  """Project/bucket/name triplet."""

  project = attr.ib(type=str)
  bucket = attr.ib(type=str)
  name = attr.ib(type=str)


class SubbuildApi(recipe_api.RecipeApi):
  """API for launching subbuilds and collecting the results."""

  def launch(
      self,
      builder_names,
      presentation,
      extra_properties=None,
      set_swarming_parent_run_id=True,
      hide_in_gerrit=True,
      include_sub_invs=True,
  ):
    """Launches builds with buildbucket or led.

        If the current task was launched with led, then subbuilds will also be
        launched with led.

        Args:
          builder_names (list(str)): The names of the builders to launch.
          presentation (StepPresentation): The presentation to add logs to.
          extra_properties (dict): The extra set of properties to launch the
            builders with. These will override the parent properties that will be
            passed to the children by default.
          set_swarming_parent_run_id (bool): Whether to set swarming parent run
            ID on buildbucket builds.
          hide_in_gerrit (bool): Hide buildbucket subbuilds in the Gerrit UI.
          include_sub_invs (bool): Whether the parent should inherit ResultDB
            test results from the child builds.

        Returns:
          launched_builds (dict): The launched_builds is a map from builder name
          to the corresponding SubbuildResult.
        """
    parent_properties = self.m.properties.thaw()
    properties = {
        key: val
        for key, val in parent_properties.items()
        if key and key in PASS_THROUGH_PROPERTIES
    }
    if extra_properties:
      properties.update(extra_properties)

    # 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. That is a requirement for testing, as well as for
    # avoiding the need to do soft transitions when updating the interface
    # between the parent and child recipes.
    if self.m.led.launched_by_led:
      builds = self._launch_with_led(builder_names, properties)
    else:
      builds = self._launch_with_buildbucket(
          builder_names,
          properties,
          set_swarming_parent_run_id=set_swarming_parent_run_id,
          hide_in_gerrit=hide_in_gerrit,
          include_sub_invs=include_sub_invs,
      )
    for builder, build in builds.items():
      presentation.links[builder] = build.url
    return builds

  def split_builder(self, builder_name):
    """Split a builder name into parts, filling in from current build."""
    parent = self.m.buildbucket.build.builder

    *prefixes, name = builder_name.split("/")
    assert len(prefixes) <= 2, f"bad builder_name {builder_name}"
    if len(prefixes) == 2:
      project, bucket = prefixes
    elif len(prefixes) == 1:
      project = parent.project
      bucket = prefixes[0]
    else:
      project = parent.project
      bucket = parent.bucket

    return _SplitBuilder(project, bucket, name)

  def _launch_with_led(self, builder_names, properties):
    edit_args = []
    for k, v in sorted(properties.items()):
      edit_args.extend(["-p", f"{k}={self.m.json.dumps(v)}"])
    edit_cr_cl_arg = None
    bb_input = self.m.buildbucket.build.input
    if bb_input.gerrit_changes:
      gerrit_change = bb_input.gerrit_changes[0]
      edit_cr_cl_arg = f"https://{gerrit_change.host}/c/{gerrit_change.project}/+/{int(gerrit_change.change)}"

    builds = {}
    for builder_name in builder_names:
      builder = self.split_builder(builder_name)
      led_data = self.m.led(
          "get-builder",
          # By default, led reduces the priority of tasks from their
          # values in buildbucket which we do not want.
          "-adjust-priority",
          "0",
          f"{builder.project}/{builder.bucket}/{builder.name}",
      )
      led_data = led_data.then("edit", *edit_args)
      if edit_cr_cl_arg:
        led_data = led_data.then("edit-cr-cl", edit_cr_cl_arg)
      led_data = self.m.led.inject_input_recipes(led_data)
      launch_res = led_data.then("launch", "-modernize", "-real-build")
      task_id = launch_res.launch_result.build_id
      build_url = launch_res.launch_result.build_url
      builds[builder_name] = SubbuildResult(
          builder=builder_name, build_id=task_id, url=build_url
      )
    return builds

  def _launch_with_buildbucket(
      self,
      builder_names,
      properties,
      set_swarming_parent_run_id,
      hide_in_gerrit,
      include_sub_invs,
  ):
    reqs = []
    swarming_parent_run_id = (
        self.m.swarming.task_id if set_swarming_parent_run_id else None
    )
    bb_tags = {"skip-retry-in-gerrit": "subbuild"}
    if hide_in_gerrit:
      bb_tags["hide-in-gerrit"] = "subbuild"
    for builder_name in builder_names:
      builder = self.split_builder(builder_name)
      reqs.append(
          self.m.buildbucket.schedule_request(
              project=builder.project,
              bucket=builder.bucket,
              builder=builder.name,
              properties=properties,
              swarming_parent_run_id=swarming_parent_run_id,
              priority=None,  # Leave unset to avoid overriding priority from configs.
              tags=self.m.buildbucket.tags(**bb_tags),
          )
      )

    scheduled_builds = self.m.buildbucket.schedule(
        reqs, step_name="schedule", include_sub_invs=include_sub_invs
    )

    builds = {}
    for build in scheduled_builds:
      build_url = f"https://ci.chromium.org/b/{build.id}"
      builds[build.builder.builder] = SubbuildResult(
          builder=build.builder.builder, build_id=build.id, url=build_url
      )
    return builds

  def collect(self, build_ids, launched_by_led=None, extra_fields=frozenset()):
    """Collects builds with the provided build_ids.

        Args:
          build_ids (list(str)): The list of build ids to collect results for.
          presentation (StepPresentation): The presentation to add logs to.
          launched_by_led (bool|None): Whether the builds to collect were
              launched by led. If None, then this value will be determined by
              whether the current task was launched by led.
          extra_fields (set): Extra fields to include in the buildbucket
            response.

        Returns:
          A map from build IDs to the corresponding SubbuildResult.
        """
    if launched_by_led is None:
      launched_by_led = self.m.led.launched_by_led
    builds = self._collect_from_buildbucket(build_ids, extra_fields)
    return collections.OrderedDict(
        sorted(builds.items(), key=lambda item: (item[1].builder, item[0]))
    )

  def get_property(self, build_proto, property_name):
    """Retrieve an output property from a subbuild's Build proto.

        Ensures a clear and unified missing property error message across all
        builders that use this recipe module.
        """
    try:
      return build_proto.output.properties[property_name]
    except ValueError:
      raise self.m.step.InfraFailure(
          f"Subbuild did not set the {property_name!r} output property"
      )

  def _collect_from_buildbucket(self, build_ids, extra_fields):
    bb_fields = self.m.buildbucket.DEFAULT_FIELDS.union({"summary_markdown"}
                                                       ).union(extra_fields)

    builds = self.m.buildbucket.collect_builds(
        [int(build_id) for build_id in build_ids],
        interval=20,  # Lower from default of 60 b/c we're impatient.
        timeout=COLLECT_TIMEOUT,
        step_name="collect",
        fields=bb_fields,
    )

    failed_builds = [
        b for b in builds.values() if b.status != common_pb2.SUCCESS
    ]
    if failed_builds:
      task_ids = [b.infra.backend.task.id.id for b in failed_builds]
      # Make sure task IDs are non-empty.
      assert all(task_ids), task_ids

      # Wait for the underlying Swarming tasks to complete. The Swarming
      # task for a Buildbucket build can take significantly longer to
      # complete than the build itself due to post-processing outside the
      # scope of the build's recipe (e.g. cache pruning). If the parent
      # build and its Swarming task both complete before the subbuild's
      # Swarming task finishes post-processing, then the subbuild's
      # Swarming task will be killed by Swarming due to the parent being
      # complete.
      #
      # That is actually working as intended. However, it's confusing for
      # a subbuild to be marked as killed when the recipe actually exited
      # normally; "killed" usually only happens for CQ builds, when a
      # build is canceled by CQ because a new patchset of the triggering
      # CL is uploaded. So it's convenient to have dashboards and queries
      # ignore "killed" tasks. We use this workaround to ensure that
      # failed subbuilds with long post-processing steps have time to
      # complete and exit cleanly with a plain old "COMPLETED (FAILURE)"
      # status.
      #
      # We only do this if the subbuild failed as a latency optimization.
      # If all subbuilds passed, the parent will go on to do some more
      # steps using the results of the subbuilds, leaving time for the
      # subbuilds' tasks to complete asynchronously, so we don't want to
      # block here while the tasks complete.
      self.m.swarming.collect(
          f"wait for {pluralize('task', task_ids)} to complete", task_ids
      )
    return {
        str(build.id):
            SubbuildResult(
                builder=build.builder.builder,
                build_id=build.id,
                build_proto=build
            ) for build in builds.values()
    }
