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

"""Utility functions for interacting with a CL's action history."""

from __future__ import print_function

import collections
import datetime
import operator

from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import iter_utils


# Bidirectional mapping between pre-cq status strings and CL action strings.
_PRECQ_STATUS_TO_ACTION = {
    constants.CL_STATUS_INFLIGHT: constants.CL_ACTION_PRE_CQ_INFLIGHT,
    constants.CL_STATUS_FULLY_VERIFIED:
        constants.CL_ACTION_PRE_CQ_FULLY_VERIFIED,
    constants.CL_STATUS_PASSED: constants.CL_ACTION_PRE_CQ_PASSED,
    constants.CL_STATUS_FAILED: constants.CL_ACTION_PRE_CQ_FAILED,
    constants.CL_STATUS_LAUNCHING: constants.CL_ACTION_PRE_CQ_LAUNCHING,
    constants.CL_STATUS_WAITING: constants.CL_ACTION_PRE_CQ_WAITING,
    constants.CL_STATUS_READY_TO_SUBMIT:
        constants.CL_ACTION_PRE_CQ_READY_TO_SUBMIT
}

_PRECQ_ACTION_TO_STATUS = dict(
    (v, k) for k, v in _PRECQ_STATUS_TO_ACTION.items())

PRE_CQ_CL_STATUSES = set(_PRECQ_STATUS_TO_ACTION.keys())

assert len(_PRECQ_STATUS_TO_ACTION) == len(_PRECQ_ACTION_TO_STATUS), \
    '_PRECQ_STATUS_TO_ACTION values are not unique.'

CL_ACTION_COLUMNS = ['id', 'build_id', 'action', 'reason',
                     'build_config', 'change_number', 'patch_number',
                     'change_source', 'timestamp', 'buildbucket_id', 'status']

_CLActionTuple = collections.namedtuple('_CLActionTuple', CL_ACTION_COLUMNS)

_GerritChangeTuple = collections.namedtuple('_GerritChangeTuple',
                                            ['gerrit_number', 'internal'])

# Presents the Pre-CQ progress of a change:
# status is the current Pre-CQ status of the change, must be one of
# constants.CL_PRECQ_CONFIG_STATUSES;
# timestamp is datetime.datetime of when this status was most recently achieved;
# build_id is the id of the build which most recently updated this status;
# buildbucket_id is the buildbucket_id of the build tirggered by the most
# recently updated build.
PreCQProgressTuple = collections.namedtuple(
    'PreCQProgressTuple', ['status', 'timestamp', 'build_id', 'buildbucket_id'])


_EXTERNAL_GERRIT_HOSTS = (
    constants.EXTERNAL_GERRIT_HOST,
    # Allow us to recognize old commits from previous code review host.
    'gerrit.chromium.org',
)


_INTERNAL_GERRIT_HOSTS = (
    constants.INTERNAL_GERRIT_HOST,
    # Allow us to recognize old commits from previous code review host.
    'gerrit-int.chromium.org',
)


class UnknownGerritHostError(ValueError):

  """Raised when attempting to construct GerritChangeTuple with unknown host."""
  def __init__(self, gerrit_host):
    super(UnknownGerritHostError, self).__init__(
        'Gerrit host %s is not a known host.')
    self.gerrit_host = gerrit_host


class GerritChangeTuple(_GerritChangeTuple):
  """A tuple for a given Gerrit change."""

  def __str__(self):
    site_params = config_lib.GetSiteParams()
    prefix = (site_params.INTERNAL_CHANGE_PREFIX
              if self.internal else site_params.EXTERNAL_CHANGE_PREFIX)
    return '%s%s' % (prefix, self.gerrit_number)

  @classmethod
  def FromHostAndNumber(cls, gerrit_host, gerrit_number):
    if gerrit_host in _EXTERNAL_GERRIT_HOSTS:
      internal = False
    elif gerrit_host in _INTERNAL_GERRIT_HOSTS:
      internal = True
    else:
      raise UnknownGerritHostError(gerrit_host)

    return cls(int(gerrit_number), internal)


_GerritPatchTuple = collections.namedtuple('_GerritPatchTuple',
                                           ['gerrit_number', 'patch_number',
                                            'internal'])

class GerritPatchTuple(_GerritPatchTuple):
  """A tuple for a given Gerrit patch."""

  def __str__(self):
    site_params = config_lib.GetSiteParams()
    prefix = (site_params.INTERNAL_CHANGE_PREFIX
              if self.internal else site_params.EXTERNAL_CHANGE_PREFIX)
    return '%s%s#%s' % (prefix, self.gerrit_number, self.patch_number)

  def GetChangeTuple(self):
    return GerritChangeTuple(self.gerrit_number, self.internal)


