# -*- 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 for tracking relevant changes (i.e. CLs) to validate."""

from __future__ import print_function

import datetime

from chromite.cbuildbot.stages import artifact_stages
from chromite.lib import builder_status_lib
from chromite.lib import clactions
from chromite.lib import constants
from chromite.lib import config_lib
from chromite.lib import cros_collections
from chromite.lib import cros_logging as logging
from chromite.lib import patch as cros_patch
from chromite.lib import triage_lib


# Limit (hours) for looking back cl actions in the history for history-aware
# submission.
CQ_HISTORY_LOOKBACK_LIMIT_HOUR = 48


class RelevantChanges(object):
  """Class that quries and tracks relevant changes."""

  @classmethod
  def _GetSlaveMappingAndCLActions(cls, master_build_id, buildstore, config,
                                   changes, slave_buildbucket_ids,
                                   include_master=False):
    """Query CIDB to for slaves and CL actions.

    Args:
      master_build_id: Build id of this master build.
      buildstore: Instance of buildstore.BuildStore.
      config: Instance of config_lib.BuildConfig of this build.
      changes: A list of GerritPatch instances to examine.
      slave_buildbucket_ids: A list of buildbucket_ids (strings) of slave builds
                             scheduled by Buildbucket.
      include_master: Boolean indicating whether to include the master build in
                      the config_map. Default to False.

    Returns:
      A tuple of (config_map, action_history). The config_map is a dictionary
      mapping build_id to config name for all slaves in this run. If
      include_master is True, the config_map also includes master build. The
      action_history is a list of all CL actions associated with |changes|.
    """
    assert buildstore, 'No buildstore to use.'
    assert config.master, 'This is not a master build.'

    # TODO(buildstore): make sure buildstore is BuildStore, not CIDBConnection.
    slave_list = buildstore.GetSlaveStatuses(
        master_build_id, buildbucket_ids=slave_buildbucket_ids)

    # TODO(akeshet): We are getting the full action history for all changes that
    # were in this CQ run. It would make more sense to only get the actions from
    # build_ids of this master and its slaves.
    action_history = buildstore.GetCIDBHandle().GetActionsForChanges(changes)

    config_map = dict()

    for d in slave_list:
      config_map[d['id']] = d['build_config']

    if include_master:
      config_map[master_build_id] = config.name

    return config_map, action_history

  @classmethod
  def GetRelevantChangesForSlaves(cls, master_build_id, buildstore, config,
                                  changes, builds_not_passed_sync_stage,
                                  slave_buildbucket_ids,
                                  include_master=False):
    """Compile a set of relevant changes for each slave.

    Args:
      master_build_id: Build id of this master build.
      buildstore: Instance of buildstore.BuildStore.
      config: Instance of config_lib.BuildConfig of this build.
      changes: A list of GerritPatch instances to examine.
      builds_not_passed_sync_stage: Set of build config names of slaves that
        didn't pass the sync stages.
      slave_buildbucket_ids: A list of buildbucket_ids (strings) of slave builds
                             scheduled by Buildbucket.
      include_master: Boolean indicating whether to include the master build in
                      the config_map. Default to False.

    Returns:
      A dictionary mapping a slave config name to a set of relevant changes
      (as GerritPatch instances). If include_master is True, the dictionary
      includes the master build config and its relevant changes.
    """
    # TODO(buildstore): make sure buildstore is BuildStore, not CIDBConnection.
    # Retrieve the slaves and clactions from CIDB.
    config_map, action_history = cls._GetSlaveMappingAndCLActions(
        master_build_id, buildstore, config, changes,
        slave_buildbucket_ids, include_master=include_master)
    changes_by_build_id = clactions.GetRelevantChangesForBuilds(
        changes, action_history, config_map.keys())

    # Convert index from build_ids to config names.
    changes_by_config = dict()
    for k, v in changes_by_build_id.iteritems():
      changes_by_config[config_map[k]] = v

    for config in builds_not_passed_sync_stage:
      # If a slave did not passed the sync stage, it means that the slave never
      # finished applying the changes in the sync stage. Hence the CL pickup
      # actions for this slave may be inaccurate. Conservatively assume all
      # changes are relevant.
      changes_by_config[config] = set(changes)

    return changes_by_config

  @classmethod
  def GetPreviouslyPassedSlavesForChanges(
      cls, master_build_id, buildstore, changes, change_relevant_slaves_dict,
      history_lookback_limit=CQ_HISTORY_LOOKBACK_LIMIT_HOUR):
    """Get slaves passed in history (not from current run) for changes.

    If a previous slave build:
    1) inserted constants.CL_ACTION_RELEVANT_TO_SLAVE cl action for a change;
    2) is a passed build;
    3) is a relevant slave of the change
    this slave is considered as a previously passed slave.

    Args:
      master_build_id: The build id of current master to get current slaves.
      buildstore: An instance of buildstore.BuildStore.
      changes: A list of cros_patch.GerritPatch instance to check.
      change_relevant_slaves_dict: A dict mapping changes to their relevant
        slaves in current run.
      history_lookback_limit: Limit (hours) for looking back cl actions in the
        histor. If it's None, do not force the limit.
        Default to CQ_HISTORY_LOOKBACK_LIMIT_HOUR.

    Returns:
      A dict mapping changes (cros_patch.GerritPatch instances) to sets of
      of build config name (strings) of their relevant slaves which passed in
      history.
    """
    assert buildstore, 'No buildstore to use.'
    # TODO(buildstore): make sure buildstore is BuildStore, not CIDBConnection.
    current_slaves = buildstore.GetSlaveStatuses(master_build_id)
    current_slave_build_ids = [x['id'] for x in current_slaves]

    valid_configs = set()
    for relevant_slaves in change_relevant_slaves_dict.values():
      valid_configs.update(relevant_slaves)

    changes_dict = {clactions.GerritPatchTuple(int(change.gerrit_number),
                                               int(change.patch_number),
                                               change.internal):
                    change for change in changes}

    start_time = None
    if history_lookback_limit is not None:
      start_time = (datetime.datetime.now() -
                    datetime.timedelta(hours=history_lookback_limit))

    actions = buildstore.GetCIDBHandle().GetActionsForChanges(
        changes,
        ignore_patch_number=False,
        status=constants.BUILDER_STATUS_PASSED,
        action=constants.CL_ACTION_RELEVANT_TO_SLAVE,
        start_time=start_time)

    change_passed_slaves_dict = {}
    for action in actions:
      if (action.build_config in valid_configs and
          action.build_id not in current_slave_build_ids):
        change = changes_dict.get(action.patch)
        if change:
          change_passed_slaves_dict.setdefault(change, set()).add(
              action.build_config)

    return change_passed_slaves_dict


