# 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_test_api
from PB.go.chromium.org.luci.buildbucket.proto import (
    builds_service as builds_service_pb2,
)
from PB.go.chromium.org.luci.led.job import job as job_pb2


class SubbuildTestApi(recipe_test_api.RecipeTestApi):

  def ci_build_message(
      self, builder, input_props=None, output_props=None, **kwargs
  ):
    """Generates a CI Buildbucket Build message.

        Args:
          builder (str): The builder name.
          input_props (Dict): Input properties to set on the build.
          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.
        """
    project = kwargs.pop("project", "fuchsia")
    msg = self.m.buildbucket.ci_build_message(
        builder=builder, project=project, **kwargs
    )
    msg.infra.swarming.task_id = "abc123"
    msg.input.properties.update(input_props if input_props else {})
    msg.output.properties.update(output_props if output_props else {})
    return msg

  def try_build_message(
      self, builder, input_props=None, output_props=None, **kwargs
  ):
    """Generates a try Buildbucket Build message.

        Args:
          builder (str): The builder name.
          input_props (Dict): Input properties to set on the build.
          output_props (Dict): Output properties to set on the build.
          kwargs: Forwarded to BuildbucketApi.try_build_message.

        See BuildBucketTestApi.try_build_message for full parameter documentation.
        """
    project = kwargs.pop("project", "fuchsia")
    msg = self.m.buildbucket.try_build_message(
        builder=builder, project=project, **kwargs
    )
    msg.infra.swarming.task_id = "abc123"
    msg.input.properties.update(input_props if input_props else {})
    msg.output.properties.update(output_props if output_props else {})
    return msg

  def child_build_steps(
      self,
      builds,
      launch_step="build",
      collect_step="build",
      collect_attempt=1
  ):
    """Generates step data to schedule and collect from child builds.

        Args:
          builds (list(build_pb2.Build)): The builds to schedule and collect from.
        """
    responses = []
    for build in builds:
      responses.append(
          dict(schedule_build=dict(id=build.id, builder=build.builder))
      )
    mock_schedule_data = self.m.buildbucket.simulated_schedule_output(
        step_name=f"{launch_step}.schedule",
        batch_response=builds_service_pb2.BatchResponse(responses=responses),
    )

    index = "" if collect_attempt <= 1 else (f" ({collect_attempt})")
    mock_collect_data = self.m.buildbucket.simulated_collect_output(
        step_name=f"{collect_step}.collect{index}",
        builds=builds,
    )
    return mock_schedule_data + mock_collect_data

  def child_led_steps(
      self,
      builds,
      collect_step="build",
  ):
    """Generates step data to schedule and collect from child builds.

        Args:
          builds (list(build_pb2.Build)): The builds to schedule and collect from.
        """
    step_data = []
    task_results = []
    i = 0
    for build in builds:
      i += 1
      suffix = ""
      if i > 1:
        suffix = f" ({int(i)})"

      task_id = f"fake-task-id-{int(i)}"

      # led launch mock will take ....infra.swarming.task_id as this
      # build's launched swarming ID.
      jd = job_pb2.Definition()
      jd.buildbucket.bbagent_args.build.CopyFrom(build)
      jd.buildbucket.bbagent_args.build.infra.swarming.task_id = task_id
      step_data.append(
          self.m.led.mock_get_builder(
              jd,
              build.builder.project,
              build.builder.bucket,
              build.builder.builder,
          )
      )
      task_results.append(
          self.m.swarming.task_result(id=task_id, name=build.builder.builder)
      )
      step_data.append(
          self.step_data(
              f"{collect_step}.read build.proto.json{suffix}",
              self.m.file.read_proto(build),
          )
      )
    ret = self.step_data(
        f"{collect_step}.collect", self.m.swarming.collect(task_results)
    )
    for s in step_data:
      ret += s
    return ret
