# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Functions for forgiving false Pre-CQ rejections."""

from __future__ import print_function
from __future__ import absolute_import
from __future__ import division

from chromite.lib import cros_logging as logging

from exonerator import gerrit_cq
from exonerator import constants


_MESSAGE_FOR_PRECQ_PICKED_UP = 'The Pre-Commit Queue has picked up your change.'
_TRYBOT_READY_LABEL = 'Trybot-Ready'
_COMMIT_QUEUE_LABEL = 'Commit-Queue'
_VERIFIED_LABEL = 'Verified'
_EXONERATOR_PRECQ_MESSAGE = """\
CL-Exonerator has triggered a Pre-CQ retry on this CL due to a Pre-CQ sanity
failure.
"""


def MaybeExonerate(change, build_id):
  """Mark a CL as Trybot-Ready only if it hasn't already been.

  Args:
    change: A GerritPatchTuple.
    build_id: The CIDB id for the build which the change was kicked out of.
  """
  helper = gerrit_cq.GetHelper(internal=change.internal)
  details = helper.GetChangeDetail(change.gerrit_number)
  if not details:
    logging.warning('Change details was None for %s', str(change))
    return False

  label = _LabelIfShouldExonerate(details, change.patch_number)
  if not label:
    logging.info(
        "Change %s was not ready to exonerate %d", str(change), build_id)
    return False

  try:
    helper.SetReview(
        change.gerrit_number,
        msg=_EXONERATOR_PRECQ_MESSAGE,
        labels={label: 1})
    logging.info('Exonerated %s with %s', str(change), label)
    return True
  # Network errors or permission errors won't get retried. That's ok for now.
  except Exception:
    logging.exception('Encountered an exception while marking %s with %s',
                      str(change), label)
    return False


def CanBeMarkedReady(change):
  """Whether a change is ready to be exonerated.

  Args:
    change: A GerritPatchTuple to test.
  """
  helper = gerrit_cq.GetHelper(internal=change.internal)
  details = helper.GetChangeDetail(change.gerrit_number)
  if details:
    return bool(_LabelIfShouldExonerate(details, change.patch_number))
  else:
    logging.warning('Change details was None for %s', str(change))
    return False


def _LabelIfShouldExonerate(change_details, known_patch_number):
  """Returns the label to exonerate if the CL should can be exonerated.

  We only want to send CLs back into the pre-cq if they haven't already been
  marked Trybot-Ready+1, CQ+1, and it's not already on a newer patchset.

  Args:
    change_details: The change details response from Gerrit.
    known_patch_number: The revision number which we want to forgive.
  """
  if _CannotExonerate(change_details, known_patch_number):
    return None

  return _LabelToReapply(change_details)


def _CannotExonerate(change_details, known_patch_number):
  """Check various condition to make sure we can exonerate the change.

  This does NOT check whether Pre-CQ approval was removed by a bot. We do
  that check when finding the label to re-apply.

  Args:
    change_details: The change details response from Gerrit.
    known_patch_number: The revision number which we want to forgive.
  """
  return not (
      gerrit_cq.SanityCheckChange(change_details, known_patch_number)
      # Must not have Verified-1
      and not any(
          label < 0
          for label in gerrit_cq.LabelValues(change_details, _VERIFIED_LABEL))
      # It shouldn't already have Trybot-Ready+1, CQ+1 or CQ-1
      and not (gerrit_cq.LabelValues(
          change_details, gerrit_cq.COMMIT_QUEUE_LABEL) - {0})
      and not (gerrit_cq.LabelValues(
          change_details, _TRYBOT_READY_LABEL) - {0})
      # Don't exonerate CLs with Code-Review-1 or Code-Review-2
      and all(label >= 0
              for label in gerrit_cq.LabelValues(
                  change_details, gerrit_cq.CODE_REVIEW_LABEL))
  )


def _LabelToReapply(change_details):
  """Returns the label removed, if the Pre-CQ approval was removed by a bot.

  Either Trybot-Ready+1 or Commit-Queue+1 labels can kick off pre-cq. To
  exonerate a change, we want to re-apply the labels which gave Pre-CQ approval,
  but only if they weren't removed by a human. If a human removes approval, it's
  probably because the change is unsafe or at fault in some way.

  Args:
    change_details: The response from gerrit with the change's details.
  """
  # Find the latest pre-cq failure message, then walk forward through the
  # messages to find the next bot laebl removal, if it exists.
  messages = change_details['messages']
  failure_index = _FindLatestPreCQKickoff(messages)
  if failure_index is None:
    return None
  labels_removed_by_bot = _FindLabelsToReapply(messages[failure_index+1:])

  # Commit-Queue is a superset of Trybot-Ready, so just forgive by applying it.
  if _COMMIT_QUEUE_LABEL in labels_removed_by_bot:
    return _COMMIT_QUEUE_LABEL
  elif _TRYBOT_READY_LABEL in labels_removed_by_bot:
    return _TRYBOT_READY_LABEL


def _FindLatestPreCQKickoff(messages):
  """Finds the latest build kickoff message index.

  Args:
    messages: The gerrit comments.

  Returns:
    The index of the message
  """
  def _IsBuildKickoffMessage(message):
    return (
        message['real_author']['email'] == constants.CHROMEOS_COMMIT_BOT_EMAIL
        and _MESSAGE_FOR_PRECQ_PICKED_UP in message['message']
    )
  for i, message in reversed(list(enumerate(messages))):
    if _IsBuildKickoffMessage(message):
      return i


def _FindLabelsToReapply(messages):
  """Finds the gerrit labels to reapply (probably the label removed by the bot)

  Args:
    messages: The gerrit comments after kickoff

  Returns:
    A set of labels which were removed by the chromeos commit bot.
  """
  labels_removed_by_bot = set()
  for message in messages:
    if (message['real_author']['email']
        == constants.CHROMEOS_COMMIT_BOT_EMAIL):
      for label in (_TRYBOT_READY_LABEL, _COMMIT_QUEUE_LABEL):
        if '-' + label in message['message']:
          labels_removed_by_bot.add(label)

  if labels_removed_by_bot:
    return labels_removed_by_bot

  # Special case - Commit-Queue+2 isn't removed by the bot. If the trybot was
  # kicked off by CR+2, we want to reapply Trybot-Ready+1.
  # We assume that if neither the bot nor a human removed any labels, then it
  # was kicked off by CR+2
  any_labels_removed = False
  for message in messages:
    for label in (_TRYBOT_READY_LABEL, _COMMIT_QUEUE_LABEL):
      if '-' + label in message['message']:
        any_labels_removed = True
  if not any_labels_removed:
    return [_TRYBOT_READY_LABEL]

  return []
