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

"""Configuration options for various cbuildbot builders."""

from __future__ import print_function

import copy
import itertools
import json
import os

from chromite.lib.const import waterfall
from chromite.lib import constants
from chromite.lib import osutils


GS_PATH_DEFAULT = 'default' # Means gs://chromeos-image-archive/ + bot_id

# Contains the valid build config suffixes in the order that they are dumped.
CONFIG_TYPE_PRECQ = 'pre-cq'
CONFIG_TYPE_PALADIN = 'paladin'
CONFIG_TYPE_RELEASE = 'release'
CONFIG_TYPE_FULL = 'full'
CONFIG_TYPE_FIRMWARE = 'firmware'
CONFIG_TYPE_FACTORY = 'factory'
CONFIG_TYPE_RELEASE_AFDO = 'release-afdo'
CONFIG_TYPE_TOOLCHAIN = 'toolchain'

# This is only used for unitests... find a better solution?
CONFIG_TYPE_DUMP_ORDER = (
    CONFIG_TYPE_PALADIN,
    CONFIG_TYPE_PRECQ,
    constants.PRE_CQ_LAUNCHER_CONFIG,
    'incremental',
    'telemetry',
    CONFIG_TYPE_FULL,
    'full-group',
    CONFIG_TYPE_RELEASE,
    'release-group',
    'release-afdo',
    'release-afdo-generate',
    'release-afdo-use',
    'sdk',
    'chromium-pfq',
    'chromium-pfq-informational',
    'chrome-perf',
    'chrome-pfq',
    'chrome-pfq-cheets-informational',
    'chrome-pfq-informational',
    'android-pfq',
    'vmtest-informational',
    'som-dispatcher',
    'config-updater',
    'pre-flight-branch',
    CONFIG_TYPE_FACTORY,
    CONFIG_TYPE_FIRMWARE,
    'toolchain',
    'asan',
    'asan-informational',
    'refresh-packages',
    'test-ap',
    'test-ap-group',
    constants.BRANCH_UTIL_CONFIG,
    constants.PAYLOADS_TYPE,
    'cbuildbot',
    'unittest-stress',
    'infra-go',
    'tryjob',
)

DISPLAY_LABEL_PRECQ = 'pre_cq'
DISPLAY_LABEL_TRYJOB = 'tryjob'
DISPLAY_LABEL_INCREMENATAL = 'incremental'
DISPLAY_LABEL_FULL = 'full'
DISPLAY_LABEL_INFORMATIONAL = 'informational'

# These are the build groups against which tryjobs can be run. All other
# groups MUST be production builds.
# TODO: crbug.com/776955 Make the above statement true.
TRYJOB_DISPLAY_LABEL = {
    DISPLAY_LABEL_PRECQ,
    DISPLAY_LABEL_TRYJOB,
    DISPLAY_LABEL_INCREMENATAL,
    DISPLAY_LABEL_FULL,
    DISPLAY_LABEL_INFORMATIONAL,
}

DISPLAY_LABEL_CQ = 'cq'
DISPLAY_LABEL_RELEASE = 'release'
DISPLAY_LABEL_CHROME_PFQ = 'chrome_pfq'
DISPLAY_LABEL_MNC_ANDROID_PFQ = 'mnc_android_pfq'
DISPLAY_LABEL_NYC_ANDROID_PFQ = 'nyc_android_pfq'
DISPLAY_LABEL_FIRMWARE = 'firmware'
DISPLAY_LABEL_FACTORY = 'factory'
DISPLAY_LABEL_TOOLCHAIN = 'toolchain'
DISPLAY_LABEL_UTILITY = 'utility'
DISPLAY_LABEL_UNKNOWN_PRODUCTION = 'production_tryjob'

# This list of constants should be kept in sync with GoldenEye code.
ALL_DISPLAY_LABEL = TRYJOB_DISPLAY_LABEL | {
    DISPLAY_LABEL_CQ,
    DISPLAY_LABEL_RELEASE,
    DISPLAY_LABEL_CHROME_PFQ,
    DISPLAY_LABEL_MNC_ANDROID_PFQ,
    DISPLAY_LABEL_NYC_ANDROID_PFQ,
    DISPLAY_LABEL_FIRMWARE,
    DISPLAY_LABEL_FACTORY,
    DISPLAY_LABEL_TOOLCHAIN,
    DISPLAY_LABEL_UTILITY,
    DISPLAY_LABEL_UNKNOWN_PRODUCTION,
}

def isTryjobConfig(build_config):
  """Is a given build config a tryjob config, or a production config?

  Args:
    build_config: A fully populated instance of BuildConfig.

  Returns:
    Boolean. True if it's a tryjob config.
  """
  return build_config.display_label in TRYJOB_DISPLAY_LABEL


# In the Json, this special build config holds the default values for all
# other configs.
DEFAULT_BUILD_CONFIG = '_default'

# We cache the config we load from disk to avoid reparsing.
_CACHED_CONFIG = None

# Constants for config template file
CONFIG_TEMPLATE_BOARDS = 'boards'
CONFIG_TEMPLATE_NAME = 'name'
CONFIG_TEMPLATE_EXPERIMENTAL = 'experimental'
CONFIG_TEMPLATE_LEADER_BOARD = 'leader_board'
CONFIG_TEMPLATE_BOARD_GROUP = 'board_group'
CONFIG_TEMPLATE_BUILDER = 'builder'
CONFIG_TEMPLATE_RELEASE = 'RELEASE'
CONFIG_TEMPLATE_CONFIGS = 'configs'
CONFIG_TEMPLATE_ARCH = 'arch'
CONFIG_TEMPLATE_RELEASE_BRANCH = 'release_branch'
CONFIG_TEMPLATE_REFERENCE_BOARD_NAME = 'reference_board_name'
CONFIG_TEMPLATE_MODELS = 'models'
CONFIG_TEMPLATE_MODEL_NAME = 'name'
CONFIG_TEMPLATE_MODEL_BOARD_NAME = 'board_name'
CONFIG_TEMPLATE_MODEL_TEST_SUITES = 'test_suites'
CONFIG_TEMPLATE_MODEL_CQ_TEST_ENABLED = 'cq_test_enabled'

CONFIG_X86_INTERNAL = 'X86_INTERNAL'
CONFIG_X86_EXTERNAL = 'X86_EXTERNAL'
CONFIG_ARM_INTERNAL = 'ARM_INTERNAL'
CONFIG_ARM_EXTERNAL = 'ARM_EXTERNAL'

def IsPFQType(b_type):
  """Returns True if this build type is a PFQ."""
  return b_type in (constants.PFQ_TYPE, constants.PALADIN_TYPE,
                    constants.CHROME_PFQ_TYPE, constants.ANDROID_PFQ_TYPE)

def IsCQType(b_type):
  """Returns True if this build type is a Commit Queue."""
  return b_type == constants.PALADIN_TYPE

def IsCanaryType(b_type):
  """Returns True if this build type is a Canary."""
  return b_type == constants.CANARY_TYPE

def IsMasterChromePFQ(config):
  """Returns True if this build is master chrome PFQ type."""
  return config.build_type == constants.CHROME_PFQ_TYPE and config.master

def IsMasterAndroidPFQ(config):
  """Returns True if this build is master Android PFQ type."""
  return config.build_type == constants.ANDROID_PFQ_TYPE and config.master

def IsMasterCQ(config):
  """Returns True if this build is master CQ."""
  return config.build_type == constants.PALADIN_TYPE and config.master

def IsMasterBuild(config):
  """Returns True if this build is master."""
  return config.master

def UseBuildbucketScheduler(config):
  """Returns True if this build uses Buildbucket to schedule builds."""
  return (config.active_waterfall in (waterfall.WATERFALL_INTERNAL,
                                      waterfall.WATERFALL_EXTERNAL,
                                      waterfall.WATERFALL_TRYBOT) and
          config.name in (constants.CQ_MASTER,
                          constants.CANARY_MASTER,
                          constants.PFQ_MASTER,
                          constants.NYC_ANDROID_PFQ_MASTER,
                          constants.TOOLCHAIN_MASTTER,
                          constants.PRE_CQ_LAUNCHER_NAME))

