# Copyright 2020 The Chromium 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 google.protobuf import json_format
from past.builtins import basestring
from recipe_engine import recipe_api
from PB.go.chromium.org.luci.buildbucket.proto import build as build_pb2


class Job(object):
  """Describes a job that could be launched via led.

  Attributes:
    name (str): Name of the job.
    properties (dict): Properties as the arguments to `led edit -p`.
    dimensions (dict): Dimensions as the arguments to `led edit -d`.
    task_id (str): Id of the swarming task.
    task_server (str): Host name of the swarming server, e.g.
        "chromium-swarm.appspot.com".
    task_result (api.swarming.TaskResult): Result of the swarming task.
    build_proto(build_pb2.Build): Proto generated from a buildbucket build.
    outcome (str): The outcome could be "success", "none" when task_result.state
        is None, or TaskState in lower case.
  """

  def __init__(self, name):
    # Metadata attached before execution.
    assert isinstance(name, basestring)
    self.name = name
    self.properties = {'name': name}
    self.dimensions = {}

    # Metadata attached during execution.
    self.task_id = None
    self.task_server = None

    # Metadata attached after execution.
    self.task_result = None
    self.build_proto = None
    self.outcome = None

  @property
  def task_url(self):
    """Returns the URL of the associated task in the Swarming UI."""
    return "%s/task?id=%s" % (self.task_server, self.task_id)

  @property
  def milo_url(self):
    """Returns the URL of the associated task in the Milo UI."""
    return "https://ci.chromium.org/swarming/task/%s?server=%s" % (
        self.task_id, self.task_server)


class JobApi(recipe_api.RecipeApi):
  """API for launching jobs and collecting the results."""

  def __init__(self, *args, **kwargs):
    super(JobApi, self).__init__(*args, **kwargs)

  def new(self, job_name):
    return Job(job_name)

  def current_recipe(self):
    return self.m.properties.get('recipe')

  def launch(self, job, presentation):
    """Launches a job with led.

    Args:
      job (Job): The job definition.
      presentation (StepPresentation): The presentation to add logs to.

    Returns:
      The input job object with additional details about the execution.
    """
    current = self.m.buildbucket.build.builder
    led_data = self.m.led(
        "get-builder",
        "luci.%s.%s:%s" % (current.project, current.bucket, current.builder),
    )
    edit_args = []
    for k, v in sorted(job.properties.items()):
      edit_args.extend(["-p", "%s=%s" % (k, self.m.json.dumps(v))])
    for k, v in sorted(job.dimensions.items()):
      edit_args.extend(["-d", "%s=%s" % (k, v)])
    led_data = led_data.then("edit", *edit_args)
    led_data = self.m.led.inject_input_recipes(led_data)
    final = led_data.then("launch", "-modernize")

    job.task_id = final.launch_result.task_id
    job.task_server = final.launch_result.swarming_hostname

    presentation.links[job.name] = job.milo_url
    return job

  def collect(self, jobs, presentation):
    """Collects execution metadata for a list of jobs.

    Args:
      jobs (list(Job)): The jobs to collect information for.
      presentation (StepPresentation): The presentation to add logs to.

    Returns:
      The input jobs with additional details collected from execution.
    """
    by_task_id = {job.task_id: job for job in jobs}
    swarming_results = self.m.swarming.collect(
        "collect",
        sorted(by_task_id.keys()),
        output_dir=self.m.path["cleanup"],
    )
    for result in sorted(swarming_results, key=lambda x: x.id):
      job = by_task_id[result.id]
      job.task_result = result

      # Led launch ensures this file is present in the task root dir.
      build_proto_path = result.output_dir.join("build.proto.json")
      build_proto = self.m.file.read_proto(
          "read build.proto.json", build_proto_path, build_pb2.Build, "JSONPB")
      job.build_proto = build_proto

      if result.success:
        job.outcome = "success"
      elif not result.state:
        job.outcome = "none"
      else:
        # Example result.state: TaskState.COMPLETED
        job.outcome = str(result.state)[10:].lower()

      presentation.links["%s (%s)" % (job.name, job.outcome)] = job.milo_url
    return jobs