class CLAction(_CLActionTuple):
  """An action or history log entry for a particular CL."""

  @classmethod
  def FromGerritPatchAndAction(cls, change, action, reason=None,
                               timestamp=None, buildbucket_id=None,
                               status=None):
    """Creates a CLAction instance from a change and action.

    Args:
      change: A GerritPatch instance.
      action: An action string.
      reason: Optional reason string.
      timestamp: Optional datetime.datetime timestamp.
      buildbucket_id: Optional buildbucket_id
      status: Optional string status
    """
    return CLAction(None, None, action, reason, None,
                    int(change.gerrit_number), int(change.patch_number),
                    BoolToChangeSource(change.internal), timestamp,
                    buildbucket_id, status)

  @classmethod
  def FromMetadataEntry(cls, entry):
    """Creates a CLAction instance from a metadata.json-style action tuple.

    Args:
      entry: An action tuple as retrieved from metadata.json (previously known
             as a CLActionTuple).
      build_metadata: The full build metadata.json entry.
    """
    change_dict = entry[0]
    return CLAction(None, None, entry[1], entry[3], None,
                    int(change_dict['gerrit_number']),
                    int(change_dict['patch_number']),
                    BoolToChangeSource(change_dict['internal']),
                    entry[2], None, None)

  def AsMetadataEntry(self):
    """Get a tuple representation, suitable for metadata.json."""
    return (self.patch._asdict(), self.action, self.timestamp, self.reason)

  @property
  def patch(self):
    """The GerritPatch this action affects."""
    return GerritPatchTuple(
        gerrit_number=self.change_number,
        patch_number=self.patch_number,
        internal=self.change_source == constants.CHANGE_SOURCE_INTERNAL
    )

  @property
  def bot_type(self):
    """The type of bot that took this action.

    Returns:
      constants.CQ or constants.PRE_CQ depending on who took the action.
    """
    build_config = self.build_config
    if build_config.endswith('-%s' % config_lib.CONFIG_TYPE_PALADIN):
      return constants.CQ
    else:
      return constants.PRE_CQ


def TranslatePreCQStatusToAction(status):
  """Translate a pre-cq |status| into a cl action.

  Returns:
    An action string suitable for use in cidb, for the given pre-cq status.

  Raises:
    KeyError if |status| is not a known pre-cq status.
  """
  return _PRECQ_STATUS_TO_ACTION[status]


def TranslatePreCQActionToStatus(action):
  """Translate a cl |action| into a pre-cq status.

  Returns:
    A pre-cq status string corresponding to the given |action|.

  Raises:
    KeyError if |action| is not a known pre-cq status-transition-action.
  """
  return _PRECQ_ACTION_TO_STATUS[action]


def BoolToChangeSource(internal):
  """Translate a change.internal bool into a change_source string.

  Returns:
    'internal' if internal, else 'external'.
  """
  return (constants.CHANGE_SOURCE_INTERNAL if internal
          else constants.CHANGE_SOURCE_EXTERNAL)


def GetCLPreCQStatusAndTime(change, action_history):
  """Get the pre-cq status and timestamp for |change| from |action_history|.

  Args:
    change: GerritPatch instance to get the pre-CQ status for.
    action_history: A list of CLAction instances, which may include actions
                    for other changes.

  Returns:
    A (status, timestamp) tuple where |status| is a valid pre-cq status
    string and |timestamp| is a datetime object for when the status was
    set. Or (None, None) if there is no pre-cq status.
  """
  actions_for_patch = ActionsForPatch(change, action_history)
  actions_for_patch = [
      a for a in actions_for_patch if a.action in _PRECQ_ACTION_TO_STATUS or
      a.action == constants.CL_ACTION_PRE_CQ_RESET]

  if (not actions_for_patch or
      actions_for_patch[-1].action == constants.CL_ACTION_PRE_CQ_RESET):
    return None, None

  return (TranslatePreCQActionToStatus(actions_for_patch[-1].action),
          actions_for_patch[-1].timestamp)


def GetCLPreCQStatus(change, action_history):
  """Get the pre-cq status for |change| based on |action_history|.

  Args:
    change: GerritPatch instance to get the pre-CQ status for.
    action_history: A list of CLAction instances. This may include
                    actions for changes other than |change|.

  Returns:
    The status, as a string, or None if there is no recorded pre-cq status.
  """
  return GetCLPreCQStatusAndTime(change, action_history)[0]


def IsChangeScreened(change, action_history):
  """Get's whether |change| has been pre-cq screened.

  Args:
    change: GerritPatch instance to get the pre-CQ status for.
    action_history: A list of CLAction instances.

  Returns:
    True if the change has been pre-cq screened, false otherwise.
  """
  actions_for_patch = ActionsForPatch(change, action_history)
  actions_for_patch = FilterPreResetActions(actions_for_patch)
  return any(a.action == constants.CL_ACTION_SCREENED_FOR_PRE_CQ
             for a in actions_for_patch)


def ActionsForPatch(change, action_history):
  """Filters a CL action list to only those for a given patch.

  Args:
    change: GerritPatch instance to filter for.
    action_history: List of CLAction objects.
  """
  patch_number = int(change.patch_number)
  change_number = int(change.gerrit_number)
  change_source = BoolToChangeSource(change.internal)

  actions_for_patch = [a for a in action_history
                       if (a.change_source == change_source and
                           a.change_number == change_number and
                           a.patch_number == patch_number)]

  return actions_for_patch