def RetryAlreadyStartedSlaves(config):
  """Returns True if wants to retry slaves which already start but fail.

  For a slave scheduled by Buildbucket, if the slave started cbuildbot
  and reported status to CIDB but failed to finish, its master may
  still want to retry the slave.
  """
  return config.name == constants.CQ_MASTER

def GetCriticalStageForRetry(config):
  """Get critical stage names for retry decisions.

  For a slave scheduled by Buildbucket, its master may want to retry it
  if it didn't pass the critical stage.

  Returns:
    A set of critical stage names (strings) for the config;
      default to an empty set.
  """
  if config.name == constants.CQ_MASTER:
    return {'CommitQueueSync', 'MasterSlaveLKGMSync'}
  else:
    return set()

def ScheduledByBuildbucket(config):
  """Returns True if this build is scheduled by Buildbucket."""
  return (config.build_type == constants.PALADIN_TYPE and
          config.name != constants.CQ_MASTER)

def OverrideConfigForTrybot(build_config, options):
  """Apply trybot-specific configuration settings.

  Args:
    build_config: The build configuration dictionary to override.
      The dictionary is not modified.
    options: The options passed on the commandline.

  Returns:
    A build configuration dictionary with the overrides applied.
  """
  # TODO: crbug.com/504653 is about deleting this method fully.

  copy_config = copy.deepcopy(build_config)
  for my_config in [copy_config] + copy_config['child_configs']:
    # Force uprev. This is so patched in changes are always built.
    my_config['uprev'] = True
    if my_config['internal']:
      my_config['overlays'] = constants.BOTH_OVERLAYS

    # Use the local manifest which only requires elevated access if it's really
    # needed to build.
    if not options.remote_trybot:
      my_config['manifest'] = my_config['dev_manifest']

    my_config['push_image'] = False

    if my_config['build_type'] != constants.PAYLOADS_TYPE:
      my_config['paygen'] = False

    if options.hwtest and my_config['hw_tests_override'] is not None:
      my_config['hw_tests'] = my_config['hw_tests_override']

    # Default to starting with a fresh chroot on remote trybot runs.
    if options.remote_trybot:
      my_config['chroot_replace'] = True

    # In trybots, we want to always run VM tests and all unit tests, so that
    # developers will get better testing for their changes.
    if my_config['vm_tests_override'] is not None:
      my_config['vm_tests'] = my_config['vm_tests_override']

  return copy_config


class AttrDict(dict):
  """Dictionary with 'attribute' access.

  This is identical to a dictionary, except that string keys can be addressed as
  read-only attributes.
  """
  def __getattr__(self, name):
    """Support attribute-like access to each dict entry."""
    if name in self:
      return self[name]

    # Super class (dict) has no __getattr__ method, so use __getattribute__.
    return super(AttrDict, self).__getattribute__(name)


class BuildConfig(AttrDict):
  """Dictionary of explicit configuration settings for a cbuildbot config

  Each dictionary entry is in turn a dictionary of config_param->value.

  See DefaultSettings for details on known configurations, and their
  documentation.
  """
  def GetBotId(self, remote_trybot=False):
    """Get the 'bot id' of a particular bot.

    The bot id is used to specify the subdirectory where artifacts are stored
    in Google Storage. To avoid conflicts between remote trybots and regular
    bots, we add a 'trybot-' prefix to any remote trybot runs.

    Args:
      remote_trybot: Whether this run is a remote trybot run.
    """
    return 'trybot-%s' % self.name if remote_trybot else self.name

  def deepcopy(self):
    """Create a deep copy of this object.

    This is a specialized version of copy.deepcopy() for BuildConfig objects. It
    speeds up deep copies by 10x because we know in advance what is stored
    inside a BuildConfig object and don't have to do as much introspection. This
    function is called a lot during setup of the config objects so optimizing it
    makes a big difference. (It saves seconds off the load time of this module!)
    """
    result = BuildConfig(self)

    # Here is where we handle all values that need deepcopy instead of shallow.
    for k, v in result.iteritems():
      if v is not None:
        if k == 'child_configs':
          result[k] = [x.deepcopy() for x in v]
        elif k in ('vm_tests', 'vm_tests_override',
                   'hw_tests', 'hw_tests_override',
                   'tast_vm_tests'):
          result[k] = [copy.copy(x) for x in v]
        # type(v) is faster than isinstance.
        elif type(v) is list:
          result[k] = v[:]

    return result

  def apply(self, *args, **kwargs):
    """Apply changes to this BuildConfig.

    Note: If an override is callable, it will be called and passed the prior
    value for the given key (or None) to compute the new value.

    Args:
      args: Dictionaries or templates to update this config with.
      kwargs: Settings to inject; see DefaultSettings for valid values.

    Returns:
      self after changes are applied.
    """
    inherits = list(args)
    inherits.append(kwargs)

    for update_config in inherits:
      for name, value in update_config.iteritems():
        if callable(value):
          # If we are applying to a fixed value, we resolve to a fixed value.
          # Otherwise, we save off a callable to apply later, perhaps with
          # nested callables (IE: we curry them). This allows us to use
          # callables in templates, and apply templates to each other and still
          # get the expected result when we use them later on.
          #
          # Delaying the resolution of callables is safe, because "Add()" always
          # applies against the default, which has fixed values for everything.

          if name in self:
            # apply it to the current value.
            if callable(self[name]):
              # If we have no fixed value to resolve with, stack the callables.
              def stack(new_callable, old_callable):
                """Helper method to isolate namespace for closure."""
                return lambda fixed: new_callable(old_callable(fixed))

              self[name] = stack(value, self[name])
            else:
              # If the current value was a fixed value, apply the callable.
              self[name] = value(self[name])
          else:
            # If we had no value to apply it to, save it for later.
            self[name] = value

        elif name == '_template':
          # We never apply _template. You have to set it through Add.
          pass

        else:
          # Simple values overwrite whatever we do or don't have.
          self[name] = value

    return self

  def derive(self, *args, **kwargs):
    """Create a new config derived from this one.

    Note: If an override is callable, it will be called and passed the prior
    value for the given key (or None) to compute the new value.

    Args:
      args: Mapping instances to mixin.
      kwargs: Settings to inject; see DefaultSettings for valid values.

    Returns:
      A new _config instance.
    """
    return self.deepcopy().apply(*args, **kwargs)

  def AddSlave(self, slave):
    """Assign slave config(s) to a build master.

    A helper for adding slave configs to a master config.
    """
    assert self.master
    if self['slave_configs'] is None:
      self['slave_configs'] = []
    self.slave_configs.append(slave.name)
    self.slave_configs.sort()

  def AddSlaves(self, slaves):
    """Assign slave config(s) to a build master.

    A helper for adding slave configs to a master config.
    """
    assert self.master
    if self['slave_configs'] is None:
      self['slave_configs'] = []
    self.slave_configs.extend(slave_config.name for slave_config in slaves)
    self.slave_configs.sort()


class VMTestConfig(object):
  """Config object for virtual machine tests suites.

  Members:
    test_type: Test type to be run.
    timeout: Number of seconds to wait before timing out waiting for
             results.
  """
  DEFAULT_TEST_TIMEOUT = 60 * 60

  def __init__(self, test_type, timeout=DEFAULT_TEST_TIMEOUT):
    """Constructor -- see members above."""
    self.test_type = test_type
    self.timeout = timeout

  def __eq__(self, other):
    return self.__dict__ == other.__dict__


class GCETestConfig(object):
  """Config object for GCE tests suites.

  Members:
    test_type: Test type to be run.
    timeout: Number of seconds to wait before timing out waiting for
             results.
  """
  DEFAULT_TEST_TIMEOUT = 60 * 60

  def __init__(self, test_type, timeout=DEFAULT_TEST_TIMEOUT):
    """Constructor -- see members above."""
    self.test_type = test_type
    self.timeout = timeout

  def __eq__(self, other):
    return self.__dict__ == other.__dict__


