# Copyright 2019 The LUCI Authors. All rights reserved.
# Use of this source code is governed under the Apache License, Version 2.0
# that can be found in the LICENSE file.
"""Recipe API for LUCI CV, the pre-commit testing system."""


import re

from google.protobuf import json_format as json_pb

from PB.go.chromium.org.luci.cv.api.recipe.v1 import cq as cq_pb2

from recipe_engine import recipe_api


class CVApi(recipe_api.RecipeApi):
  """This module provides recipe API of LUCI CV, a pre-commit testing system."""

  # Common Run modes.
  NEW_PATCHSET_RUN = 'NEW_PATCHSET_RUN'
  DRY_RUN = 'DRY_RUN'
  QUICK_DRY_RUN = 'QUICK_DRY_RUN'
  FULL_RUN = 'FULL_RUN'

  class CVInactive(Exception):
    """Incorrect usage of CVApi method requiring active CV."""

  CQInactive = CVInactive

  def __init__(self, input_props, **kwargs):
    super().__init__(**kwargs)
    self._input = input_props
    self._active = False
    self._output = cq_pb2.Output()

  def initialize(self):
    if self._input.active or (
        # legacy style
        'dry_run' in self.m.properties.get('$recipe_engine/cq', {})):
      self._active = True
    if self._active and not self._input.run_mode:
      # backfill
      self._input.run_mode = (
          self.DRY_RUN if self._input.dry_run else self.FULL_RUN)

  @property
  def active(self):
    """Returns whether CQ is active for this build."""
    return self._active

  @property
  def run_mode(self):
    """Returns the mode(str) of the CQ Run that triggers this build.

    Raises:
      CQInactive if CQ is not active for this build.
    """
    self._enforce_active()
    return self._input.run_mode

  @property
  def experimental(self):
    """Returns whether this build is triggered for a CQ experimental builder.

    See `Builder.experiment_percentage` doc in [CQ
    config](https://chromium.googlesource.com/infra/luci/luci-go/+/main/cv/api/config/v2/config.proto)

    Raises:
      CQInactive if CQ is not active for this build.
    """
    self._enforce_active()
    return self._input.experimental

  @property
  def top_level(self):
    """Returns whether CQ triggered this build directly.

    Can be spoofed. *DO NOT USE FOR SECURITY CHECKS.*

    Raises:
      CQInactive if CQ is not active for this build.
    """
    self._enforce_active()
    return self._input.top_level

  @property
  def ordered_gerrit_changes(self):
    """Returns list[bb_common_pb2.GerritChange] in order in which CLs should be
    applied or submitted.

    Raises:
      CQInactive if CQ is not active for this build.
    """
    self._enforce_active()
    assert self.m.buildbucket.build.input.gerrit_changes, (
        'you must simulate buildbucket.input.gerrit_changes in your test '
        'in order to use api.cv.ordered_gerrit_changes')
    return self.m.buildbucket.build.input.gerrit_changes

  @property
  def props_for_child_build(self):
    """Returns properties dict meant to be passed to child builds.

    These will preserve the CQ context of the current build in the
    about-to-be-triggered child build.

    ```python
    properties = {'foo': bar, 'protolike': proto_message}
    properties.update(api.cv.props_for_child_build)
    req = api.buildbucket.schedule_request(
        builder='child',
        gerrit_changes=list(api.buildbucket.build.input.gerrit_changes),
        properties=properties)
    child_builds = api.buildbucket.schedule([req])
    api.cv.record_triggered_builds(*child_builds)
    ```

    The contents of returned dict should be treated as opaque blob,
    it may be changed without notice.
    """
    if not self._input.active:
      return {}
    msg = cq_pb2.Input()
    msg.CopyFrom(self._input)
    msg.top_level = False
    return {
        '$recipe_engine/cq':
            json_pb.MessageToDict(msg, preserving_proto_field_name=True)
    }

  @property
  def attempt_key(self):
    """Returns a string that is unique for a CV attempt.

    The same `attempt_key` will be used for all builds within an
    attempt.

    Raises:
      CQInactive if CQ is not active for this build.
    """
    return self._extract_unique_cq_tag('attempt_key')

  @property
  def cl_group_key(self):
    """Returns a string that is unique for a current set of Gerrit change
    patchsets (or, equivalently, buildsets).

    The same `cl_group_key` will be used if another Attempt is made for the
    same set of changes at a different time.

    Raises:
      CQInactive if CQ is not active for this build.
    """
    return self._extract_unique_cq_tag('cl_group_key')

  @property
  def equivalent_cl_group_key(self):
    """Returns a string that is unique for a given set of Gerrit changes
    disregarding trivial patchset differences.

    For example, when a new "trivial" patchset is uploaded, then the
    cl_group_key will change but the equivalent_cl_group_key will stay the same.

    Raises:
      CQInactive if CQ is not active for this build.
    """
    return self._extract_unique_cq_tag('equivalent_cl_group_key')

  @property
  def cl_owners(self):
    """Returns string(s) of the owner's email addresses used for the patchset.

    Usually CLs only have one owner, but more than one is possible so a list
    will be returned.

    Raises:
      CQInactive if CQ is not active for this build.
    """
    self._enforce_active()
    key = 'cq_cl_owner'
    cl_owner_strings = []
    for t in self.m.buildbucket.build.tags:
      if t.key == key:
        cl_owner_strings.append(t.value)
    return cl_owner_strings

  @property
  def triggered_build_ids(self):
    """Returns recorded Buildbucket build IDs as a list of integers."""
    return [bid for bid in self._output.triggered_build_ids]

  def record_triggered_builds(self, *builds):
    """Adds IDs of given Buildbucket builds to the list of triggered build IDs.

    Must be called after some step.

    Expected usage:
      ```python
        api.cv.record_triggered_builds(*api.buildbucket.schedule([req1, req2]))
      ```

    Args:
      * [`Build`](https://chromium.googlesource.com/infra/luci/luci-go/+/main/buildbucket/proto/build.proto)
        objects, typically returned by `api.buildbucket.schedule`.
    """
    return self.record_triggered_build_ids(*[b.id for b in builds])

  def record_triggered_build_ids(self, *build_ids):
    """Adds the given Buildbucket build IDs to the list of triggered build IDs.

    Must be called after some step.

    Args:
      * build_ids (list of int or string): Buildbucket build IDs.
    """
    if not build_ids:
      return
    self._output.triggered_build_ids.extend(int(bid) for bid in build_ids)
    self._write_output_props(
        triggered_build_ids=[
            str(bid) for bid in self._output.triggered_build_ids
        ],)

  @property
  def do_not_retry_build(self):
    return self._output.retry == cq_pb2.Output.OUTPUT_RETRY_DENIED

  def set_do_not_retry_build(self):
    """Instruct CQ to not retry this build.

    This mechanism is used to reduce duration of CQ attempt and save testing
    capacity if retrying will likely return an identical result.
    """
    if self._output.retry == cq_pb2.Output.OUTPUT_RETRY_DENIED:
      return
    self._output.retry = cq_pb2.Output.OUTPUT_RETRY_DENIED
    self._write_output_props(
        cur_step=self.m.step('TRYJOB DO NOT RETRY', cmd=None),
        do_not_retry=True,
    )

  @property
  def allowed_reuse_modes(self):
    return [m for m in self._output.reusability.mode_allowlist]

  def allow_reuse_for(self, *modes):
    """Instructs CQ that this build can be reused in a future Run if
    and only if its mode is in the provided modes.

    Overwrites all previously set values.
    """
    # TODO(yiwzhang): Expose low-level method to modify reuse if needed.
    if not modes:
      raise ValueError('expected at least 1 modes, got 0')
    del self._output.reusability.mode_allowlist[:]
    self._output.reusability.mode_allowlist.extend(modes)
    # TODO(crbug/1225047): Stop populating _output.reuse after CQDaemon is
    # decommissioned. For now, CQDaemon will still use this field to decide
    # reusability.
    del self._output.reuse[:]
    self._output.reuse.extend(cq_pb2.Output.Reuse(mode_regexp=m) for m in modes)
    self._write_output_props()

  @property
  def owner_is_googler(self):
    """Returns whether the Run/Attempt owner is a Googler.

    DO NOT USE: this is a temporary workaround for crbug.com/1259887 that is
    supposed to be used by builders in Chrome project only.
    Raises:
      CQInactive if CQ is not active for this build.
      ValueError if the builder is not in Chrome project.
    """
    self._enforce_active()
    if (self.m.buildbucket.build.builder.project != 'chrome' and
        not self.m.buildbucket.build.builder.project.startswith('chrome-m')):
      raise ValueError('owner_is_googler can only be called for chrome project')
    return self._input.owner_is_googler

  def _extract_unique_cq_tag(self, suffix):
    key = 'cq_' + suffix
    self._enforce_active()
    for t in self.m.buildbucket.build.tags:
      if t.key == key:
        return t.value
    raise ValueError('Can\'t find tag with key %r' % key)  # pragma: nocover

  def _write_output_props(self, cur_step=None, **addition_props):
    # TODO(iannucci): add API to set properties regardless of the current step.
    if not cur_step:
      cur_step = self.m.step.active_result
      assert cur_step, 'must be called after some step'
    output = cq_pb2.Output()
    output.CopyFrom(self._output)
    cur_step.presentation.properties['$recipe_engine/cq/output'] = output
    for k, v in addition_props.items():
      cur_step.presentation.properties[k] = v

  def _enforce_active(self):
    if not self._active:
      raise self.CQInactive()