def ActionsForOldPatches(change, action_history):
  """Get CL actions for old patches.

  Args:
    change: GerritPatch instance.
    action_history: List of CLActions.

  Returns:
    List of CLActions of 'change' with smaller patch_number.
  """
  patch_number = int(change.patch_number)
  change_number = int(change.gerrit_number)
  change_source = BoolToChangeSource(change.internal)

  actions_for_old_patches = [a for a in action_history
                             if (a.change_source == change_source and
                                 a.change_number == change_number and
                                 a.patch_number < patch_number)]
  return actions_for_old_patches


def GetOldPreCQBuildActions(change, action_history,
                            min_timestamp=datetime.datetime.min):
  """Get old pre-cq build actions.

  Args:
    change: GerritPatch instance.
    action_history: List of CLActions.
    min_timestamp: Minimum timestamp requirement for the cl actions.

  Returns:
    CL actions for pre-cq runs which were launched after min_timestamp
    and not cancelled.
  """
  if not isinstance(min_timestamp, datetime.datetime):
    raise ValueError(" %s type %s isn't an instance of datetime.datetime."
                     % (min_timestamp, type(min_timestamp)))

  actions_for_old_patches = ActionsForOldPatches(change, action_history)
  cancelled_builds = GetCancelledPreCQBuilds(action_history)
  cancelled_buildbucket_ids = set([x.buildbucket_id for x in cancelled_builds])

  old_pre_cq_build_actions = [
      a for a in actions_for_old_patches
      if (a.action == constants.CL_ACTION_TRYBOT_LAUNCHING and
          a.buildbucket_id is not None and
          a.buildbucket_id not in cancelled_buildbucket_ids and
          a.timestamp is not None and
          a.timestamp > min_timestamp)]

  return old_pre_cq_build_actions

def GetCancelledPreCQBuilds(action_history):
  """Get cancelled pre-cq builds.

  Args:
    action_history: List of clactions.CLAction instances.

  Returns:
    A set of clactions.CLAction instances with action
    constants.CL_ACTION_TRYBOT_CANCELLED.
  """
  return set([a for a in action_history
              if a.buildbucket_id is not None and
              a.action == constants.CL_ACTION_TRYBOT_CANCELLED])

def GetRequeuedOrSpeculative(change, action_history, is_speculative):
  """For a |change| get either a requeued or speculative action if necessary.

  This method returns an action string for an action that should be recorded
  on |change|, or None if no action needs to be recorded.

  Args:
    change: GerritPatch instance to operate upon.
    action_history: List of CL actions (may include actions on changes other
                    than |change|).
    is_speculative: Boolean indicating if |change| is speculative, i.e. it does
                    not have CQ approval.

  Returns:
    CL_ACTION_REQUEUED, CL_ACTION_SPECULATIVE, or None.
  """
  actions_for_patch = ActionsForPatch(change, action_history)

  if is_speculative:
    # Speculative changes should have 1 CL_ACTION_SPECULATIVE action that is
    # newer than the newest REQUEUED or KICKED_OUT action, and at least 1
    # action if there is no REQUEUED or KICKED_OUT action.
    for a in reversed(actions_for_patch):
      if a.action == constants.CL_ACTION_SPECULATIVE:
        return None
      elif (a.action == constants.CL_ACTION_REQUEUED or
            a.action == constants.CL_ACTION_KICKED_OUT):
        return constants.CL_ACTION_SPECULATIVE
    return constants.CL_ACTION_SPECULATIVE
  else:
    # Non speculative changes should have 1 CL_ACTION_REQUEUED action that is
    # newer than the newest SPECULATIVE or KICKED_OUT action, but no action if
    # there are no SPECULATIVE or REQUEUED actions.
    for a in reversed(actions_for_patch):
      if (a.action == constants.CL_ACTION_KICKED_OUT or
          a.action == constants.CL_ACTION_SPECULATIVE):
        return constants.CL_ACTION_REQUEUED
      if a.action == constants.CL_ACTION_REQUEUED:
        return None

  return None


def GetCLActionCount(change, configs, action, action_history,
                     latest_patchset_only=True):
  """Return how many times |action| has occured on |change|.

  Args:
    change: GerritPatch instance to operate upon.
    configs: List or set of config names to consider.
    action: The action string to look for.
    action_history: List of CLAction instances to count through.
    latest_patchset_only: If True, only count actions that occured to the
      latest patch number. Note, this may be different than the patch
      number specified in |change|. Default: True.

  Returns:
    The count of how many times |action| occured on |change| by the given
    |config|.
  """
  change_number = int(change.gerrit_number)
  change_source = BoolToChangeSource(change.internal)
  actions_for_change = [a for a in action_history
                        if (a.change_source == change_source and
                            a.change_number == change_number)]

  if actions_for_change and latest_patchset_only:
    latest_patch_number = max(a.patch_number for a in actions_for_change)
    actions_for_change = [a for a in actions_for_change
                          if a.patch_number == latest_patch_number]

  actions_for_change = [a for a in actions_for_change
                        if (a.build_config in configs and
                            a.action == action)]

  return len(actions_for_change)