class TastVMTestConfig(object):
  """Config object for a Tast virtual-machine-based test suite.

  Members:
    name: String containing short human-readable name describing test suite.
    test_exprs: List of string expressions describing which tests to run; this
                is passed directly to the 'tast run' command. See
                https://goo.gl/UPNEgT for info about test expressions.
    timeout: Number of seconds to wait before timing out waiting for
             results.
  """
  DEFAULT_TEST_TIMEOUT = 10 * 60

  def __init__(self, suite_name, test_exprs, timeout=DEFAULT_TEST_TIMEOUT):
    """Constructor -- see members above."""
    # This is an easy mistake to make and results in confusing errors later when
    # a list of one-character strings gets passed to the tast command.
    if not isinstance(test_exprs, list):
      raise TypeError('test_exprs must be list of strings')
    self.suite_name = suite_name
    self.test_exprs = test_exprs
    self.timeout = timeout

  def __eq__(self, other):
    return self.__dict__ == other.__dict__


class ModelTestConfig(object):
  """Model specific config that controls which test suites are executed.

  Members:
    name: The name of the model that will be tested (matches model label)
    lab_board_name: The name of the board in the lab (matches board label)
    test_suites: List of hardware test suites that will be executed.
  """
  def __init__(self, name, lab_board_name, test_suites=None):
    """Constructor -- see members above."""
    self.name = name
    self.lab_board_name = lab_board_name
    self.test_suites = test_suites

  def __eq__(self, other):
    return self.__dict__ == other.__dict__


class HWTestConfig(object):
  """Config object for hardware tests suites.

  Members:
    suite: Name of the test suite to run.
    timeout: Number of seconds to wait before timing out waiting for
             results.
    pool: Pool to use for hw testing.
    blocking: Setting this to true requires that this suite must PASS for suites
              scheduled after it to run. This also means any suites that are
              scheduled before a blocking one are also blocking ones scheduled
              after. This should be used when you want some suites to block
              whether or not others should run e.g. only run longer-running
              suites if some core ones pass first.

              Note, if you want multiple suites to block other suites but run
              in parallel, you should only mark the last one scheduled as
              blocking (it effectively serves as a thread/process join).
    async: Fire-and-forget suite.
    warn_only: Failure on HW tests warns only (does not generate error).
    critical: Usually we consider structural failures here as OK.
    priority:  Priority at which tests in the suite will be scheduled in
               the hw lab.
    file_bugs: Should we file bugs if a test fails in a suite run.
    num: Maximum number of DUTs to use when scheduling tests in the hw lab.
    minimum_duts: minimum number of DUTs required for testing in the hw lab.
    retry: Whether we should retry tests that fail in a suite run.
    max_retries: Integer, maximum job retries allowed at suite level.
                 None for no max.
    suite_min_duts: Preferred minimum duts. Lab will prioritize on getting such
                    number of duts even if the suite is competing with
                    other suites that have higher priority.
    suite_args: Arguments passed to the suite.  This should be a dict
                representing keyword arguments.  The value is marshalled
                using repr(), so the dict values should be basic types.

  Some combinations of member settings are invalid:
    * A suite config may not specify both blocking and async.
    * A suite config may not specify both warn_only and critical.
  """
  _MINUTE = 60
  _HOUR = 60 * _MINUTE
  # CTS timeout about 2 * expected runtime in case other tests are using the CTS
  # pool.
  CTS_QUAL_HW_TEST_TIMEOUT = int(48.0 * _HOUR)
  # GTS runs faster than CTS. But to avoid starving GTS by CTS we set both
  # timeouts equal.
  GTS_QUAL_HW_TEST_TIMEOUT = CTS_QUAL_HW_TEST_TIMEOUT
  SHARED_HW_TEST_TIMEOUT = int(3.0 * _HOUR)
  PALADIN_HW_TEST_TIMEOUT = int(1.5 * _HOUR)
  BRANCHED_HW_TEST_TIMEOUT = int(10.0 * _HOUR)

  # TODO(jrbarnette) Async HW test phases complete within seconds.
  # however, the tests they start can require hours to complete.
  # Chromite code doesn't distinguish "timeout for Autotest" from
  # timeout in the builder.  This is WRONG WRONG WRONG.  But, until
  # there's a better fix, we'll allow these phases hours to fail.
  ASYNC_HW_TEST_TIMEOUT = int(250.0 * _MINUTE)

  def __init__(self, suite,
               num=constants.HWTEST_DEFAULT_NUM,
               pool=constants.HWTEST_MACH_POOL,
               timeout=SHARED_HW_TEST_TIMEOUT,
               async=False,
               warn_only=False,
               critical=False,
               blocking=False,
               file_bugs=False,
               priority=constants.HWTEST_BUILD_PRIORITY,
               retry=True,
               max_retries=constants.HWTEST_MAX_RETRIES,
               minimum_duts=0,
               suite_min_duts=0,
               suite_args=None,
               offload_failures_only=False):
    """Constructor -- see members above."""
    assert not async or not blocking
    assert not warn_only or not critical
    self.suite = suite
    self.num = num
    self.pool = pool
    self.timeout = timeout
    self.blocking = blocking
    self.async = async
    self.warn_only = warn_only
    self.critical = critical
    self.file_bugs = file_bugs
    self.priority = priority
    self.retry = retry
    self.max_retries = max_retries
    self.minimum_duts = minimum_duts
    self.suite_min_duts = suite_min_duts
    self.suite_args = suite_args
    self.offload_failures_only = offload_failures_only

  def SetBranchedValues(self):
    """Changes the HW Test timeout/priority values to branched values."""
    self.timeout = max(HWTestConfig.BRANCHED_HW_TEST_TIMEOUT, self.timeout)

    # Set minimum_duts default to 0, which means that lab will not check the
    # number of available duts to meet the minimum requirement before creating
    # a suite job for branched build.
    self.minimum_duts = 0

    # Only reduce priority if it's lower.
    new_priority = constants.HWTEST_PRIORITIES_MAP[
        constants.HWTEST_DEFAULT_PRIORITY]
    if isinstance(self.priority, (int, long)):
      self.priority = min(self.priority, new_priority)
    elif constants.HWTEST_PRIORITIES_MAP[self.priority] > new_priority:
      self.priority = new_priority

  @property
  def timeout_mins(self):
    return int(self.timeout / 60)

  def __eq__(self, other):
    return self.__dict__ == other.__dict__