class TriageRelevantChanges(object):
  """Class to triage relevant changes within a CQ run..

  This class keeps track of relevant_changes of a list slave builds of given a
  master build. With the build information fetched from Buildbucket and CIDB,
  it performs relevant change triages, and returns a ShouldWait flag indicating
  whether it's still meaningful for the master build to wait for the slave
  builds. The triages include anaylizing whether the failed slave builds have
  passed the critial sync stage, whether the failures in failed slave builds
  are ignorable for changes, classifying changes into will_submit, might_submit
  and will_not_submit sets, and so on.
  More context: go/self-destructed-commit-queue
  """

  # Accepted statues of the critical stages
  ACCEPTED_STATUSES = {
      constants.BUILDER_STATUS_PASSED,
      constants.BUILDER_STATUS_SKIPPED
  }

  # TODO(nxia): crbug.com/694749
  # Get stage names from stage classes instead of duplicating them here.
  COMMIT_QUEUE_SYNC = 'CommitQueueSync'
  MASTER_SLAVE_LKGM_SYNC = 'MasterSlaveLKGMSync'
  STAGE_SYNC = {COMMIT_QUEUE_SYNC, MASTER_SLAVE_LKGM_SYNC}

  STAGE_UPLOAD_PREBUILTS = (
      artifact_stages.UploadPrebuiltsStage.StageNamePrefix())

  def __init__(self, master_build_id, buildstore, builders_array, config,
               metadata, version, build_root, changes, buildbucket_info_dict,
               cidb_status_dict, completed_builds, dependency_map,
               buildbucket_client, dry_run=True):
    """Initialize an instance of TriageRelevantChanges.

    Args:
      master_build_id: The build_id of the master build.
      buildstore: A BuildStore instance to make DB calls.
      builders_array: A list of expected slave build config names (strings).
      config: An instance of config_lib.BuildConfig. Config dict of this build.
      metadata: Instance of metadata_lib.CBuildbotMetadata. Metadata of this
                build.
      version: Current manifest version string. See the return type of
        VersionInfo.VersionString().
      build_root: Path to the build root directory.
      changes: A list of changes (GerritPatch instances) which have been applied
        to this build.
      buildbucket_info_dict: A dict mapping all slave build config names to
        their BuildbucketInfos (See SlaveBuilerStatus.GetAllSlaveBuildbucketInfo
        for details).
      cidb_status_dict: A dict mapping all slave build config names to their
        CIDBStatusInfos (See SlaveBuilerStatus.GetAllSlaveCIDBStatusInfo for
        details)
      completed_builds: A set of slave build config names (strings) which
        have completed and will not be retried.
      dependency_map: A dict mapping a change (patch.GerritPatch instance) to a
        set of changes (patch.GerritPatch instances) depending on this change.
        (See ValidationPool.GetDependMapForChanges for details.)
      buildbucket_client: Instance of buildbucket_lib.buildbucket_client.
      dry_run: Boolean indicating whether it's a dry run. Default to True.
    """
    self.master_build_id = master_build_id
    self.buildstore = buildstore
    self.db = buildstore.GetCIDBHandle()
    self.builders_array = builders_array
    self.config = config
    self.metadata = metadata
    self.version = version
    self.buildbucket_info_dict = buildbucket_info_dict
    self.cidb_status_dict = cidb_status_dict
    self.completed_builds = completed_builds
    self.build_root = build_root
    self.changes = changes
    self.dependency_map = dependency_map
    self.buildbucket_client = buildbucket_client
    self.dry_run = dry_run

    # Dict mapping slave config names to a list of stages
    self.slave_stages_dict = None
    # Dict mapping slave config names to relevant change sets.
    self.slave_changes_dict = None

    # A set of changes which will be submitted by the master.
    self.will_submit = set()
    # A set of changes which are being tested by the slaves.
    self.might_submit = set(self.changes)
    # A set of chagnes which won't be submitted by the master.
    self.will_not_submit = set()

    # A dict mapping build config name to a set of changes which can ignore the
    # failures in the build.
    self.build_ignorable_changes_dict = {}

    # A dict mapping changes to their relevant slaves (build_configs).
    self.change_relevant_slaves_dict = None

    # A dict mapping changes to their passed slaves (build_configs) in history.
    self.change_passed_slaves_dict = None

    self._UpdateSlaveInfo()

  def _UpdateSlaveInfo(self):
    """Update slave infomation with stages, relevant_changes, and subsys."""
    self.slave_stages_dict = self.GetChildStages()
    self.slave_changes_dict = self._GetRelevantChanges(
        self.slave_stages_dict)
    self.change_relevant_slaves_dict = cros_collections.InvertDictionary(
        self.slave_changes_dict)
    self.change_passed_slaves_dict = (
        RelevantChanges.GetPreviouslyPassedSlavesForChanges(
            self.master_build_id, self.buildstore, self.changes,
            self.change_relevant_slaves_dict))

  @staticmethod
  def GetDependChanges(changes, dependency_map):
    """Get a set of changes depending on the given changes.

    Args:
      changes: A set of changes to get the dependent change set.
      dependency_map: A dict mapping a change (patch.GerritPatch instance) to a
        set of changes (patch.GerritPatch instances) directly or indirectly
        depending on this change. (See ValidationPool.GetDependMapForChanges for
        details.)

    Returns:
      A set of all changes directly or indirectly depending on the given
      changes.
    """
    return set().union(*[dependency_map.get(c, set()) for c in changes])

  # TODO(nxia): Consolidate with completion_stages._ShouldSubmitPartialPool
  def GetChildStages(self):
    """Get child stages from buildstore.

    Returns:
      A dict mapping all child config names (strings) to their stages (a list
        of dicts, see BuildStore.GetBuildsStages for details.)
    """
    slave_stages_dict = {}
    slave_buildbucket_ids = []

    if self.buildbucket_info_dict is not None:
      for slave_config, bb_info in self.buildbucket_info_dict.iteritems():
        # Set default value for all slaves, some may not have stages in CIDB.
        slave_stages_dict.setdefault(slave_config, [])
        slave_buildbucket_ids.append(bb_info.buildbucket_id)

    stages = self.buildstore.GetBuildsStages(
        buildbucket_ids=slave_buildbucket_ids)

    for stage in stages:
      slave_stages_dict[stage['build_config']].append(stage)

    return slave_stages_dict

  @classmethod
  def PassedAnyOfStages(cls, stages, desired_stages):
    """Check if the stages have passed any stage from desired_stages.

    Args:
      stages: A list of stages (see the type of slave_stages_dict value part)
        to check.
      desired_stages: A set of desired stages (strings).

    Returns:
      True if the accepted stages in the given stages cover any stage in
      the desired_stages set; else, False.
    """
    accepted_stages = {stage['name'] for stage in stages
                       if stage['status'] in cls.ACCEPTED_STATUSES}

    return accepted_stages.intersection(desired_stages)

  @classmethod
  def GetBuildsPassedAnyOfStages(cls, build_stages_dict, desired_stages):
    """Get builds which have passed any stage from desired_stages.

    Args:
      build_stages_dict: A dict mapping build config names to their stage lists.
      desired_stages: A set of desired stages (strings).

    Returns:
      A set of build config names (strings) which have passed any stage in
      desired_stages.
    """
    return set(build_config
               for build_config, stages in build_stages_dict.iteritems()
               if cls.PassedAnyOfStages(stages, desired_stages))

  def _GetRelevantChanges(self, slave_stages_dict):
    """Get relevant changes for slave builds.

    Args:
      slave_stages_dict: A dict mapping slaves config names (strings) to their
        stage lists. (see GetSlaveStages for details).

    Returns:
      A dict mapping all slave config names (strings) to sets of changes which
      are relevant to the slave builds. If a build has passed the STAGE_SYNC
      stage, it has recorded the CLs it picked up in the CIDB, it's mapped to
      its relevant change set. If a build failed to pass the STAGE_SYNC stage,
      we assume it's relevant to all changes, so it's mapped to the change set
      containing all the applied changes.
    """
    # If a build passed the sync stage, the picked up change stats are recorded.
    builds_passed_sync_stage = self.GetBuildsPassedAnyOfStages(
        slave_stages_dict, self.STAGE_SYNC)
    builds_not_passed_sync_stage = (set(self.buildbucket_info_dict.keys()) -
                                    builds_passed_sync_stage)
    slave_buildbucket_ids = [bb_info.buildbucket_id
                             for bb_info in self.buildbucket_info_dict.values()]
    slave_changes_dict = RelevantChanges.GetRelevantChangesForSlaves(
        self.master_build_id, self.buildstore, self.config, self.changes,
        builds_not_passed_sync_stage, slave_buildbucket_ids)

    # Some slaves may not pick up any changes, update the value to set()
    for slave_config in self.buildbucket_info_dict:
      slave_changes_dict.setdefault(slave_config, set())

    return slave_changes_dict

  def _GetIgnorableChanges(self, build_config, builder_status,
                           relevant_changes):
    """Get changes that can ignore failures in BuilderStatus.

    Some projects are configured with ignored-stages in COMMIT_QUEUE.ini. The CQ
    can still submit changes from these projects if all failed statges are
    listed in ignored-stages. Please refer to
    cq_config.CQConfigParser.GetStagesToIgnore for more details.

    1) if the builder_status is in 'pass' status, it means the build uploaded a
    'pass' builder_status but failed other steps in or after the completion
    stage. This is rare but still possible, and it should not blame any changes
    as the build has finishes its testing. Returns all changes in
    relevant_changes in this case.
    2) else if the builder_status is in 'fail' with failure messages, it
    calculates and returns all ignorable changes given the failure messages.
    3) else, the builder_status is either in 'fail' status without failure
    messages or in one of the 'inflight' and 'missing' statuses. It cannot
    calculate ignorable changes without any failure message so should just
    return an empty set.

    Args:
      build_config: The config name (string) of the build.
      builder_status: An instance of build_status.BuilderStatus.
      relevant_changes: A set of relevant changes for triage to get the
        ignorable changes.

    Returns:
      A set of ignorable changes (GerritPatch instances).
    """
    if builder_status.Passed():
      return relevant_changes
    elif builder_status.Failed() and builder_status.message:
      ignoreable_changes = set()
      for change in relevant_changes:
        ignore_result = triage_lib.CalculateSuspects.CanIgnoreFailures(
            [builder_status.message], change, self.build_root)

        if ignore_result[0]:
          logging.debug('change %s is ignoreable for failures of %s.',
                        cros_patch.GetChangesAsString([change]), build_config)
          ignoreable_changes.add(change)
      return ignoreable_changes
    else:
      return set()

  def _UpdateWillNotSubmitChanges(self, will_not_submit):
    """Update will_not_submit change set.

    Args:
      will_not_submit: A set of changes (GerritPatch instances) to add to
        will_not_submit.
    """
    self.will_not_submit.update(will_not_submit)
    self.might_submit.difference_update(will_not_submit)

  def _GetWillNotSubmitChanges(self, build_config, changes):
    """Get changes which will not be submitted because of the failed build.

    Get a list of changes which will not be submitted because the build_config
    is relevant to the changes, and the build of this build_config didn't pass
    in current run and the failures are not ignorable, and there's no passed
    build of this build_config in history.

    Args:
      build_config: The build config name (string) of the failed build.
      changes: A list of cros_patch.GerritPatch instances to check.

    Returns:
      A list of changes (cros_patch.GerritPatch) which will not be submitted.
    """
    will_not_submit_changes = set()
    for change in changes:
      if (build_config in self.change_relevant_slaves_dict.get(change, set())
          and build_config not in self.change_passed_slaves_dict.get(
              change, set())):
        will_not_submit_changes.add(change)

    return will_not_submit_changes

  def _ProcessCompletedBuilds(self):
    """Process completed and not retriable builds.

    This method goes through all the builds which completed without SUCCESS
    result and will not be retried.
    1) if the failed build didn't pass the sync stage, iterate all changes,
    move the changes which didn't pass this build config in history to
    will_not_submit (as well as their dependencies).
    2) else, get BuilderStatus for the build (if there's no BuilderStatus
    pickle file in GS, a BuilderStatus with 'missing' status will be returned).
    Find not ignorable changes given the BuilderStatus, iterate the changes in
    not ignorable changes, move the changes which didn't pass this build config
    in history to will_not_submit (as well as their dependencies).
    """
    # TODO(nxia): Improve SlaveBuilderStatus to take buildbucket_info_dict
    # and cidb_status_dict as arguments to avoid extra queries.
    slave_builder_statuses = builder_status_lib.SlaveBuilderStatus(
        self.master_build_id, self.buildstore, self.config, self.metadata,
        self.buildbucket_client, self.builders_array, self.dry_run)

    for build_config, bb_info in self.buildbucket_info_dict.iteritems():
      if (build_config in self.completed_builds and
          bb_info.status == constants.BUILDBUCKET_BUILDER_STATUS_COMPLETED and
          bb_info.result != constants.BUILDBUCKET_BUILDER_RESULT_SUCCESS):
        # This build didn't succeed and cannot be retried.
        logging.info('Processing relevant changes of build %s status %s '
                     'result %s', build_config, bb_info.status, bb_info.result)

        stages = self.slave_stages_dict[build_config]
        if not self.PassedAnyOfStages(stages, self.STAGE_SYNC):
          # The build_config didn't pass any of the sync stages. Find changes
          # which don't have valid passed builds of this build_config in
          # history. Move the changes and their dependencies to will_not_submit
          # set.
          will_not_submit_changes = self._GetWillNotSubmitChanges(
              build_config, self.changes)
          depend_changes = self.GetDependChanges(
              will_not_submit_changes, self.dependency_map)
          will_not_submit_changes |= depend_changes

          if will_not_submit_changes:
            self._UpdateWillNotSubmitChanges(will_not_submit_changes)
            logging.info('Build %s didn\'t pass any stage in %s. Will not'
                         ' submit changes: %s', build_config, self.STAGE_SYNC,
                         cros_patch.GetChangesAsString(will_not_submit_changes))
        else:
          # The build passed the required sync stage. Get builder_status and
          # get not ignorable changes based on the builder_status. Find changes
          # in the not ignorable changes don't have valid passed builds of this
          # build_config hi history. Move the changes and their dependencies to
          # will_not_submit set.
          relevant_changes = self.slave_changes_dict[build_config]
          builder_status = slave_builder_statuses.GetBuilderStatusForBuild(
              build_config)
          ignorable_changes = self._GetIgnorableChanges(
              build_config, builder_status, relevant_changes)
          self.build_ignorable_changes_dict[build_config] = ignorable_changes
          not_ignorable_changes = relevant_changes - ignorable_changes

          will_not_submit_changes = self._GetWillNotSubmitChanges(
              build_config, not_ignorable_changes)
          depend_changes = self.GetDependChanges(
              will_not_submit_changes, self.dependency_map)
          will_not_submit_changes = will_not_submit_changes | depend_changes

          if will_not_submit_changes:
            self._UpdateWillNotSubmitChanges(will_not_submit_changes)
            logging.info('Build %s failed with not ignorable failures, will not'
                         ' submit changes: %s', build_config,
                         cros_patch.GetChangesAsString(will_not_submit_changes))

        if not self.might_submit:
          # No need to process other completed builds, might_submit is empty.
          return

  def _ChangeVerifiedByCurrentBuild(self, change, build_config,
                                    buildbucket_info_dict,
                                    build_ignorable_changes_dict):
    """Whether the change can by verified by the current build of build_config.

    A change can be verified by the build if it satisfies the conditions:
    1) the build successfully completed; OR
    2) the build failed but its failures can be ignored by the change.

    Args:
      change: An instance of cros_patch.GerritPatch to check.
      build_config: The build config name (string) (relevant to the change) to
        verify.
      buildbucket_info_dict: A dict mapping all slave build config names to
        their BuildbucketInfos (See SlaveBuilerStatus.GetAllSlaveBuildbucketInfo
        for details).
      build_ignorable_changes_dict: A dict mapping build config name (string) to
        a set of changes (GerritPatch instances) which can ignore the failures
        in the build.

    Returns:
      True if the change can be verified by the current build of build_config;
      else, False.
    """
    bb_info = buildbucket_info_dict.get(build_config)
    ignorable_changes = build_ignorable_changes_dict.get(build_config, set())
    if bb_info.status != constants.BUILDBUCKET_BUILDER_STATUS_COMPLETED:
      return False
    if bb_info.result != constants.BUILDBUCKET_BUILDER_RESULT_SUCCESS:
      #If the build uploaded 'passed' BuilderStatus pickle or the build
      # only contains failures which can be ignored by this change, change is
      # in the value set for build_config in build_ignorable_changes_dict.
      if change not in ignorable_changes:
        return False

    return True

  def _ChangeCanBeSubmitted(self, change, relevant_slave_configs,
                            buildbucket_info_dict, build_ignorable_changes_dict,
                            change_passed_slaves_dict):
    """Whether the change can be submitted by current cq or cq history.

    A change can NOT be submitted if at least one of its relevant slaves
    satisfies the conditions:
    1) the relevant build_config failed in current build with not ignorable
      failures; AND
    2) no passed build for the relevant build_config in cq history.

    Args:
      change: A change (GerritPatch instance) to check.
      relevant_slave_configs: A list of relevant slave config names (string) of
        this change.
      buildbucket_info_dict: A dict mapping all slave build config names to
        their BuildbucketInfos (See SlaveBuilerStatus.GetAllSlaveBuildbucketInfo
        for details).
      build_ignorable_changes_dict: A dict mapping build config name (string) to
        a set of changes (GerritPatch instances) which can ignore the failures
        in the build.
      change_passed_slaves_dict: A dict mapping changes (cros_patch.GerritPatch)
        to their passed slaves (build_config name strings) in history.

    Returns:
      True if the change can be submitted given the statues of its relevant
      slaves; else, False.
    """
    for build_config in relevant_slave_configs:
      if (not self._ChangeVerifiedByCurrentBuild(change, build_config,
                                                 buildbucket_info_dict,
                                                 build_ignorable_changes_dict)
          and build_config not in change_passed_slaves_dict.get(change, set())):
        return False

    return True

  def _ProcessMightSubmitChanges(self):
    """Process changes in might_submit set.

    This method goes through all the changes in current might_submit set. For
    each change, get a set of its relevant slaves. If all the relevant slaves
    can either be verified by current CQ or passed in CQ history, move the
    change to will_submit set.
    """
    if not self.might_submit:
      return

    logging.info('Processing changes in might submit set.')
    will_submit_changes = set()
    for change in self.might_submit:
      relevant_slaves = self.change_relevant_slaves_dict.get(change, set())
      if self._ChangeCanBeSubmitted(
          change, relevant_slaves, self.buildbucket_info_dict,
          self.build_ignorable_changes_dict, self.change_passed_slaves_dict):
        will_submit_changes.add(change)

    if will_submit_changes:
      self.will_submit.update(will_submit_changes)
      self.might_submit.difference_update(will_submit_changes)
      logging.info('Moving %s to will_submit set, because their relevant builds'
                   ' completed successfully or all failures are ignorable or '
                   'passed in CQ history.',
                   cros_patch.GetChangesAsString(will_submit_changes))

  def _AllCompletedSlavesPassedUploadPrebuiltsStage(self):
    """Check if all completed slaves have passed the UploadPrebuiltsStage."""
    site_config = config_lib.GetConfig()
    for build_config in self.completed_builds:
      # compilecheck builds don't run UploadPrebuiltsStage
      if (not site_config[build_config].compilecheck and
          not self.PassedAnyOfStages(self.slave_stages_dict[build_config],
                                     {self.STAGE_UPLOAD_PREBUILTS})):
        logging.info("Completed build %s didn't pass stage %s. "
                     "The master can't publish uprevs now.",
                     build_config, self.STAGE_UPLOAD_PREBUILTS)
        return False

    return True

  def _AllUncompletedSlavesPassedUploadPrebuiltsStage(self):
    """Check if all uncompleted slaves have passed the UploadPrebuiltsStage."""
    site_config = config_lib.GetConfig()
    for build_config in set(self.builders_array) - self.completed_builds:
      # compilecheck builds don't run UploadPrebuiltsStage
      if (not site_config[build_config].compilecheck and
          not self.PassedAnyOfStages(self.slave_stages_dict[build_config],
                                     {self.STAGE_UPLOAD_PREBUILTS})):
        logging.info("Uncompleted build %s haven't passed stage %s. "
                     "The master can't publish uprevs now.",
                     build_config, self.STAGE_UPLOAD_PREBUILTS)
        return False

    return True

  def ShouldSelfDestruct(self):
    """Process builds and relevant changes, decide whether to self-destruct.

    Returns:
      A tuple of (boolean indicating if the master should self-destruct,
                  boolean indicating if the master should self-destruct with
                  with success)
    """
    self._ProcessCompletedBuilds()
    self._ProcessMightSubmitChanges()

    logging.info('will_submit set contains %d changes: [%s]\n'
                 'might_submit set contains %d changes: [%s]\n'
                 'will_not_submit set contains %d changes: [%s]\n',
                 len(self.will_submit),
                 cros_patch.GetChangesAsString(self.will_submit),
                 len(self.might_submit),
                 cros_patch.GetChangesAsString(self.might_submit),
                 len(self.will_not_submit),
                 cros_patch.GetChangesAsString(self.will_not_submit))

    # The master should wait for all the necessary slaves to pass the
    # UploadPrebuiltsStage so the master can publish prebuilts after
    # self-destruction with success. More context: crbug.com/703819
    all_completed_slaves_passed = (
        self._AllCompletedSlavesPassedUploadPrebuiltsStage())
    all_uncompleted_slaves_passed = (
        self._AllUncompletedSlavesPassedUploadPrebuiltsStage())
    should_self_destruct = (bool(not self.might_submit) and
                            (not all_completed_slaves_passed or
                             all_uncompleted_slaves_passed))
    should_self_destruct_with_success = (bool(not self.might_submit) and
                                         bool(not self.will_not_submit) and
                                         all_completed_slaves_passed and
                                         all_uncompleted_slaves_passed)

    return should_self_destruct, should_self_destruct_with_success