def FilterPreResetActions(action_history):
  """Filters out actions prior to most recent pre-cq reset action.

  Args:
    action_history: List of CLAction instance.

  Returns:
    List of CLAction instances that occur after the last pre-cq-reset action.
  """
  reset = False
  for i, a in enumerate(action_history):
    if a.action == constants.CL_ACTION_PRE_CQ_RESET:
      reset = True
      reset_index = i
  if reset:
    action_history = action_history[(reset_index+1):]
  return action_history


def GetCLPreCQProgress(change, action_history):
  """Gets a CL's per-config PreCQ statuses.

  Args:
    change: GerritPatch instance to get statuses for.
    action_history: List of CLAction instances.

  Returns:
    A dict mapping per Pre-CQ config name (string) to its Pre-CQ progress (in
      the format of PreCQProgressTuple).
  """
  actions_for_patch = ActionsForPatch(change, action_history)
  config_status_dict = {}

  # If there is a reset action recorded, filter out all actions prior to it.
  actions_for_patch = FilterPreResetActions(actions_for_patch)

  # Only configs for which the pre-cq-launcher has requested verification
  # should be included in the per-config status.
  for a in actions_for_patch:
    if a.action == constants.CL_ACTION_VALIDATION_PENDING_PRE_CQ:
      assert a.reason, 'Validation was requested without a specified config.'
      config_status_dict[a.reason] = PreCQProgressTuple(
          constants.CL_PRECQ_CONFIG_STATUS_PENDING, a.timestamp, a.build_id,
          a.buildbucket_id)

  # Loop through actions_for_patch several times, in order of status priority.
  # Each action maps to a status:
  #   CL_ACTION_TRYBOT_LAUNCHING -> CL_PRECQ_CONFIG_STATUS_LAUNCHED
  #   CL_ACTION_PICKED_UP -> CL_PRECQ_CONFIG_STATUS_INFLIGHT
  #   CL_ACTION_KICKED_OUT -> CL_PRECQ_CONFIG_STATUS_FAILED
  #   CL_ACTION_FORGIVEN -> CL_PRECQ_CONFIG_STATUS_PENDING
  # All have the same priority.
  for a in actions_for_patch:
    if (a.action == constants.CL_ACTION_TRYBOT_LAUNCHING and
        a.reason in config_status_dict):
      config_status_dict[a.reason] = PreCQProgressTuple(
          constants.CL_PRECQ_CONFIG_STATUS_LAUNCHED, a.timestamp, a.build_id,
          a.buildbucket_id)
    elif (a.action == constants.CL_ACTION_PICKED_UP and
          a.build_config in config_status_dict):
      config_status_dict[a.build_config] = PreCQProgressTuple(
          constants.CL_PRECQ_CONFIG_STATUS_INFLIGHT, a.timestamp, a.build_id,
          a.buildbucket_id)
    elif (a.action == constants.CL_ACTION_KICKED_OUT and
          (a.build_config in config_status_dict or
           a.reason in config_status_dict)):
      config = (a.build_config if a.build_config in config_status_dict else
                a.reason)
      config_status_dict[config] = PreCQProgressTuple(
          constants.CL_PRECQ_CONFIG_STATUS_FAILED, a.timestamp, a.build_id,
          a.buildbucket_id)
    elif (a.action == constants.CL_ACTION_FORGIVEN and
          (a.build_config in config_status_dict or
           a.reason in config_status_dict)):
      config = (a.build_config if a.build_config in config_status_dict else
                a.reason)
      config_status_dict[config] = PreCQProgressTuple(
          constants.CL_PRECQ_CONFIG_STATUS_PENDING, a.timestamp, a.build_id,
          a.buildbucket_id)

  for a in actions_for_patch:
    if (a.action == constants.CL_ACTION_VERIFIED and
        a.build_config in config_status_dict):
      config_status_dict[a.build_config] = PreCQProgressTuple(
          constants.CL_PRECQ_CONFIG_STATUS_VERIFIED, a.timestamp, a.build_id,
          a.buildbucket_id)

  return config_status_dict


def GetPreCQProgressMap(changes, action_history):
  """Gets the per-config pre-cq status for all changes.

  Args:
    changes: Set of GerritPatch changes to consider.
    action_history: List of CLAction instances.

  Returns:
    A dict of the form {change: config_status_dict} where config_status_dict
    is as returned by GetCLPreCQProgress. Any change that has not yet been
    screened will be absent from the returned dict.
  """
  progress_map = {}
  for change in changes:
    config_status_dict = GetCLPreCQProgress(change, action_history)
    if config_status_dict:
      progress_map[change] = config_status_dict

  return progress_map