def DefaultSettings():
  # Enumeration of valid settings; any/all config settings must be in this.
  # All settings must be documented.
  return dict(
      # The name of the template we inherit settings from.
      _template=None,

      # The name of the config.
      name=None,

      # What type of builder is used for this build? This is a hint sent to
      # the waterfall code. It is ignored by the trybot waterfall.
      #   constants.VALID_BUILD_SLAVE_TYPES
      buildslave_type=constants.GCE_BEEFY_BUILD_SLAVE_TYPE,

      # A list of boards to build.
      boards=None,

      # A list of ModelTestConfig objects that represent all of the models
      # supported by a given unified build and their corresponding test config.
      models=[],

      # This value defines what part of the Golden Eye UI is responsible for
      # displaying builds of this build config. The value is required, and
      # must be in ALL_DISPLAY_LABEL.
      # TODO: Make the value required after crbug.com/776955 is finished.
      display_label=None,

      # The profile of the variant to set up and build.
      profile=None,

      # This bot pushes changes to the overlays.
      master=False,

      # If this bot triggers slave builds, this will contain a list of
      # slave config names.
      slave_configs=None,

      # If False, this flag indicates that the CQ should not check whether
      # this bot passed or failed. Set this to False if you are setting up a
      # new bot. Once the bot is on the waterfall and is consistently green,
      # mark the builder as important=True.
      important=False,

      # If True, build config should always be run as if --debug was set
      # on the cbuildbot command line. This is different from 'important'
      # and is usually correlated with tryjob build configs.
      debug=False,

      # Timeout for the build as a whole (in seconds).
      build_timeout=(4 * 60 + 30) * 60,

      # An integer. If this builder fails this many times consecutively, send
      # an alert email to the recipients health_alert_recipients. This does
      # not apply to tryjobs. This feature is similar to the ERROR_WATERMARK
      # feature of upload_symbols, and it may make sense to merge the features
      # at some point.
      health_threshold=0,

      # If this build_config fails this many times consecutively, trigger a
      # sanity-check build on this build_config. A sanity-check-pre-cq is a
      # pre-cq build without patched CLs.
      sanity_check_threshold=0,

      # List of email addresses to send health alerts to for this builder. It
      # supports automatic email address lookup for the following sheriff
      # types:
      #     'tree': tree sheriffs
      #     'chrome': chrome gardeners
      health_alert_recipients=[],

      # Whether this is an internal build config.
      internal=False,

      # Whether this is a branched build config. Used for pfq logic.
      branch=False,

      # The name of the manifest to use. E.g., to use the buildtools manifest,
      # specify 'buildtools'.
      manifest=constants.DEFAULT_MANIFEST,

      # The name of the manifest to use if we're building on a local trybot.
      # This should only require elevated access if it's really needed to
      # build this config.
      dev_manifest=constants.DEFAULT_MANIFEST,

      # Applies only to paladin builders. If true, Sync to the manifest
      # without applying any test patches, then do a fresh build in a new
      # chroot. Then, apply the patches and build in the existing chroot.
      build_before_patching=False,

      # Applies only to paladin builders. If True, Sync to the master manifest
      # without applying any of the test patches, rather than running
      # CommitQueueSync. This is basically ToT immediately prior to the
      # current commit queue run.
      do_not_apply_cq_patches=False,

      # Applies only to master builders. List of the names of slave builders
      # to be treated as sanity checkers. If only sanity check builders fail,
      # then the master will ignore the failures. In a CQ run, if any of the
      # sanity check builders fail and other builders fail as well, the master
      # will treat the build as failed, but will not reset the ready bit of
      # the tested patches.
      sanity_check_slaves=None,

      # emerge use flags to use while setting up the board, building packages,
      # making images, etc.
      useflags=[],

      # Set the variable CHROMEOS_OFFICIAL for the build. Known to affect
      # parallel_emerge, cros_set_lsb_release, and chromeos_version.sh. See
      # bug chromium-os:14649
      chromeos_official=False,

      # Use binary packages for building the toolchain. (emerge --getbinpkg)
      usepkg_toolchain=True,

      # Use binary packages for build_packages and setup_board.
      usepkg_build_packages=True,

      # If set, run BuildPackages in the background and allow subsequent
      # stages to run in parallel with this one.
      #
      # For each release group, the first builder should be set to run in the
      # foreground (to build binary packages), and the remainder of the
      # builders should be set to run in parallel (to install the binary
      # packages.)
      build_packages_in_background=False,

      # Only use binaries in build_packages for Chrome itself.
      chrome_binhost_only=False,

      # Does this profile need to sync chrome?  If None, we guess based on
      # other factors.  If True/False, we always do that.
      sync_chrome=None,

      # Use the newest ebuilds for all the toolchain packages.
      latest_toolchain=False,

      # This is only valid when latest_toolchain is True. If you set this to a
      # commit-ish, the gcc ebuild will use it to build the toolchain
      # compiler.
      gcc_githash=None,

      # Wipe and replace the board inside the chroot.
      board_replace=False,

      # Wipe and replace chroot, but not source.
      chroot_replace=True,

      # Uprevs the local ebuilds to build new changes since last stable.
      # build.  If master then also pushes these changes on success. Note that
      # we uprev on just about every bot config because it gives us a more
      # deterministic build system (the tradeoff being that some bots build
      # from source more frequently than if they never did an uprev). This way
      # the release/factory/etc... builders will pick up changes that devs
      # pushed before it runs, but after the correspoding PFQ bot ran (which
      # is what creates+uploads binpkgs).  The incremental bots are about the
      # only ones that don't uprev because they mimic the flow a developer
      # goes through on their own local systems.
      uprev=True,

      # Select what overlays to look at for revving and prebuilts. This can be
      # any constants.VALID_OVERLAYS.
      overlays=constants.PUBLIC_OVERLAYS,

      # Select what overlays to push at. This should be a subset of overlays
      # for the particular builder.  Must be None if not a master.  There
      # should only be one master bot pushing changes to each overlay per
      # branch.
      push_overlays=None,

      # Uprev Android, values of 'latest_release', or None.
      android_rev=None,

      # Which Android branch build do we try to uprev from.
      android_import_branch=None,

      # Android package name.
      android_package=None,

      # Android GTS package branch name, if it is necessary to uprev.
      android_gts_build_branch=None,

      # Uprev Chrome, values of 'tot', 'stable_release', or None.
      chrome_rev=None,

      # Exit the builder right after checking compilation.
      # TODO(mtennant): Should be something like "compile_check_only".
      compilecheck=False,

      # Test CLs to verify they're ready for the commit queue.
      pre_cq=False,

      # Runs the tests that the signer would run. This should only be set if
      # 'recovery' is in images.
      signer_tests=False,

      # Runs unittests for packages.
      unittests=True,

      # A list of the packages to blacklist from unittests.
      unittest_blacklist=[],

      # Generates AFDO data. Will capture a profile of chrome using a hwtest
      # to run a predetermined set of benchmarks.
      afdo_generate=False,

      # Generates AFDO data, builds the minimum amount of artifacts and
      # assumes a non-distributed builder (i.e.: the whole process in a single
      # builder).
      afdo_generate_min=False,

      # Update the Chrome ebuild with the AFDO profile info.
      afdo_update_ebuild=False,

      # Uses AFDO data. The Chrome build will be optimized using the AFDO
      # profile information found in the chrome ebuild file.
      afdo_use=False,

      # A list of VMTestConfig objects to run by default.
      vm_tests=[VMTestConfig(constants.SMOKE_SUITE_TEST_TYPE),
                VMTestConfig(constants.SIMPLE_AU_TEST_TYPE)],

      # A list of all VMTestConfig objects to use if VM Tests are forced on
      # (--vmtest command line or trybot). None means no override.
      vm_tests_override=None,

      # If true, in addition to upload vm test result to artifact folder, report
      # results to other dashboard as well.
      vm_test_report_to_dashboards=False,

      # The number of times to run the VMTest stage. If this is >1, then we
      # will run the stage this many times, stopping if we encounter any
      # failures.
      vm_test_runs=1,

      # A list of HWTestConfig objects to run.
      hw_tests=[],

      # A list of all HWTestConfig objects to use if HW Tests are forced on
      # (--hwtest command line or trybot). None means no override.
      hw_tests_override=None,

      # If true, uploads artifacts for hw testing. Upload payloads for test
      # image if the image is built. If not, dev image is used and then base
      # image.
      upload_hw_test_artifacts=True,

      # If true, uploads individual image tarballs.
      upload_standalone_images=True,

      # A list of GCETestConfig objects to use. Currently only some lakitu
      # builders run gce tests.
      gce_tests=[],

      # A list of TastVMTestConfig objects describing Tast-based test suites
      # that should be run in a VM.
      tast_vm_tests=[],

      # List of patterns for portage packages for which stripped binpackages
      # should be uploaded to GS. The patterns are used to search for packages
      # via `equery list`.
      upload_stripped_packages=[
          # Used by SimpleChrome workflow.
          'chromeos-base/chromeos-chrome',
          'sys-kernel/*kernel*',
      ],

      # Google Storage path to offload files to.
      #   None - No upload
      #   GS_PATH_DEFAULT - 'gs://chromeos-image-archive/' + bot_id
      #   value - Upload to explicit path
      gs_path=GS_PATH_DEFAULT,

      # TODO(sosa): Deprecate binary.
      # Type of builder.  Check constants.VALID_BUILD_TYPES.
      build_type=constants.PFQ_TYPE,

      # Whether to schedule test suites by suite_scheduler. Generally only
      # True for "release" builders.
      suite_scheduling=False,

      # The class name used to build this config.  See the modules in
      # cbuildbot / builders/*_builders.py for possible values.  This should
      # be the name in string form -- e.g. "simple_builders.SimpleBuilder" to
      # get the SimpleBuilder class in the simple_builders module.  If not
      # specified, we'll fallback to legacy probing behavior until everyone
      # has been converted (see the scripts/cbuildbot.py file for details).
      builder_class_name=None,

      # List of images we want to build -- see build_image for more details.
      images=['test'],

      # Image from which we will build update payloads.  Must either be None
      # or name one of the images in the 'images' list, above.
      payload_image=None,

      # Whether to build a netboot image.
      factory_install_netboot=True,

      # Whether to build the factory toolkit.
      factory_toolkit=True,

      # Whether to build factory packages in BuildPackages.
      factory=True,

      # Tuple of specific packages we want to build.  Most configs won't
      # specify anything here and instead let build_packages calculate.
      packages=[],

      # Do we push a final release image to chromeos-images.
      push_image=False,

      # Do we upload debug symbols.
      upload_symbols=False,

      # Whether we upload a hwqual tarball.
      hwqual=False,

      # Run a stage that generates release payloads for signed images.
      paygen=False,

      # If the paygen stage runs, generate tests, and schedule auto-tests for
      # them.
      paygen_skip_testing=False,

      # If the paygen stage runs, don't generate any delta payloads. This is
      # only done if deltas are broken for a given board.
      paygen_skip_delta_payloads=False,

      # Run a stage that generates and uploads package CPE information.
      cpe_export=True,

      # Run a stage that generates and uploads debug symbols.
      debug_symbols=True,

      # Do not package the debug symbols in the binary package. The debug
      # symbols will be in an archive with the name cpv.debug.tbz2 in
      # /build/${BOARD}/packages and uploaded with the prebuilt.
      separate_debug_symbols=True,

      # Include *.debug files for debugging core files with gdb in debug.tgz.
      # These are very large. This option only has an effect if debug_symbols
      # and archive are set.
      archive_build_debug=False,

      # Run a stage that archives build and test artifacts for developer
      # consumption.
      archive=True,

      # Git repository URL for our manifests.
      #  https://chromium.googlesource.com/chromiumos/manifest
      #  https://chrome-internal.googlesource.com/chromeos/manifest-internal
      manifest_repo_url=None,

      # Whether we are using the manifest_version repo that stores per-build
      # manifests.
      manifest_version=False,

      # Use a different branch of the project manifest for the build.
      manifest_branch=None,

      # Use the Last Known Good Manifest blessed by Paladin.
      use_lkgm=False,

      # If we use_lkgm -- What is the name of the manifest to look for?
      lkgm_manifest=constants.LKGM_MANIFEST,

      # LKGM for Chrome OS generated for Chrome builds that are blessed from
      # canary runs.
      use_chrome_lkgm=False,

      # True if this build config is critical for the chrome_lkgm decision.
      critical_for_chrome=False,

      # Upload prebuilts for this build. Valid values are PUBLIC, PRIVATE, or
      # False.
      prebuilts=False,

      # Use SDK as opposed to building the chroot from source.
      use_sdk=True,

      # List this config when user runs cbuildbot with --list option without
      # the --all flag.
      trybot_list=False,

      # The description string to print out for config when user runs --list.
      description=None,

      # Boolean that enables parameter --git-sync for upload_prebuilts.
      git_sync=False,

      # A list of the child config groups, if applicable. See the AddGroup
      # method.
      child_configs=[],

      # Set shared user password for "chronos" user in built images. Use
      # "None" (default) to remove the shared user password. Note that test
      # images will always set the password to "test0000".
      shared_user_password=None,

      # Whether this config belongs to a config group.
      grouped=False,

      # layout of build_image resulting image. See
      # scripts/build_library/legacy_disk_layout.json or
      # overlay-<board>/scripts/disk_layout.json for possible values.
      disk_layout=None,

      # If enabled, run the PatchChanges stage.  Enabled by default. Can be
      # overridden by the --nopatch flag.
      postsync_patch=True,

      # Reexec into the buildroot after syncing.  Enabled by default.
      postsync_reexec=True,

      # Create delta sysroot during ArchiveStage. Disabled by default.
      create_delta_sysroot=False,

      # Run the binhost_test stage. Only makes sense for builders that have no
      # boards.
      binhost_test=False,

      # Run the BranchUtilTestStage. Useful for builders that publish new
      # manifest versions that we may later want to branch off of.
      branch_util_test=False,

      # If specified, it is passed on to the PushImage script as '--sign-types'
      # commandline argument.  Must be either None or a list of image types.
      sign_types=None,

      # TODO(sosa): Collapse to one option.
      # ========== Dev installer prebuilts options =======================

      # Upload prebuilts for this build to this bucket. If it equals None the
      # default buckets are used.
      binhost_bucket=None,

      # Parameter --key for upload_prebuilts. If it equals None, the default
      # values are used, which depend on the build type.
      binhost_key=None,

      # Parameter --binhost-base-url for upload_prebuilts. If it equals None,
      # the default value is used.
      binhost_base_url=None,

      # Upload dev installer prebuilts.
      dev_installer_prebuilts=False,

      # Enable rootfs verification on the image.
      rootfs_verification=True,

      # Build the Chrome SDK.
      chrome_sdk=False,

      # If chrome_sdk is set to True, this determines whether we attempt to
      # build Chrome itself with the generated SDK.
      chrome_sdk_build_chrome=True,

      # If chrome_sdk is set to True, this determines whether we use goma to
      # build chrome.
      chrome_sdk_goma=True,

      # Run image tests. This should only be set if 'base' is in our list of
      # images.
      image_test=False,

      # ==================================================================
      # The documentation associated with the config.
      doc=None,

      # ==================================================================
      # Hints to Buildbot master UI

      # If set, tells buildbot what name to give to the corresponding builder
      # on its waterfall.
      buildbot_waterfall_name=None,

      # If not None, the name (in waterfall.CIDB_KNOWN_WATERFALLS) of the
      # waterfall that this target should be active on.
      active_waterfall=None,

      # If true, skip package retries in BuildPackages step.
      nobuildretry=False,

      # If false, turn off rebooting between builds
      auto_reboot=True,
  )


