# Copyright (c) 2013 The ChromiumOS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A generation of a set of tasks.

Part of the Chrome build flags optimization.

This module contains the base generation class. This class contains the tasks of
this current generation. The generation will not evolve to the next generation
until all the tasks in this generation are done executing. It also contains a
set of tasks that could potentially be used to generate the next generation,
e.g., in the genetic algorithm, a set of good species will be kept to evolve to
the successive generations. For the hill climbing algorithm example, the
candidate_pool will contain a current task t being evaluated and the exe_set
will contains all the task t's neighbor.
"""

__author__ = 'yuhenglong@google.com (Yuheng Long)'


class NoneOverridingError(Exception):
  """Define an Exception class for subclasses not overriding certain methods."""
  pass


class Generation(object):
  """A generation of a framework run.

  The base class of generation. Concrete subclasses, e.g., GAGeneration should
  override the Next and IsImproved method to implement algorithm specific
  applications.
  """

  def __init__(self, exe_set, candidate_pool):
    """Set up the tasks set of this generation.

    Args:
      exe_set: A set of tasks to be run.
      candidate_pool: A set of tasks to be considered to be used to generate the
        next generation.
    """

    self._exe_set = exe_set
    self._candidate_pool = candidate_pool

    # Keeping the record of how many tasks are pending. Pending tasks are the
    # ones that have been sent out to the next stage for execution but have not
    # finished. A generation is not ready for the reproduction of the new
    # generations until all its pending tasks have been executed.
    self._pending = len(exe_set)

  def CandidatePool(self):
    """Return the candidate tasks of this generation."""

    return self._candidate_pool

  def Pool(self):
    """Return the task set of this generation."""

    return self._exe_set

  def Done(self):
    """All the tasks in this generation are done.

    Returns:
      True if all the tasks have been executed. That is the number of pending
      task is 0.
    """

    return self._pending == 0

  def UpdateTask(self, task):
    """Match a task t in this generation that is equal to the input task.

    This method is called when the input task has just finished execution. This
    method finds out whether there is a pending task t in the current generation
    that is the same as the input task. Two tasks are the same if their flag
    options are the same. A task is pending if it has not been performed.
    If there is a pending task t that matches the input task, task t will be
    substituted with the input task in this generation. In that case, the input
    task, as well as its build and test results encapsulated in the task, will
    be stored in the current generation. These results could be used to produce
    the next generation.
    If there is a match, the current generation will have one less pending task.
    When there is no pending task, the generation can be used to produce the
    next generation.
    The caller of this function is responsible for not calling this method on
    the same task more than once.

    Args:
      task: A task that has its results ready.

    Returns:
      Whether the input task belongs to this generation.
    """

    # If there is a match, the input task belongs to this generation.
    if task not in self._exe_set:
      return False

    # Remove the place holder task in this generation and store the new input
    # task and its result.
    self._exe_set.remove(task)
    self._exe_set.add(task)

    # The current generation will have one less task to wait on.
    self._pending -= 1

    assert self._pending >= 0

    return True

  def IsImproved(self):
    """True if this generation has improvement upon its parent generation.

    Raises:
      NoneOverridingError: The subclass should override this method.
    """
    raise NoneOverridingError('Must be implemented by child class')

  def Next(self, _):
    """Calculate the next generation.

    This is the core of the framework implementation. It must be overridden by
    the concrete subclass to implement algorithm specific generations.

    Args:
      _: A set of tasks that have been generated before. The overridden method
        in the subclasses can use this so as not to generate task that has been
        generated before.

    Returns:
      A set of new generations.

    Raises:
      NoneOverridingError: The subclass should override this method.
    """

    raise NoneOverridingError('Must be implemented by child class')