def GetPreCQCategories(progress_map):
  """Gets the set of busy and verified CLs in the pre-cq.

  Args:
    progress_map: See return type of GetPreCQProgressMap.

  Returns:
    A (busy, inflight, verified) tuple where each item is a set of changes.
    A change is verified if all its pending configs have verified it. A change
    is busy if it is not verified, but all pending configs are either launched
    or inflight or verified. A change is inflight if all configs are at least
    at or past the inflight state, and at least one config is still inflight.
  """
  busy, inflight, verified = set(), set(), set()
  busy_states = (constants.CL_PRECQ_CONFIG_STATUS_LAUNCHED,
                 constants.CL_PRECQ_CONFIG_STATUS_INFLIGHT,
                 constants.CL_PRECQ_CONFIG_STATUS_VERIFIED)
  beyond_inflight_states = (constants.CL_PRECQ_CONFIG_STATUS_INFLIGHT,
                            constants.CL_PRECQ_CONFIG_STATUS_VERIFIED,
                            constants.CL_PRECQ_CONFIG_STATUS_FAILED)

  for change, config_status_dict in progress_map.iteritems():
    statuses = [x.status for x in config_status_dict.values()]
    if all(x == constants.CL_PRECQ_CONFIG_STATUS_VERIFIED for x in statuses):
      verified.add(change)
    elif all(x in busy_states for x in statuses):
      busy.add(change)

    if (all(x in beyond_inflight_states for x in statuses) and
        any(x == constants.CL_PRECQ_CONFIG_STATUS_INFLIGHT for x in statuses)):
      inflight.add(change)

  return busy, inflight, verified


def GetPreCQConfigsToTest(changes, progress_map):
  """Gets the set of configs to be tested for any change in |changes|.

  Note: All |changes| must already be screened, i.e. must appear in
  progress_map.

  Args:
    changes: A list or set of changes (GerritPatch).
    progress_map: See return type of GetPreCQProgressMap.

  Returns:
    A set of configs that must be launched in order to make each change in
    |changes| be considered 'busy' by the pre-cq.

  Raises:
    KeyError if any change in |changes| is not yet screened, and hence
    does not appear in progress_map.
  """
  configs_to_test = set()
  # Failed is considered a to-test state so that if a CL fails a given config
  # and gets rejected, it will be re-tested by that config when it is re-queued.
  to_test_states = (constants.CL_PRECQ_CONFIG_STATUS_PENDING,
                    constants.CL_PRECQ_CONFIG_STATUS_FAILED)
  for change in changes:
    for config, pre_cq_progress_tuple in progress_map[change].iteritems():
      if pre_cq_progress_tuple.status in to_test_states:
        configs_to_test.add(config)
  return configs_to_test


def GetRelevantChangesForBuilds(changes, action_history, build_ids):
  """Get relevant changes for |build_ids| by examing CL actions.

  Args:
    changes: A list of GerritPatch instances to examine.
    action_history: A list of CLAction instances.
    build_ids: A list of build id to examine.

  Returns:
    A dictionary mapping a build id to a set of changes.
  """
  changes_map = dict()
  relevant_actions = [x for x in action_history if x.build_id in build_ids]
  for change in changes:
    actions = ActionsForPatch(change, relevant_actions)
    pickups = set([x.build_id for x in actions if
                   x.action == constants.CL_ACTION_PICKED_UP])
    discards = set([x.build_id for x in actions if
                    x.action == constants.CL_ACTION_IRRELEVANT_TO_SLAVE])
    relevant_build_ids = pickups - discards
    for build_id in relevant_build_ids:
      changes_map.setdefault(build_id, set()).add(change)

  return changes_map


# ##############################################################################
# Aggregate history over a list of CLActions

def _MeasureTimestampIntervals(intervals):
  """Gets the length of a set of invervals.

  Args:
    intervals: A list of (start, stop) timestamp tuples.

  Returns:
    The total length of the given intervals, in seconds.
  """
  lengths = [e - s for s, e in intervals]
  return sum(lengths, datetime.timedelta(0)).total_seconds()


def _GetIntervals(change, action_history, start_actions, stop_actions,
                  start_at_beginning=False):
  """Get intervals corresponding to given start and stop actions.

  Args:
    change: GerritPatch instance of a submitted change.
    action_history: list of CL actions.
    start_actions: list of action types to be considered as start actions for
                   intervals.
    stop_actions: list of action types to be considered as stop actions for
                  intervals.
    start_at_beginning: optional boolean, default False. If true, consider the
                        first action to be a start action.
  """
  actions_for_patch = ActionsForPatch(change, action_history)
  if not actions_for_patch:
    return []

  intervals = []
  in_interval = start_at_beginning
  if in_interval:
    start_time = actions_for_patch[0].timestamp
  for a in actions_for_patch:
    if in_interval and a.action in stop_actions:
      if start_time < a.timestamp:
        intervals.append((start_time, a.timestamp))
      in_interval = False
    elif not in_interval and a.action in start_actions:
      start_time = a.timestamp
      in_interval = True

  if in_interval and start_time < actions_for_patch[-1].timestamp:
    intervals.append((start_time, actions_for_patch[-1].timestamp))

  return intervals