def GerritInstanceParameters(name, instance, defaults=False):
  GOB_HOST = '%s.googlesource.com'
  param_names = ['_GOB_INSTANCE', '_GERRIT_INSTANCE', '_GOB_HOST',
                 '_GERRIT_HOST', '_GOB_URL', '_GERRIT_URL']
  if defaults:
    return dict([('%s%s' % (name, x), None) for x in param_names])

  gob_instance = instance
  gerrit_instance = '%s-review' % instance
  gob_host = GOB_HOST % gob_instance
  gerrit_host = GOB_HOST % gerrit_instance
  gob_url = 'https://%s' % gob_host
  gerrit_url = 'https://%s' % gerrit_host

  params = [gob_instance, gerrit_instance, gob_host, gerrit_host,
            gob_url, gerrit_url]

  return dict([('%s%s' % (name, pn), p) for pn, p in zip(param_names, params)])


def DefaultSiteParameters():
  # Enumeration of valid site parameters; any/all site parameters must be here.
  # All site parameters should be documented.
  default_site_params = {}

  # Helper variables for defining site parameters.
  gob_host = '%s.googlesource.com'

  external_remote = 'cros'
  internal_remote = 'cros-internal'
  chromium_remote = 'chromium'
  chrome_remote = 'chrome'

  internal_change_prefix = '*'
  external_change_prefix = ''

  # Gerrit instance site parameters.
  default_site_params.update(GOB_HOST=gob_host)
  default_site_params.update(
      GerritInstanceParameters('EXTERNAL', 'chromium'))
  default_site_params.update(
      GerritInstanceParameters('INTERNAL', 'chrome-internal'))
  default_site_params.update(
      GerritInstanceParameters('AOSP', 'android', defaults=True))
  default_site_params.update(
      GerritInstanceParameters('WEAVE', 'weave', defaults=True))

  default_site_params.update(
      # Parameters to define which manifests to use.
      MANIFEST_PROJECT=None,
      MANIFEST_INT_PROJECT=None,
      MANIFEST_PROJECTS=None,
      MANIFEST_URL=None,
      MANIFEST_INT_URL=None,

      # CrOS remotes specified in the manifests.
      EXTERNAL_REMOTE=external_remote,
      INTERNAL_REMOTE=internal_remote,
      GOB_REMOTES=None,
      KAYLE_INTERNAL_REMOTE=None,
      CHROMIUM_REMOTE=None,
      CHROME_REMOTE=None,
      AOSP_REMOTE=None,
      WEAVE_REMOTE=None,

      # Only remotes listed in CROS_REMOTES are considered branchable.
      # CROS_REMOTES and BRANCHABLE_PROJECTS must be kept in sync.
      GERRIT_HOSTS={
          external_remote: default_site_params['EXTERNAL_GERRIT_HOST'],
          internal_remote: default_site_params['INTERNAL_GERRIT_HOST']
      },
      CROS_REMOTES={
          external_remote: default_site_params['EXTERNAL_GOB_URL'],
          internal_remote: default_site_params['INTERNAL_GOB_URL']
      },
      GIT_REMOTES={
          chromium_remote: default_site_params['EXTERNAL_GOB_URL'],
          chrome_remote: default_site_params['INTERNAL_GOB_URL'],
          external_remote: default_site_params['EXTERNAL_GOB_URL'],
          internal_remote: default_site_params['INTERNAL_GOB_URL'],
      },

      # Prefix to distinguish internal and external changes. This is used
      # when a user specifies a patch with "-g", when generating a key for
      # a patch to use in our PatchCache, and when displaying a custom
      # string for the patch.
      INTERNAL_CHANGE_PREFIX=internal_change_prefix,
      EXTERNAL_CHANGE_PREFIX=external_change_prefix,
      CHANGE_PREFIX={
          external_remote: internal_change_prefix,
          internal_remote: external_change_prefix
      },

      # List of remotes that are okay to include in the external manifest.
      EXTERNAL_REMOTES=None,

      # Mapping 'remote name' -> regexp that matches names of repositories on
      # that remote that can be branched when creating CrOS branch.
      # Branching script will actually create a new git ref when branching
      # these projects. It won't attempt to create a git ref for other projects
      # that may be mentioned in a manifest. If a remote is missing from this
      # dictionary, all projects on that remote are considered to not be
      # branchable.
      BRANCHABLE_PROJECTS={
          external_remote: r'(chromiumos|aosp)/(.+)',
          internal_remote: r'chromeos/(.+)'
      },

      # Additional parameters used to filter manifests, create modified
      # manifests, and to branch manifests.
      MANIFEST_VERSIONS_GOB_URL=None,
      MANIFEST_VERSIONS_GOB_URL_TEST=None,
      MANIFEST_VERSIONS_INT_GOB_URL=None,
      MANIFEST_VERSIONS_INT_GOB_URL_TEST=None,
      MANIFEST_VERSIONS_GS_URL=None,

      # Standard directories under buildroot for cloning these repos.
      EXTERNAL_MANIFEST_VERSIONS_PATH=None,
      INTERNAL_MANIFEST_VERSIONS_PATH=None,

      # URL of the repo project.
      REPO_URL='https://chromium.googlesource.com/external/repo',

      # GS URL in which to archive build artifacts.
      ARCHIVE_URL='gs://chromeos-image-archive',
  )

  return default_site_params


