# 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.presentation.links
          step_links[str(build.build_id)] = build.url
          if build.build_proto.status == common_pb2.Status.Value('SUCCESS'):
            display_step.presentation.status = self.m.step.SUCCESS
          elif build.build_proto.status in infra_failure_states:
            display_step.presentation.status = self.m.step.EXCEPTION
            infra_failures.append(build)
          elif build.build_proto.status == common_pb2.Status.Value('FAILURE'):
            display_step.presentation.status = self.m.step.FAILURE
            failures.append(build)
          # For any other status, use warning color.
          else:
            display_step.presentation.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.presentation.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.presentation.status = self.m.step.SUCCESS
          elif build.status in infra_failure_states:
            display_step.presentation.status = self.m.step.EXCEPTION
            infra_failures.append(build)
          elif build.status == common_pb2.Status.Value('FAILURE'):
            display_step.presentation.status = self.m.step.FAILURE
            failures.append(build)
          # For any other status, use warning color.
          else:
            display_step.presentation.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.presentation.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.presentation.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,
          )