def _GetReadyIntervals(change, action_history):
  """Gets the time intervals in which |change| was fully ready.

  Args:
    change: GerritPatch instance of a submitted change.
    action_history: list of CL actions.
  """
  start = (constants.CL_ACTION_REQUEUED,)
  stop = (constants.CL_ACTION_SPECULATIVE, constants.CL_ACTION_KICKED_OUT)
  return _GetIntervals(change, action_history, start, stop, True)


def GetCLHandlingTime(change, action_history):
  """Returns the handling time of |change|, in seconds.

  This method computes a CL's handling time, not including the time spent
  waiting for a developer to mark or re-mark their change as ready.

  Args:
    change: GerritPatch instance of a submitted change.
    action_history: List of CL actions.
  """
  ready_intervals = _GetReadyIntervals(change, action_history)
  return _MeasureTimestampIntervals(ready_intervals)


def GetCLWallClockTime(change, action_history):
  """Returns the total end-to-end time of the |change|, in seconds.

  This method includes the full time from when the patch was first marked as
  CQ-ready (and CR+2, V+1) until the time it was submitted.

  Args:
    change: GerritPatch instance of a submitted change.
    action_history: List of CL actions.
  """
  start = (constants.CL_ACTION_REQUEUED,)
  stop = (constants.CL_ACTION_SUBMITTED,)
  intervals = _GetIntervals(change, action_history, start, stop, True)
  return _MeasureTimestampIntervals(intervals)


def GetPreCQTime(change, action_history):
  """Returns the time spent waiting for the pre-cq to finish."""
  ready_intervals = _GetReadyIntervals(change, action_history)
  start = (constants.CL_ACTION_SCREENED_FOR_PRE_CQ,)
  stop = (constants.CL_ACTION_PRE_CQ_FULLY_VERIFIED,)
  precq_intervals = _GetIntervals(change, action_history, start, stop)
  return _MeasureTimestampIntervals(
      iter_utils.IntersectIntervals([ready_intervals, precq_intervals]))


def GetCQWaitTime(change, action_history):
  """Returns the time spent waiting for a CL to be picked up by the CQ."""
  ready_intervals = _GetReadyIntervals(change, action_history)
  precq_passed_interval = _GetIntervals(
      change, action_history, (constants.CL_ACTION_PRE_CQ_PASSED,), ())
  relevant_configs = (constants.PRE_CQ_LAUNCHER_CONFIG, constants.CQ_MASTER)
  relevant_config_actions = [a for a in action_history
                             if a.build_config in relevant_configs]
  start = (constants.CL_ACTION_REQUEUED, constants.CL_ACTION_FORGIVEN)
  stop = (constants.CL_ACTION_PICKED_UP,)
  waiting_intervals = _GetIntervals(change, relevant_config_actions, start,
                                    stop, True)
  return _MeasureTimestampIntervals(
      iter_utils.IntersectIntervals(
          [ready_intervals, waiting_intervals, precq_passed_interval]))


def GetCQRunTime(change, action_history):
  """Returns the time spent testing a CL in the CQ."""
  ready_intervals = _GetReadyIntervals(change, action_history)
  relevant_configs = (constants.CQ_MASTER,)
  relevant_config_actions = [a for a in action_history
                             if a.build_config in relevant_configs]
  start = (constants.CL_ACTION_PICKED_UP,)
  stop = (constants.CL_ACTION_FORGIVEN, constants.CL_ACTION_KICKED_OUT,
          constants.CL_ACTION_SUBMITTED)
  testing_intervals = _GetIntervals(change, relevant_config_actions, start,
                                    stop)
  return _MeasureTimestampIntervals(
      iter_utils.IntersectIntervals([ready_intervals, testing_intervals]))


def GetCQAttemptsCount(change, action_history):
  """Gets the number of times a CL was picked up by CQ."""
  actions = ActionsForPatch(change, action_history)
  return sum(1 for a in actions
             if (a.build_config == constants.CQ_MASTER and
                 a.action == constants.CL_ACTION_PICKED_UP))


def _CLsForPatches(patches):
  """Get GerritChangeTuples corresponding to the give GerritPatchTuples."""
  return set(p.GetChangeTuple() for p in patches)


def AffectedCLs(action_history):
  """Get the CLs affected by a set of actions.

  Args:
    action_history: An iterable of CLActions.

  Returns:
    A set of GerritChangleTuple objects for the affected CLs.
  """
  return _CLsForPatches(AffectedPatches(action_history))


def AffectedPatches(action_history):
  """Get the patches affected by a set of actions.

  Args:
    action_history: An iterable of CLActions.

  Returns:
    A set of GerritPatchTuple objects for the affected patches.
  """
  return set(a.patch for a in action_history)