class SiteParameters(dict):
  """This holds the site-wide configuration parameters for a SiteConfig."""

  def __getattr__(self, name):
    """Support attribute-like access to each SiteValue entry."""
    if name in self:
      return self[name]

    return super(SiteParameters, self).__getattribute__(name)

  @classmethod
  def HideDefaults(cls, site_params):
    """Hide default valued site parameters.

    Args:
      site_params: A dictionary of site parameters.

    Returns:
      A dictionary of site parameters containing only non-default
      valued entries.
    """
    defaults = DefaultSiteParameters()
    return {k: v for k, v in site_params.iteritems() if defaults.get(k) != v}


class SiteConfig(dict):
  """This holds a set of named BuildConfig values."""

  def __init__(self, defaults=None, templates=None, site_params=None):
    """Init.

    Args:
      defaults: Dictionary of key value pairs to use as BuildConfig values.
                All BuildConfig values should be defined here. If None,
                the DefaultSettings() is used. Most sites should use
                DefaultSettings(), and then update to add any site specific
                values needed.
      templates: Dictionary of template names to partial BuildConfigs
                 other BuildConfigs can be based on. Mostly used to reduce
                 verbosity of the config dump file format.
      site_params: Dictionary of site-wide configuration parameters. Keys
                   of the site_params dictionary should be strings.
    """
    super(SiteConfig, self).__init__()
    self._defaults = DefaultSettings()
    if defaults:
      self._defaults.update(defaults)
    self._templates = AttrDict() if templates is None else AttrDict(templates)
    self._site_params = DefaultSiteParameters()
    if site_params:
      self._site_params.update(site_params)

  def GetDefault(self):
    """Create the canonical default build configuration."""
    # Enumeration of valid settings; any/all config settings must be in this.
    # All settings must be documented.
    return BuildConfig(**self._defaults)

  def GetTemplates(self):
    """Get the templates of the build configs"""
    return self._templates

  @property
  def templates(self):
    return self._templates

  @property
  def params(self):
    """Get the site-wide configuration parameters."""
    return SiteParameters(**self._site_params)

  #
  # Methods for searching a SiteConfig's contents.
  #
  def GetBoards(self):
    """Return an iterable of all boards in the SiteConfig."""
    return set(itertools.chain.from_iterable(
        x.boards for x in self.itervalues() if x.boards))

  def FindFullConfigsForBoard(self, board=None):
    """Returns full builder configs for a board.

    Args:
      board: The board to match. By default, match all boards.

    Returns:
      A tuple containing a list of matching external configs and a list of
      matching internal release configs for a board.
    """
    ext_cfgs = []
    int_cfgs = []

    for name, c in self.iteritems():
      if c['boards'] and (board is None or board in c['boards']):
        if (name.endswith('-%s' % CONFIG_TYPE_RELEASE) and
            c['internal']):
          int_cfgs.append(c.deepcopy())
        elif (name.endswith('-%s' % CONFIG_TYPE_FULL) and
              not c['internal']):
          ext_cfgs.append(c.deepcopy())

    return ext_cfgs, int_cfgs

  def FindCanonicalConfigForBoard(self, board, allow_internal=True):
    """Get the canonical cbuildbot builder config for a board."""
    ext_cfgs, int_cfgs = self.FindFullConfigsForBoard(board)
    # If both external and internal builds exist for this board, prefer the
    # internal one unless instructed otherwise.
    both = (int_cfgs if allow_internal else []) + ext_cfgs

    if not both:
      raise ValueError('Invalid board specified: %s.' % board)
    return both[0]

  def GetSlaveConfigMapForMaster(self, master_config, options=None,
                                 important_only=True):
    """Gets the slave builds triggered by a master config.

    If a master builder also performs a build, it can (incorrectly) return
    itself.

    Args:
      master_config: A build config for a master builder.
      options: The options passed on the commandline. This argument is required
      for normal operation, but we accept None to assist with testing.
      important_only: If True, only get the important slaves.

    Returns:
      A slave_name to slave_config map, corresponding to the slaves for the
      master represented by master_config.

    Raises:
      AssertionError if the given config is not a master config or it does
        not have a manifest_version.
    """
    assert master_config.manifest_version
    assert master_config.master
    assert master_config.slave_configs is not None

    slave_name_config_map = {}
    if options is not None and options.remote_trybot:
      return {}

    # Look up the build configs for all slaves named by the master.
    slave_name_config_map = {
        name: self[name] for name in master_config.slave_configs
    }

    if important_only:
      # Remove unimportant configs from the result.
      slave_name_config_map = {
          k: v for k, v in slave_name_config_map.iteritems() if v.important
      }

    return slave_name_config_map

  def GetSlavesForMaster(self, master_config, options=None,
                         important_only=True):
    """Get a list of qualified build slave configs given the master_config.

    Args:
      master_config: A build config for a master builder.
      options: The options passed on the commandline. This argument is optional,
               and only makes sense when called from cbuildbot.
      important_only: If True, only get the important slaves.
    """
    slave_map = self.GetSlaveConfigMapForMaster(
        master_config, options=options, important_only=important_only)
    return slave_map.values()

  #
  # Methods used when creating a Config programatically.
  #
  def Add(self, name, template=None, *args, **kwargs):
    """Add a new BuildConfig to the SiteConfig.

    Example usage:
      # Creates default build named foo.
      site_config.Add('foo')

      # Creates default build with board 'foo_board'
      site_config.Add('foo',
                      boards=['foo_board'])

      # Creates build based on template_build for 'foo_board'.
      site_config.Add('foo',
                      template_build,
                      boards=['foo_board'])

      # Creates build based on template for 'foo_board'. with mixin.
      # Inheritance order is default, template, mixin, arguments.
      site_config.Add('foo',
                      template_build,
                      mixin_build_config,
                      boards=['foo_board'])

      # Creates build without a template but with mixin.
      # Inheritance order is default, template, mixin, arguments.
      site_config.Add('foo',
                      None,
                      mixin_build_config,
                      boards=['foo_board'])

    Args:
      name: The name to label this configuration; this is what cbuildbot
            would see.
      template: BuildConfig to use as a template for this build.
      args: BuildConfigs to patch into this config. First one (if present) is
            considered the template. See AddTemplate for help on templates.
      kwargs: BuildConfig values to explicitly set on this config.

    Returns:
      The BuildConfig just added to the SiteConfig.
    """
    assert name not in self, ('%s already exists.' % name)

    inherits, overrides = args, kwargs
    if template:
      inherits = (template,) + inherits

    # Make sure we don't ignore that argument silently.
    if '_template' in overrides:
      raise ValueError('_template cannot be explicitly set.')

    result = self.GetDefault()
    result.apply(*inherits, **overrides)

    # Select the template name based on template argument, or nothing.
    resolved_template = template.get('_template') if template else None
    assert not resolved_template or resolved_template in self.templates, \
        '%s inherits from non-template %s' % (name, resolved_template)

    # Our name is passed as an explicit argument. We use the first build
    # config as our template, or nothing.
    result['name'] = name
    result['_template'] = resolved_template
    self[name] = result
    return result

  def AddWithoutTemplate(self, name, *args, **kwargs):
    """Add a config containing only explicitly listed values (no defaults)."""
    self.Add(name, None, *args, **kwargs)

  def AddGroup(self, name, *args, **kwargs):
    """Create a new group of build configurations.

    Args:
      name: The name to label this configuration; this is what cbuildbot
            would see.
      args: Configurations to build in this group. The first config in
            the group is considered the primary configuration and is used
            for syncing and creating the chroot.
      kwargs: Override values to use for the parent config.

    Returns:
      A new BuildConfig instance.
    """
    child_configs = [x.deepcopy().apply(grouped=True) for x in args]
    return self.Add(name, args[0], child_configs=child_configs, **kwargs)

  def AddForBoards(self, suffix, boards, per_board=None,
                   template=None, *args, **kwargs):
    """Create configs for all boards in |boards|.

    Args:
      suffix: Config name is <board>-<suffix>.
      boards: A list of board names as strings.
      per_board: A dictionary of board names to BuildConfigs, or None.
      template: The template to use for all configs created.
      *args: Mixin templates to apply.
      **kwargs: Additional keyword arguments to be used in AddConfig.

    Returns:
      List of the configs created.
    """
    result = []

    for board in boards:
      config_name = '%s-%s' % (board, suffix)

      # Insert the per_board value as the last mixin, if it exists.
      mixins = args + (dict(boards=[board]),)
      if per_board and board in per_board:
        mixins = mixins + (per_board[board],)

      # Create the new config for this board.
      result.append(
          self.Add(config_name, template, *mixins, **kwargs))

    return result

  def AddTemplate(self, name, *args, **kwargs):
    """Create a template named |name|.

    Templates are used to define common settings that are shared across types
    of builders. They help reduce duplication in config_dump.json, because we
    only define the template and its settings once.

    Args:
      name: The name of the template.
      args: See the docstring of BuildConfig.derive.
      kwargs: See the docstring of BuildConfig.derive.
    """
    assert name not in self._templates, ('Template %s already exists.' % name)

    template = BuildConfig()
    template.apply(*args, **kwargs)
    template['_template'] = name
    self._templates[name] = template

    return template

  def _MarshalBuildConfig(self, name, config):
    """Hide the defaults from a given config entry.

    Args:
      name: Default build name (usually dictionary key).
      config: A config entry.

    Returns:
      The same config entry, but without any defaults.
    """
    defaults = self.GetDefault()
    defaults['name'] = name

    template = config.get('_template')
    if template:
      defaults.apply(self._templates[template])
      defaults['_template'] = None

    result = {}
    for k, v in config.iteritems():
      if defaults.get(k) != v:
        if k == 'child_configs':
          result['child_configs'] = [self._MarshalBuildConfig(name, child)
                                     for child in v]
        else:
          result[k] = v

    return result

  def _MarshalTemplates(self):
    """Return a version of self._templates with only used templates.

    Templates have callables/delete keys resolved against GetDefault() to
    ensure they can be safely saved to json.

    Returns:
      Dict copy of self._templates with all unreferenced templates removed.
    """
    defaults = self.GetDefault()

    # All templates used. We ignore child configs since they
    # should exist at top level.
    used = set(c.get('_template', None) for c in self.itervalues())
    used.discard(None)

    result = {}

    for name in used:
      # Expand any special values (callables, etc)
      expanded = defaults.derive(self._templates[name])
      # Recover the '_template' value which is filtered out by derive.
      expanded['_template'] = name
      # Hide anything that matches the default.
      save = {k: v for k, v in expanded.iteritems() if defaults.get(k) != v}
      result[name] = save

    return result

  def SaveConfigToString(self):
    """Save this Config object to a Json format string."""
    default = self.GetDefault()
    site_params = self.params

    config_dict = {}
    config_dict['_default'] = default
    config_dict['_templates'] = self._MarshalTemplates()
    config_dict['_site_params'] = SiteParameters.HideDefaults(site_params)
    for k, v in self.iteritems():
      config_dict[k] = self._MarshalBuildConfig(k, v)

    return PrettyJsonDict(config_dict)

  def SaveConfigToFile(self, config_file):
    """Save this Config to a Json file.

    Args:
      config_file: The file to write too.
    """
    json_string = self.SaveConfigToString()
    osutils.WriteFile(config_file, json_string)

  def DumpExpandedConfigToString(self):
    """Dump the SiteConfig to Json with all configs full expanded.

    This is intended for debugging default/template behavior. The dumped JSON
    can't be reloaded (at least not reliably).
    """
    return PrettyJsonDict(self)

