# -*- 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)
