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

from recipe_engine import recipe_api
from past.builtins import long

from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2

from RECIPE_MODULES.fuchsia.utils import pluralize


class DisplayUtilApi(recipe_api.RecipeApi):
  """Module to display buildbucket or swarming tasks as steps."""

  def display_subbuilds(self, step_name, subbuilds, raise_on_failure=False):
    """Display build links and status for each input build.

        Optionally raise on build failure(s).

        Args:
          step_name (str): Name of build group to display in step name.
          builds (seq(buildbucket.v2.Build)): buildbucket Build objects. See
            recipe_engine/buildbucket recipe module for more info.
          raise_on_failure (bool): Raise InfraFailure or StepFailure on failure.

        Raises:
          InfraFailure: One or more input builds had infra failure. Takes priority
            over step failures.
          StepFailure: One or more of input builds failed.
        """
    # List of failed builds
    infra_failures = []
    failures = []
    # Create per-build display steps.
    infra_failure_states = [
        common_pb2.Status.Value('INFRA_FAILURE'),
        common_pb2.Status.Value('CANCELED')
    ]
    with self.m.step.nest(step_name) as presentation:
      for id_name, build in subbuilds.items():
        with self.m.step.nest(build.build_name) as display_step:
          step_links = display_step.links
          step_links[str(build.build_id)] = build.url
          if build.build_proto.status == common_pb2.Status.Value('SUCCESS'):
            display_step.status = self.m.step.SUCCESS
          elif build.build_proto.status in infra_failure_states:
            display_step.status = self.m.step.EXCEPTION
            infra_failures.append(build)
          elif build.build_proto.status == common_pb2.Status.Value('FAILURE'):
            display_step.status = self.m.step.FAILURE
            failures.append(build)
          # For any other status, use warning color.
          else:
            display_step.status = self.m.step.WARNING

      def summary_section(build):
        url = self.m.buildbucket.build_url(build_id=build.build_id)
        failure_header = "[%s](%s)" % (build.build_name, url)
        if build.build_proto.status == common_pb2.INFRA_FAILURE:
          failure_header += " (infra failure)"
        summary = build.build_proto.summary_markdown.strip()
        # Don't include an empty summary.
        if not summary:
          return failure_header
        return failure_header + ":\n\n%s" % summary

      failure_message_parts = []
      for b in infra_failures + failures:
        failure_message_parts.append(summary_section(b))

      if raise_on_failure:
        # If there were any infra failures, raise purple.
        if infra_failures:
          presentation.status = self.m.step.EXCEPTION
          exception_type = self.m.step.InfraFailure
        # Otherwise if there were any step failures, raise red.
        elif failures:
          presentation.status = self.m.step.FAILURE
          exception_type = self.m.step.StepFailure
        else:
          return

        num_failed = len(failures) + len(infra_failures)
        raise exception_type(
            "%s failed:\n\n%s" % (
                pluralize("build",
                          num_failed), "\n\n".join(failure_message_parts)
            )
        )

  def display_builds(self, step_name, builds, raise_on_failure=False):
    """Display build links and status for each input build.

        Optionally raise on build failure(s).

        Args:
          step_name (str): Name of build group to display in step name.
          builds (seq(buildbucket.v2.Build)): buildbucket Build objects. See
            recipe_engine/buildbucket recipe module for more info.
          raise_on_failure (bool): Raise InfraFailure or StepFailure on failure.

        Raises:
          InfraFailure: One or more input builds had infra failure. Takes priority
            over step failures.
          StepFailure: One or more of input builds failed.
        """
    # List of failed builds
    infra_failures = []
    failures = []
    # Create per-build display steps.
    infra_failure_states = [
        common_pb2.Status.Value('INFRA_FAILURE'),
        common_pb2.Status.Value('CANCELED')
    ]
    with self.m.step.nest(step_name) as presentation:
      for k in builds:
        build = builds[k] if isinstance(k, long) or isinstance(k, int) else k
        with self.m.step.nest(build.builder.builder) as display_step:
          step_links = display_step.links
          step_links[str(build.id)
                    ] = self.m.buildbucket.build_url(build_id=build.id)
          if build.status == common_pb2.Status.Value('SUCCESS'):
            display_step.status = self.m.step.SUCCESS
          elif build.status in infra_failure_states:
            display_step.status = self.m.step.EXCEPTION
            infra_failures.append(build)
          elif build.status == common_pb2.Status.Value('FAILURE'):
            display_step.status = self.m.step.FAILURE
            failures.append(build)
          # For any other status, use warning color.
          else:
            display_step.status = self.m.step.WARNING

      def summary_section(build):
        url = self.m.buildbucket.build_url(build_id=build.id)
        failure_header = "[%s](%s)" % (build.builder.builder, url)
        if build.status == common_pb2.INFRA_FAILURE:
          failure_header += " (infra failure)"
        summary = build.summary_markdown.strip()
        # Don't include an empty summary.
        if not summary:
          return failure_header
        return failure_header + ":\n\n%s" % summary

      failure_message_parts = []
      for b in infra_failures + failures:
        failure_message_parts.append(summary_section(b))

      if raise_on_failure:
        # If there were any infra failures, raise purple.
        if infra_failures:
          presentation.status = self.m.step.EXCEPTION
          exception_type = self.m.step.InfraFailure
        # Otherwise if there were any step failures, raise red.
        elif failures:
          presentation.status = self.m.step.FAILURE
          exception_type = self.m.step.StepFailure
        else:
          return

        num_failed = len(failures) + len(infra_failures)
        raise exception_type(
            "%s failed:\n\n%s" % (
                pluralize("build",
                          num_failed), "\n\n".join(failure_message_parts)
            )
        )

  def display_tasks(self, step_name, results, metadata, raise_on_failure=False):
    """Display task links and status for each input task.

        Optionally raise on build failure(s).

        Args:
          step_name (str): Name of build group to display in step name.
          results (seq(swarming.TaskResult)): swarming TaskResult objects. See
            recipe_engine/swarming recipe module for more info.
          metadata (seq(swarming.TaskMetadata)): swarming TaskMetadata objects. See
            recipe_engine/swarming recipe module for more info.
          raise_on_failure (bool): Raise InfraFailure or StepFailure on failure.

        Raises:
          InfraFailure: One or more input builds had infra failure. Takes priority
            over step failures.
          StepFailure: One or more of input builds failed.
        """
    self._display(
        step_name=step_name,
        builds=results,
        raise_on_failure=raise_on_failure,
        process_func=self._process_task,
        metadata=metadata,
    )

  def _process_task(
      self, result, infra_failed_builders, failed_builders, links
  ):
    """Process a single swarming.TaskResult.

        Args:
          result (swarming.TaskResult): A swarming TaskResult object.
          infra_failed_builders (List(str)): A list of the builder names with infra failures.
          failed_builders (List(str)): A list of the builder names with failures.
          links (Dict): A dictionary with the task links as values and the task id as keys.
        """
    with self.m.step.nest(result.name) as display_step:
      step_links = display_step.links
      step_links[str(result.id)] = links[result.id]
      if (result.state is None or
          result.state != self.m.swarming.TaskState.COMPLETED):
        display_step.status = self.m.step.EXCEPTION
        infra_failed_builders.append(result.name)
      elif not result.success:
        display_step.status = self.m.step.FAILURE
        failed_builders.append(result.name)
      else:
        display_step.status = self.m.step.WARNING

  def _display(
      self,
      step_name,
      builds,
      process_func,
      raise_on_failure=False,
      metadata=None
  ):
    """Display build links and status for each input build.

        Optionally raise on build failure(s).

        Args:
          step_name (str): Name of build group to display in step name.
          builds (seq(buildbucket.v2.Build) or seq(swarming.TaskResult)): buildbucket Build or swarming TaskResult objects. See
            recipe_engine/buildbucket or recipe_engine/swarming recipe module for more info.
          process_func (Runnable): A function to process a build or task result object.
          raise_on_failure (bool): Raise InfraFailure or StepFailure on failure.
          metadata (seq(swarming.TaskMetadata)): swarming TaskMetadata objects. See
            recipe_engine/swarming recipe module for more info.

        Raises:
          InfraFailure: One or more input builds had infra failure. Takes priority
            over step failures.
          StepFailure: One or more of input builds failed.
        """
    infra_failed_builders = []
    failed_builders = []
    # Create per-build display steps.
    with self.m.step.nest(step_name):
      for k in builds:
        build = builds[k] if isinstance(k, (long, int)) else k
        args = {
            "result": build,
            "infra_failed_builders": infra_failed_builders,
            "failed_builders": failed_builders,
        }
        if metadata:
          args["links"] = {m.id: m.task_ui_link for m in metadata}
        process_func(**args)

      if raise_on_failure:
        # Construct failure header and message. Include both types of failures,
        # regardless of whether we raise purple or red.
        failure_header = "build(s) failed"
        failure_message = []
        if infra_failed_builders:
          failure_message.append(
              "infra failures: {infra_failed_builders}".format(
                  infra_failed_builders=", ".join(infra_failed_builders)
              )
          )
        if failed_builders:
          failure_message.append(
              "step failures: {failed_builders}".format(
                  failed_builders=", ".join(failed_builders)
              )
          )
        failure_message = ", ".join(failure_message)
        # If there were any infra failures, raise purple.
        if infra_failed_builders:
          self.m.step.empty(
              failure_header,
              status=self.m.step.INFRA_FAILURE,
              step_text=failure_message,
          )
        # Otherwise if there were any step failures, raise red.
        if failed_builders:
          self.m.step.empty(
              failure_header,
              status=self.m.step.FAILURE,
              step_text=failure_message,
          )