#
# Methods related to working with GE Data.
#

def LoadGEBuildConfigFromFile(
    build_settings_file=constants.GE_BUILD_CONFIG_FILE):
  """Load template config dict from a Json encoded file."""
  json_string = osutils.ReadFile(build_settings_file)
  return json.loads(json_string)


def GeBuildConfigAllBoards(ge_build_config):
  """Extract a list of board names from the GE Build Config.

  Args:
    ge_build_config: Dictionary containing the decoded GE configuration file.

  Returns:
    A list of board names as strings.
  """
  return [b['name'] for b in ge_build_config['boards']]

def GetUnifiedBuildConfigAllBuilds(ge_build_config):
  """Extract a list of all unified build configurations.

  This dictionary is based on the JSON defined by the proto generated from
  GoldenEye.  See cs/crosbuilds.proto

  Args:
    ge_build_config: Dictionary containing the decoded GE configuration file.

  Returns:
    A list of unified build configurations (json configs)
  """
  return ge_build_config.get('reference_board_unified_builds', [])

class BoardGroup(object):
  """Class holds leader_boards and follower_boards for grouped boards"""

  def __init__(self):
    self.leader_boards = []
    self.follower_boards = []

  def AddLeaderBoard(self, board):
    self.leader_boards.append(board)

  def AddFollowerBoard(self, board):
    self.follower_boards.append(board)

  def __str__(self):
    return ('Leader_boards: %s Follower_boards: %s' %
            (self.leader_boards, self.follower_boards))

