# -*- coding: utf-8 -*-
# Copyright 2016 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.

"""Module that generates and sends CL validation messages."""

from __future__ import print_function

from chromite.lib import constants
from chromite.lib import cros_logging as logging
from chromite.lib import gob_util
from chromite.lib import patch as cros_patch


def CreateValidationFailureMessage(pre_cq_trybot,
                                   change,
                                   suspects,
                                   messages,
                                   sanity=True,
                                   infra_fail=False,
                                   lab_fail=False,
                                   no_stat=None,
                                   retry=False):
  """Create a message explaining why a validation failure occurred.

  Args:
    pre_cq_trybot: Whether the builder is a Pre-CQ trybot. (Note: The Pre-CQ
      launcher is NOT considered a Pre-CQ trybot.)
    change: The change we want to create a message for.
    suspects: An instance of triage_lib.SuspectChanges.
    messages: A list of build failure messages from supporting builders.
      These must be BuildFailureMessage objects or NoneType objects.
    sanity: A boolean indicating whether the build was considered sane. If
      not sane, none of the changes will have their CommitReady bit modified.
    infra_fail: The build failed purely due to infrastructure failures.
    lab_fail: The build failed purely due to test lab infrastructure failures.
    no_stat: A list of builders which failed prematurely without reporting
      status.
    retry: Whether we should retry automatically.

  Returns:
    A string that communicates what happened.
  """
  msg = []
  if no_stat:
    msg.append('The following build(s) did not start or failed prematurely:')
    msg.append(', '.join(no_stat))

  if messages:
    # Build a list of error messages. We don't want to build a ridiculously
    # long comment, as Gerrit will reject it. See https://crbug.com/236831
    max_error_len = 20000 / max(1, len(messages))
    msg.append('The following build(s) failed:')
    for message in [str(x) for x in messages]:
      if len(message) > max_error_len:
        message = message[:max_error_len] + '... (truncated)'
      msg.append(message)

  # Create a list of changes other than this one that might be guilty.
  # Limit the number of suspects to 20 so that the list of suspects isn't
  # ridiculously long.
  max_suspects = 20
  other_suspects = set(suspects.keys()) - set([change])
  if len(other_suspects) < max_suspects:
    other_suspects_str = cros_patch.GetChangesAsString(other_suspects)
  else:
    other_suspects_str = ('%d other changes. See the blamelist for more '
                          'details.' % (len(other_suspects),))

  if not sanity:
    msg.append('The build was consider not sane because the sanity check '
               'builder(s) failed. Your change will not be blamed for the '
               'failure.')
    assert retry
  elif lab_fail:
    msg.append('The build encountered Chrome OS Lab infrastructure issues. '
               ' Your change will not be blamed for the failure.')
    assert retry
  else:
    if infra_fail:
      msg.append('The build failure may have been caused by infrastructure '
                 'issues and/or bad %s changes.' % constants.INFRA_PROJECTS)

    if change in suspects.keys():
      if other_suspects_str:
        msg.append('Your change may have caused this failure. There are '
                   'also other changes that may be at fault: %s'
                   % other_suspects_str)
      else:
        msg.append('This failure was probably caused by your change.')

        msg.append('Please check whether the failure is your fault. If your '
                   'change is not at fault, you may mark it as ready again.')
    else:
      if len(suspects) == 1:
        msg.append('This failure was probably caused by %s'
                   % other_suspects_str)
      elif len(suspects) > 0:
        msg.append('One of the following changes is probably at fault: %s'
                   % other_suspects_str)

      assert retry

  if retry:
    bot = 'The Pre-Commit Queue' if pre_cq_trybot else 'The Commit Queue'
    msg.insert(0, 'NOTE: %s will retry your change automatically.' % bot)

  return '\n\n'.join(msg)


class PaladinMessage(object):
  """Object used to send messages to developers about their changes."""

  # URL where Paladin documentation is stored.
  _PALADIN_DOCUMENTATION_URL = ('https://dev.chromium.org/developers/'
                                'tree-sheriffs/sheriff-details-chromium-os/'
                                'commit-queue-overview')

  # Gerrit can't handle commands over 32768 bytes. See https://crbug.com/236831
  MAX_MESSAGE_LEN = 32000

  def __init__(self, message, patch, helper):
    if len(message) > self.MAX_MESSAGE_LEN:
      message = message[:self.MAX_MESSAGE_LEN] + '... (truncated)'
    self.message = message
    self.patch = patch
    self.helper = helper

  def _ConstructPaladinMessage(self):
    """Adds any standard Paladin messaging to an existing message."""
    return self.message + ('\n\nCommit queue documentation: %s' %
                           self._PALADIN_DOCUMENTATION_URL)

  def Send(self, dryrun):
    """Posts a comment to a gerrit review."""
    body = {
        'message': self._ConstructPaladinMessage(),
        'notify': 'OWNER',
    }
    path = 'changes/%s/revisions/%s/review' % (
        self.patch.gerrit_number, self.patch.revision)
    if dryrun:
      logging.info('Would have sent %r to %s', body, path)
      return
    gob_util.FetchUrl(self.helper.host, path, reqtype='POST', body=body)