class CLActionHistory(object):
  """Class to derive aggregate information from CLAction histories."""

  def __init__(self, action_history):
    """Initialize the object.

    Args:
      action_history: An iterable of CLAction objects to aggregate information
          from.
    """
    # We preprocess this list to speed up various lookups. It shouldn't be
    # messed with in the lifetime of the object.
    self._action_history = tuple(sorted(action_history,
                                        key=operator.attrgetter('timestamp')))

    # Index the given action_history in various useful forms.
    self._per_patch_actions = {}
    self._per_cl_actions = {}
    self._per_patch_reject_actions = {}

    # Precompute some oft-used attributes.
    self.submit_actions = [a for a in self._action_history
                           if a.action == constants.CL_ACTION_SUBMITTED]
    self.reject_actions = [a for a in self._action_history
                           if a.action == constants.CL_ACTION_KICKED_OUT]
    self.submit_fail_actions = [a for a in self._action_history if
                                a.action == constants.CL_ACTION_SUBMIT_FAILED]
    self.exoneration_actions = [a for a in self._action_history if
                                a.action == constants.CL_ACTION_EXONERATED]
    self.affected_patches = AffectedPatches(self._action_history)
    self.affected_cls = _CLsForPatches(self.affected_patches)

    for action in self._action_history:
      patch = action.patch
      self._per_patch_actions.setdefault(patch, []).append(action)
      self._per_cl_actions.setdefault(patch.GetChangeTuple(), []).append(action)
    for action in self.reject_actions:
      patch = action.patch
      self._per_patch_reject_actions.setdefault(patch, []).append(action)

  def __iter__(self):
    """Support iterating over the entire history."""
    for a in self._action_history:
      yield a

  def __len__(self):
    """Return the length of the entire history."""
    return len(self._action_history)

  def GetSubmittedPatches(self, exclude_irrelevant_submissions=True):
    """Get a list of submitted patches from the action history.

    Args:
      exclude_irrelevant_submissions: Some CLs are submitted independent of our
          CQ infrastructure. When True, we exclude those CLs, as they shouldn't
          affect our statistics.

    Returns:
      set of submitted GerritPatchTuple objects.
    """
    relevant_actions = self.submit_actions
    if exclude_irrelevant_submissions:
      relevant_actions = [a for a in relevant_actions
                          if a.reason != constants.STRATEGY_NONMANIFEST]
    return AffectedPatches(relevant_actions)

  def GetSubmittedCLs(self, exclude_irrelevant_submissions=True):
    """Get a list of submitted patches from the action history.

    Args:
      exclude_irrelevant_submissions: Some CLs are submitted independent of our
          CQ infrastructure. When True, we exclude those CLs, as they shouldn't
          affect our statistics.

    Returns:
      set of submitted GerritPatchTuple objects.
    """
    return _CLsForPatches(
        self.GetSubmittedPatches(exclude_irrelevant_submissions))

  def SortBySubmitTimes(self, cls_or_patches):
    """Sort the given patches or cls in ascending order of submit time.

    Many functions in this class returns sets of cls/patches. This is convenient
    to dedup objects returned from various sources. While presenting this
    information to the user, it is often better to present them in a natural
    'order'.

    Args:
      cls_or_patches: Iterable of GerritPatchTuples or GerritChangeTuple objects
          to sort.

    Returns:
      list sorted in ascending order of submit time. Any patches/cls that were
      not submitted are appended to the end in a deterministic order.
    """
    affected_cls_or_patches = self.affected_cls | self.affected_patches
    unknown_changes = set(cls_or_patches) - affected_cls_or_patches
    assert not unknown_changes, 'Unknown changes: %s' % str(unknown_changes)

    per_change_final_submit_time = {}
    per_change_first_action_time = {}
    for change in cls_or_patches:
      actions = self.GetCLOrPatchActions(change)
      submit_actions = [x for x in actions
                        if x.action == constants.CL_ACTION_SUBMITTED]
      first_action = actions[0]

      if submit_actions:
        per_change_final_submit_time[change] = submit_actions[-1].timestamp
      else:
        per_change_first_action_time[change] = first_action.timestamp

    sorted_changes = sorted(per_change_final_submit_time.keys(),
                            key=per_change_final_submit_time.get)
    # We want to sort the inflight changes in some stable order. Let's sort them
    # by order of 'first action ever taken'
    sorted_changes += sorted(per_change_first_action_time.keys(),
                             key=lambda x: per_change_first_action_time[x])
    return sorted_changes

  # ############################################################################
  # Summarize handling times in different stages based on the action history.
  def GetPatchHandlingTimes(self):
    """Get handling times of all submitted patches.

    Returns:
      {submitted_patch: handling_time} where submitted_patch is a
      GerritPatchTuple for a submitted patch, and handling_time is the total
      handling time for that patch.
    """
    return {k: GetCLHandlingTime(k, self._per_patch_actions[k])
            for k in self.GetSubmittedPatches()}

  def GetPreCQHandlingTimes(self):
    """Get the time spent by all submitted patches in the pre-cq.

    Returns:
      {submitted_patch: precq_handling_time} where submitted_patch is a
      GerritPatchTuple for a submitted patch, and precq_handling_time is the
      handling time for that patch in the pre-cq.
    """
    return {k: GetPreCQTime(k, self._per_patch_actions[k])
            for k in self.GetSubmittedPatches()}

  def GetCQHandlingTimes(self):
    """Get the time spent by all submitted patches in the cq.

    Returns:
      {submitted_patch: cq_handling_time} where submitted_patch is a
      GerritPatchTuple for a submitted patch, and cq_handling_time is the
      handling time for that patch in the cq.
    """
    return {k: GetCQRunTime(k, self._per_patch_actions[k])
            for k in self.GetSubmittedPatches()}

  def GetCQWaitingTimes(self):
    """Get the time spent by all submitted patches waiting for the cq.

    Returns:
      {submitted_patch: cq_waiting_time} where submitted_patch is a
      GerritPatchTuple for a submitted patch, and cq_waiting_time is the
      time spent by that patch waiting for the cq.
    """
    return {k: GetCQWaitTime(k, self._per_patch_actions[k])
            for k in self.GetSubmittedPatches()}

  def GetExonerations(self):
    """Gets the exoneration actions by patch.

    Returns:
      A map from patch to a list of exoneration actions in ascending order of
      timestamps.
    """
    exonerations = {}
    for action in self.exoneration_actions:
      exonerations.setdefault(action.patch, []).append(action)
    return exonerations

  # ############################################################################
  # Classify CLs as good/bad based on the action history.
  def GetFalseRejections(self, bot_type=None):
    """Get the changes that were good, but were rejected at some point.

    We consider a patch to have been rejected falsely if it is later submitted
    because a build with no difference to the change later considered it good.

    Args:
      bot_type: (optional) constants.PRE_CQ or constants.CQ to restrict the
          actions considered.

    Returns:
      A map from rejected patch to a list of rejection actions of the relevant
      bot_type in ascending order of timestamps.
    """
    rejections = self._GetPatchRejectionsByBuilds(bot_type)
    submitted_patches = self.GetSubmittedPatches(
        exclude_irrelevant_submissions=False)
    candidates = set(rejections) & submitted_patches

    # Filter out candidates that were rejected because they were batched
    # together with truly bad patches in a pre_cq run.
    bad_precq_builds = set()
    precq_true_rejections = self.GetTrueRejections(constants.PRE_CQ)
    for patch in precq_true_rejections:
      for action in precq_true_rejections[patch]:
        bad_precq_builds.add(action.build_id)

    updated_candidates = {}
    for patch in candidates:
      updated_actions = [a for a in rejections[patch]
                         if a.build_id not in bad_precq_builds]
      if updated_actions:
        updated_candidates[patch] = updated_actions
    return updated_candidates

  def GetTrueRejections(self, bot_type=None):
    """Get the changes that were bad, and were rejected.

    A patch rejection is considered a true rejection if a new patch was uploaded
    after the rejection. Note that we consider a rejection a true rejection only
    if a subsequent patch was submitted.

    Returns:
      A map from rejected patch to a list of rejection actions of the relevant
      bot_type in ascending order of timestamps.
    """
    rejections = self._GetPatchRejectionsByBuilds(bot_type)
    submitted_patches = self.GetSubmittedPatches(
        exclude_irrelevant_submissions=False)
    submitted_cls = set([x.GetChangeTuple() for x in submitted_patches])

    candidates = {}
    for patch in set(rejections) - submitted_patches:
      if patch.GetChangeTuple() in submitted_cls:
        # Some other patch for the same was submitted.
        candidates[patch] = rejections[patch]

    return candidates

  # ############################################################################
  # Helper functions.
  def _GetPatchRejectionsByBuilds(self, bot_type=None):
    """Gets all patches that were rejected due to build failures.

    This filters out rejections that were caused by failure to apply the patch.

    Args:
      bot_type: Optional bot_type to filter actions by.

    Returns:
      dict of rejected patches to rejection actions for the given bot_type.
    """
    rejected_patches = AffectedPatches(self.reject_actions)
    candidates = collections.defaultdict(list)
    for patch in rejected_patches:
      relevant_builds = set(a.build_id for a in self._per_patch_actions[patch]
                            if a.action == constants.CL_ACTION_PICKED_UP)
      relevant_actions_iter = (a for a in self._per_patch_actions[patch]
                               if a.action == constants.CL_ACTION_KICKED_OUT)
      if bot_type is not None:
        relevant_actions_iter = (a for a in relevant_actions_iter
                                 if a.bot_type == bot_type)

      for action in relevant_actions_iter:
        if action.build_id in relevant_builds:
          candidates[patch].append(action)
    return dict(candidates)

  def GetCLOrPatchActions(self, cl_or_patch):
    """Get cl/patch specific actions."""
    if isinstance(cl_or_patch, GerritChangeTuple):
      return self._per_cl_actions.get(cl_or_patch, [])
    else:
      return self._per_patch_actions.get(cl_or_patch, [])