def GroupBoardsByBuilderAndBoardGroup(board_list):
  """Group boards by builder and board_group.

  Args:
    board_list: board list from the template file.

  Returns:
    builder_group_dict: maps builder to {group_n: board_group_n}
    builder_ungrouped_dict: maps builder to a list of ungrouped boards
  """
  builder_group_dict = {}
  builder_ungrouped_dict = {}

  for b in board_list:
    name = b[CONFIG_TEMPLATE_NAME]
    for config in b[CONFIG_TEMPLATE_CONFIGS]:
      board = {'name': name}
      board.update(config)

      builder = config[CONFIG_TEMPLATE_BUILDER]
      if builder not in builder_group_dict:
        builder_group_dict[builder] = {}
      if builder not in builder_ungrouped_dict:
        builder_ungrouped_dict[builder] = []

      board_group = config[CONFIG_TEMPLATE_BOARD_GROUP]
      if not board_group:
        builder_ungrouped_dict[builder].append(board)
        continue
      if board_group not in builder_group_dict[builder]:
        builder_group_dict[builder][board_group] = BoardGroup()
      if config[CONFIG_TEMPLATE_LEADER_BOARD]:
        builder_group_dict[builder][board_group].AddLeaderBoard(board)
      else:
        builder_group_dict[builder][board_group].AddFollowerBoard(board)

  return (builder_group_dict, builder_ungrouped_dict)


def GroupBoardsByBuilder(board_list):
  """Group boards by the 'builder' flag."""
  builder_to_boards_dict = {}

  for b in board_list:
    for config in b[CONFIG_TEMPLATE_CONFIGS]:
      builder = config[CONFIG_TEMPLATE_BUILDER]
      if builder not in builder_to_boards_dict:
        builder_to_boards_dict[builder] = set()
      builder_to_boards_dict[builder].add(b[CONFIG_TEMPLATE_NAME])

  return builder_to_boards_dict

def GetArchBoardDict(ge_build_config):
  """Get a dict mapping arch types to board names.

  Args:
    ge_build_config: Dictionary containing the decoded GE configuration file.

  Returns:
    A dict mapping arch types to board names.
  """
  arch_board_dict = {}

  for b in ge_build_config[CONFIG_TEMPLATE_BOARDS]:
    board_name = b[CONFIG_TEMPLATE_NAME]
    for config in b[CONFIG_TEMPLATE_CONFIGS]:
      arch = config[CONFIG_TEMPLATE_ARCH]
      arch_board_dict.setdefault(arch, set()).add(board_name)

  for b in GetUnifiedBuildConfigAllBuilds(ge_build_config):
    board_name = b[CONFIG_TEMPLATE_REFERENCE_BOARD_NAME]
    arch = b[CONFIG_TEMPLATE_ARCH]
    arch_board_dict.setdefault(arch, set()).add(board_name)

  return arch_board_dict

#
# Methods related to loading/saving Json.
#
class ObjectJSONEncoder(json.JSONEncoder):
  """Json Encoder that encodes objects as their dictionaries."""
  # pylint: disable=method-hidden
  def default(self, obj):
    return self.encode(obj.__dict__)


def PrettyJsonDict(dictionary):
  """Returns a pretty-ified json dump of a dictionary."""
  return json.dumps(dictionary, cls=ObjectJSONEncoder,
                    sort_keys=True, indent=4, separators=(',', ': '))


def LoadConfigFromFile(config_file=constants.CHROMEOS_CONFIG_FILE):
  """Load a Config a Json encoded file."""
  json_string = osutils.ReadFile(config_file)
  return LoadConfigFromString(json_string)


def LoadConfigFromString(json_string):
  """Load a cbuildbot config from it's Json encoded string."""
  config_dict = json.loads(json_string)

  # Use standard defaults, but allow the config to override.
  defaults = DefaultSettings()
  defaults.update(config_dict.pop(DEFAULT_BUILD_CONFIG))
  _DeserializeTestConfigs(defaults)

  templates = config_dict.pop('_templates', {})
  for t in templates.itervalues():
    _DeserializeTestConfigs(t)

  site_params = DefaultSiteParameters()
  site_params.update(config_dict.pop('_site_params', {}))

  defaultBuildConfig = BuildConfig(**defaults)

  builds = {n: _CreateBuildConfig(n, defaultBuildConfig, v, templates)
            for n, v in config_dict.iteritems()}

  # config is the struct that holds the complete cbuildbot config.
  result = SiteConfig(defaults=defaults, templates=templates,
                      site_params=site_params)
  result.update(builds)

  return result


def _DeserializeTestConfig(build_dict, config_key, test_class,
                           preserve_none=False):
  """Deserialize test config of given type inside build_dict.

  Args:
    build_dict: The build_dict to update (in place)
    config_key: Key for the config inside build_dict.
    test_class: The class to instantiate for the config.
    preserve_none: If True, None values are preserved as is. By default, they
        are dropped.
  """
  serialized_test_configs = build_dict.pop(config_key, None)
  if serialized_test_configs is None:
    if preserve_none:
      build_dict[config_key] = None
    return

  test_configs = []
  for test_config_string in serialized_test_configs:
    if isinstance(test_config_string, test_class):
      test_config = test_config_string
    else:
      # Each test config is dumped as a json string embedded in json.
      embedded_configs = json.loads(test_config_string)
      test_config = test_class(**embedded_configs)
    test_configs.append(test_config)
  build_dict[config_key] = test_configs


def _DeserializeTestConfigs(build_dict):
  """Updates a config dictionary with recreated objects.

  Various test configs are serialized as strings (rather than JSON objects), so
  we need to turn them into real objects before they can be consumed.

  Args:
    build_dict: The config dictionary to update (in place).
  """
  _DeserializeTestConfig(build_dict, 'vm_tests', VMTestConfig)
  _DeserializeTestConfig(build_dict, 'vm_tests_override', VMTestConfig,
                         preserve_none=True)
  _DeserializeTestConfig(build_dict, 'models', ModelTestConfig)
  _DeserializeTestConfig(build_dict, 'hw_tests', HWTestConfig)
  _DeserializeTestConfig(build_dict, 'hw_tests_override', HWTestConfig,
                         preserve_none=True)
  _DeserializeTestConfig(build_dict, 'gce_tests', GCETestConfig)
  _DeserializeTestConfig(build_dict, 'tast_vm_tests', TastVMTestConfig)


def _CreateBuildConfig(name, default, build_dict, templates):
  """Create a BuildConfig object from it's parsed JSON dictionary encoding."""
  # These build config values need special handling.
  child_configs = build_dict.pop('child_configs', None)
  template = build_dict.get('_template')

  # Use the name passed in as the default build name.
  build_dict.setdefault('name', name)

  result = default.deepcopy()
  # Use update to explicitly avoid apply's special handing.
  if template:
    result.update(templates[template])
  result.update(build_dict)

  _DeserializeTestConfigs(result)

  if child_configs is not None:
    result['child_configs'] = [
        _CreateBuildConfig(name, default, child, templates)
        for child in child_configs
    ]

  return result


def ClearConfigCache():
  """Clear the currently cached SiteConfig.

  This is intended to be used very early in the startup, after we fetch/update
  the site config information available to us.

  However, this operation is never 100% safe, since the Chrome OS config, or an
  outdated config was availble to any code that ran before (including on
  import), and that code might have used or cached related values.
  """
  # pylint: disable=global-statement
  global _CACHED_CONFIG
  _CACHED_CONFIG = None


def GetConfig():
  """Load the current SiteConfig.

  Returns:
    SiteConfig instance to use for this build.
  """
  # pylint: disable=global-statement
  global _CACHED_CONFIG

  if _CACHED_CONFIG is None:
    if os.path.exists(constants.SITE_CONFIG_FILE):
      # Use a site specific config, if present.
      filename = constants.SITE_CONFIG_FILE
    else:
      # Fall back to default Chrome OS configuration.
      filename = constants.CHROMEOS_CONFIG_FILE

    _CACHED_CONFIG = LoadConfigFromFile(filename)

  return _CACHED_CONFIG
