# -*- coding: utf-8 -*-
# Copyright (c) 2012 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.

"""The cros chrome-sdk command for the simple chrome workflow."""

from __future__ import print_function

import argparse
import collections
import contextlib
import glob
import json
import os
import re

from chromite.cbuildbot import archive_lib
from chromite.cli import command
from chromite.lib import cache
from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import gs
from chromite.lib import memoize
from chromite.lib import osutils
from chromite.lib import path_util
from chromite.lib import retry_util
from gn_helpers import gn_helpers


COMMAND_NAME = 'chrome-sdk'
CUSTOM_VERSION = 'custom'


def Log(*args, **kwargs):
  """Conditional logging.

  Args:
    silent: If set to True, then logs with level DEBUG.  logs with level INFO
      otherwise.  Defaults to False.
  """
  silent = kwargs.pop('silent', False)
  level = logging.DEBUG if silent else logging.INFO
  logging.log(level, *args, **kwargs)


class NoChromiumSrcDir(Exception):
  """Error thrown when no chromium src dir is found."""

  def __init__(self, path):
    Exception.__init__(self, 'No chromium src dir found in: %s' % (path))

class MissingLKGMFile(Exception):
  """Error thrown when we cannot get the version from CHROMEOS_LKGM."""

  def __init__(self, path):
    Exception.__init__(self, 'Cannot parse CHROMEOS_LKGM file: %s' % (path))

class MissingSDK(Exception):
  """Error thrown when we cannot find an SDK."""

  def __init__(self, board, version=None):
    msg = 'Cannot find SDK for %r' % (board,)
    if version is not None:
      msg += ' with version %s' % (version,)
    Exception.__init__(self, msg)


class SDKFetcher(object):
  """Functionality for fetching an SDK environment.

  For the version of ChromeOS specified, the class downloads and caches
  SDK components.
  """
  SDK_BOARD_ENV = '%SDK_BOARD'
  SDK_PATH_ENV = '%SDK_PATH'
  SDK_VERSION_ENV = '%SDK_VERSION'

  SDKContext = collections.namedtuple(
      'SDKContext', ['version', 'target_tc', 'key_map'])

  TARBALL_CACHE = 'tarballs'
  MISC_CACHE = 'misc'

  TARGET_TOOLCHAIN_KEY = 'target_toolchain'
  QEMU_BIN_PATH = 'app-emulation/qemu'
  SEABIOS_BIN_PATH = 'sys-firmware/seabios'
  TAST_CMD_PATH = 'chromeos-base/tast-cmd'
  TAST_REMOTE_TESTS_PATH = 'chromeos-base/tast-remote-tests-cros'

  CANARIES_PER_DAY = 3
  DAYS_TO_CONSIDER = 14
  VERSIONS_TO_CONSIDER = DAYS_TO_CONSIDER * CANARIES_PER_DAY

  def __init__(self, cache_dir, board, clear_cache=False, chrome_src=None,
               sdk_path=None, toolchain_path=None, silent=False,
               use_external_config=None, require_exact_version=False):
    """Initialize the class.

    Args:
      cache_dir: The toplevel cache dir to use.
      board: The board to manage the SDK for.
      clear_cache: Clears the sdk cache during __init__.
      chrome_src: The location of the chrome checkout.  If unspecified, the
        cwd is presumed to be within a chrome checkout.
      sdk_path: The path (whether a local directory or a gs:// path) to fetch
        SDK components from.
      toolchain_path: The path (whether a local directory or a gs:// path) to
        fetch toolchain components from.
      silent: If set, the fetcher prints less output.
      use_external_config: When identifying the configuration for a board,
        force usage of the external configuration if both external and internal
        are available.
      require_exact_version: Use exact SDK version only.
    """
    site_config = config_lib.GetConfig()

    self.cache_base = os.path.join(cache_dir, COMMAND_NAME)
    if clear_cache:
      logging.warning('Clearing the SDK cache.')
      osutils.RmDir(self.cache_base, ignore_missing=True)
      self._RemoveOldCacheDir()
    self.tarball_cache = cache.TarballCache(
        os.path.join(self.cache_base, self.TARBALL_CACHE))
    self.misc_cache = cache.DiskCache(
        os.path.join(self.cache_base, self.MISC_CACHE))
    self.board = board
    self.config = site_config.FindCanonicalConfigForBoard(
        board, allow_internal=not use_external_config)
    self.gs_base = archive_lib.GetBaseUploadURI(self.config)
    self.clear_cache = clear_cache
    self.chrome_src = chrome_src
    self.sdk_path = sdk_path
    self.toolchain_path = toolchain_path
    self.require_exact_version = require_exact_version
    self.silent = silent

    # For external configs, there is no need to run 'gsutil config', because
    # the necessary files are all accessible to anonymous users.
    internal = self.config['internal']
    self.gs_ctx = gs.GSContext(cache_dir=cache_dir, init_boto=internal)

    if self.sdk_path is None:
      self.sdk_path = os.environ.get(self.SDK_PATH_ENV)

    if self.toolchain_path is None:
      self.toolchain_path = 'gs://%s' % constants.SDK_GS_BUCKET

  def _RemoveOldCacheDir(self):
    """Deletes old cache directory."""
    checkout = path_util.DetermineCheckout(os.getcwd())
    if checkout.type == path_util.CHECKOUT_TYPE_GCLIENT:
      old_path = os.path.join(checkout.root, path_util.OLD_CHROME_CACHE_DIR)
      osutils.RmDir(old_path, ignore_missing=True)

  def _UpdateTarball(self, url, ref):
    """Worker function to fetch tarballs"""
    with osutils.TempDir(base_dir=self.tarball_cache.staging_dir) as tempdir:
      local_path = os.path.join(tempdir, os.path.basename(url))
      Log('SDK: Fetching %s', url, silent=self.silent)
      self.gs_ctx.Copy(url, tempdir, debug_level=logging.DEBUG)
      ref.SetDefault(local_path, lock=True)

  def _GetMetadata(self, version):
    """Return metadata (in the form of a dict) for a given version."""
    raw_json = None
    version_base = self._GetVersionGSBase(version)
    with self.misc_cache.Lookup(
        self._GetCacheKeyForComponent(version, constants.METADATA_JSON)) as ref:
      if ref.Exists(lock=True):
        raw_json = osutils.ReadFile(ref.path)
      else:
        metadata_path = os.path.join(version_base, constants.METADATA_JSON)
        partial_metadata_path = os.path.join(version_base,
                                             constants.PARTIAL_METADATA_JSON)
        try:
          raw_json = self.gs_ctx.Cat(metadata_path,
                                     debug_level=logging.DEBUG)
        except gs.GSNoSuchKey:
          logging.info('Could not read %s, falling back to %s',
                       metadata_path, partial_metadata_path)
          raw_json = self.gs_ctx.Cat(partial_metadata_path,
                                     debug_level=logging.DEBUG)

        ref.AssignText(raw_json)

    return json.loads(raw_json)

  @staticmethod
  def GetChromeLKGM(chrome_src_dir=None):
    """Get ChromeOS LKGM checked into the Chrome tree.

    Args:
      chrome_src_dir: chrome source directory.

    Returns:
      Version number in format '10171.0.0'.
    """
    if not chrome_src_dir:
      chrome_src_dir = path_util.DetermineCheckout(os.getcwd()).chrome_src_dir
    if not chrome_src_dir:
      return None
    lkgm_file = os.path.join(chrome_src_dir, constants.PATH_TO_CHROME_LKGM)
    version = osutils.ReadFile(lkgm_file).rstrip()
    logging.debug('Read LKGM version from %s: %s', lkgm_file, version)
    return version

  @classmethod
  def GetCachePath(cls, key, cache_dir, board):
    """Gets the path to an item in the cache.

    This should be used when inspecting an SDK that's already been initialized
    elsewhere.

    Args:
      key: Key of item in the cache.
      cache_dir: The toplevel cache dir to search in.
      board: The board to search for.

    Returns:
      Path to the item, or None if the item is missing.
    """
    # The board is always known in the simple chrome SDK shell.
    if board is None:
      return None

    # Get the version by looking at the env var if we're in the SDK shell, and
    # failing that, look at the misc cache.
    sdk_version = os.environ.get(cls.SDK_VERSION_ENV)
    if not sdk_version:
      misc_cache_path = os.path.join(
          cache_dir, COMMAND_NAME, cls.MISC_CACHE)
      misc_cache = cache.DiskCache(misc_cache_path)
      with misc_cache.Lookup((board, 'latest')) as ref:
        if ref.Exists(lock=True):
          sdk_version = osutils.ReadFile(ref.path).strip()
      if not sdk_version:
        return None

    # Look up the cache entry in the tarball cache.
    tarball_cache_path = os.path.join(
        cache_dir, COMMAND_NAME, cls.TARBALL_CACHE)
    tarball_cache = cache.TarballCache(tarball_cache_path)
    cache_key = (board, sdk_version, key)
    with tarball_cache.Lookup(cache_key) as ref:
      if ref.Exists():
        return ref.path
    return None

  @memoize.Memoize
  def _GetSDKVersion(self, version):
    """Get SDK version from metadata.

    Args:
      version: LKGM version, e.g. 12345.0.0

    Returns:
      sdk_version, e.g. 2018.06.04.200410
    """
    return self._GetMetadata(version)['sdk-version']

  def _GetManifest(self, version):
    """Get the build manifest from the cache, downloading it if necessary.

    Args:
      version: LKGM version, e.g. 12345.0.0

    Returns:
      build manifest as a python dictionary. The build manifest contains build
      versions for packages built by the SDK builder.
    """
    with self.misc_cache.Lookup(('manifest', self.board, version)) as ref:
      if ref.Exists(lock=True):
        manifest = osutils.ReadFile(ref.path)
      else:
        manifest_path = gs.GetGsURL(
            bucket=constants.SDK_GS_BUCKET,
            suburl='cros-sdk-%s.tar.xz.Manifest' % self._GetSDKVersion(version),
            for_gsutil=True)
        manifest = self.gs_ctx.Cat(manifest_path)
        ref.AssignText(manifest)
      return json.loads(manifest)

  def _GetBinPackageGSPath(self, version, key):
    """Get google storage path of prebuilt binary package.

    Args:
      version: LKGM version, e.g. 12345.0.0
      key: key in build manifest, for e.g. 'app-emulation/qemu'

    Returns:
      GS path, for e.g. gs://chromeos-prebuilt/board/amd64-host/
      chroot-2018.10.23.171742/packages/app-emulation/qemu-3.0.0.tbz2
    """
    if not version or not key:
      # A version and key is needed to locate the package in Google Storage.
      return None
    package_version = self._GetManifest(version)['packages'][key][0][0]
    return gs.GetGsURL(
        bucket='chromeos-prebuilt',
        suburl='board/amd64-host/chroot-%s/packages/%s-%s.tbz2' %
        (self._GetSDKVersion(version), key, package_version),
        for_gsutil=True)

  def _GetTarballCachePath(self, version, key):
    """Get a path in the tarball cache.

    Args:
      version: LKGM version, e.g. 12345.0.0
      key: tarball key, for e.g. 'app-emulation/qemu'
    """
    cache_key = self._GetCacheKeyForComponent(version, key)
    with self.tarball_cache.Lookup(cache_key) as ref:
      if ref.Exists(lock=True):
        return ref.path
      else:
        logging.warning('%s not found.', key)
    return None

  def _FinalizePackages(self, version):
    """Finalize downloaded packages.

    Fix broken seabios symlinks in the qemu package.

    Args:
      version: LKGM version, e.g. 12345.0.0
    """
    self._CreateSeabiosFWSymlinks(version)

  def _CreateSeabiosFWSymlinks(self, version):
    """Create Seabios firmware symlinks.

    tarballs/<board>+<version>+app-emulation/qemu/usr/share/qemu/ has a number
    of broken symlinks, for example: bios.bin -> ../seabios/bios.bin
    bios.bin is in the seabios package at <cache>/seabios/usr/share/seabios/
    To resolve these symlinks, we create symlinks from
    <cache>+sys-firmware/seabios/usr/share/* to
    <cache>+app-emulation/qemu/usr/share/

    Args:
      version: LKGM version, e.g. 12345.0.0
    """
    qemu_bin_path = self._GetTarballCachePath(version, self.QEMU_BIN_PATH)
    seabios_bin_path = self._GetTarballCachePath(version, self.SEABIOS_BIN_PATH)
    if not qemu_bin_path or not seabios_bin_path:
      logging.warning('Could not create Seabios firmware links.')
      return

    # Symlink the directories in seabios/usr/share/* to qemu/usr/share/.
    share_dir = 'usr/share'
    seabios_share_dir = os.path.join(seabios_bin_path, share_dir)
    qemu_share_dir = os.path.join(qemu_bin_path, share_dir)
    for seabios_dir in os.listdir(seabios_share_dir):
      src_dir = os.path.relpath(
          os.path.join(seabios_share_dir, seabios_dir), qemu_share_dir)
      target_dir = os.path.join(qemu_share_dir, seabios_dir)
      if not os.path.exists(target_dir):
        os.symlink(src_dir, target_dir)

  def _GetFullVersionFromStorage(self, version_file):
    """Cat |version_file| in google storage.

    Args:
      version_file: google storage path of the version file.

    Returns:
      Version number in the format 'R30-3929.0.0' or None.
    """
    try:
       # If the version doesn't exist in google storage,
       # which isn't unlikely, don't waste time on retries.
      full_version = self.gs_ctx.Cat(version_file, retries=0)
      assert full_version.startswith('R')
      return full_version
    except (gs.GSNoSuchKey, gs.GSCommandError):
      return None

  def _GetFullVersionFromRecentLatest(self, version):
    """Gets the full version number from a recent LATEST- file.

    If LATEST-{version} does not exist, we need to look for a recent
    LATEST- file to get a valid full version from.

    Args:
      version: The version number to look backwards from. If version is not a
      canary version (ending in .0.0), returns None.

    Returns:
      Version number in the format 'R30-3929.0.0' or None.
    """

    # If version does not end in .0.0 it is not a canary so fail.
    if not version.endswith('.0.0'):
      return None
    version_base = int(version.split('.')[0])
    version_base_min = version_base - self.VERSIONS_TO_CONSIDER

    for v in xrange(version_base - 1, version_base_min, -1):
      version_file = '%s/LATEST-%d.0.0' % (self.gs_base, v)
      logging.info('Trying: %s', version_file)
      full_version = self._GetFullVersionFromStorage(version_file)
      if full_version is not None:
        logging.warning(
            'Using cros version from most recent LATEST file: %s -> %s',
            version_file, full_version)
        return full_version
    logging.warning('No recent LATEST file found from %d.0.0 to %d.0.0: ',
                    version_base_min, version_base)
    return None

  def _GetFullVersionFromLatest(self, version):
    """Gets the full version number from the LATEST-{version} file.

    Args:
      version: The version number or branch to look at.

    Returns:
      Version number in the format 'R30-3929.0.0' or None.
    """
    version_file = '%s/LATEST-%s' % (self.gs_base, version)
    full_version = self._GetFullVersionFromStorage(version_file)
    if full_version is None and not self.require_exact_version:
      logging.warning('No LATEST file matching SDK version %s', version)
      return self._GetFullVersionFromRecentLatest(version)
    return full_version

  def GetDefaultVersion(self):
    """Get the default SDK version to use.

    If we are in an existing SDK shell, the default version will just be
    the current version. Otherwise, we will try to calculate the
    appropriate version to use based on the checkout.
    """
    if os.environ.get(self.SDK_BOARD_ENV) == self.board:
      sdk_version = os.environ.get(self.SDK_VERSION_ENV)
      if sdk_version is not None:
        return sdk_version

    with self.misc_cache.Lookup((self.board, 'latest')) as ref:
      if ref.Exists(lock=True):
        version = osutils.ReadFile(ref.path).strip()
        # Deal with the old version format.
        if version.startswith('R'):
          version = version.split('-')[1]
        return version
      else:
        return None

  def _SetDefaultVersion(self, version):
    """Set the new default version."""
    with self.misc_cache.Lookup((self.board, 'latest')) as ref:
      ref.AssignText(version)

  def UpdateDefaultVersion(self):
    """Update the version that we default to using.

    Returns:
      A tuple of the form (version, updated), where |version| is the
      version number in the format '3929.0.0', and |updated| indicates
      whether the version was indeed updated.
    """
    checkout_dir = self.chrome_src if self.chrome_src else os.getcwd()
    checkout = path_util.DetermineCheckout(checkout_dir)
    current = self.GetDefaultVersion() or '0'

    if not checkout.chrome_src_dir:
      raise NoChromiumSrcDir(checkout_dir)

    target = self.GetChromeLKGM(checkout.chrome_src_dir)
    if target is None:
      raise MissingLKGMFile(checkout.chrome_src_dir)

    self._SetDefaultVersion(target)
    return target, target != current

  def GetFullVersion(self, version):
    """Add the release branch and build number to a ChromeOS platform version.

    This will specify where you can get the latest build for the given version
    for the current board.

    Args:
      version: A ChromeOS platform number of the form XXXX.XX.XX, i.e.,
        3918.0.0. If a full version is provided, it will be returned unmodified.

    Returns:
      The version with release branch and build number added, as needed. E.g.
      R28-3918.0.0-b1234.
    """
    if version.startswith('R'):
      return version

    with self.misc_cache.Lookup(('full-version', self.board, version)) as ref:
      if ref.Exists(lock=True):
        return osutils.ReadFile(ref.path).strip()
      else:
        full_version = self._GetFullVersionFromLatest(version)

        if full_version is None:
          raise MissingSDK(self.board, version)

        ref.AssignText(full_version)
        return full_version

  def _GetVersionGSBase(self, version):
    """The base path of the SDK for a particular version."""
    if self.sdk_path is not None:
      return self.sdk_path

    full_version = self.GetFullVersion(version)
    return os.path.join(self.gs_base, full_version)

  def _GetCacheKeyForComponent(self, version, component):
    """Builds the cache key tuple for an SDK component."""
    version_section = version
    if self.sdk_path is not None:
      version_section = self.sdk_path.replace('/', '__').replace(':', '__')
    return (self.board, version_section, component)

  @contextlib.contextmanager
  def Prepare(self, components, version=None, target_tc=None,
              toolchain_url=None):
    """Ensures the components of an SDK exist and are read-locked.

    For a given SDK version, pulls down missing components, and provides a
    context where the components are read-locked, which prevents the cache from
    deleting them during its purge operations.

    If both target_tc and toolchain_url arguments are provided, then this
    does not download metadata.json for the given version. Otherwise, this
    function requires metadata.json for the given version to exist.

    Args:
      gs_ctx: GSContext object.
      components: A list of specific components(tarballs) to prepare.
      version: The version to prepare.  If not set, uses the version returned by
        GetDefaultVersion().  If there is no default version set (this is the
        first time we are being executed), then we update the default version.
      target_tc: Target toolchain name to use, e.g. x86_64-cros-linux-gnu
      toolchain_url: Format pattern for path to fetch toolchain from,
        e.g. 2014/04/%(target)s-2014.04.23.220740.tar.xz

    Yields:
      An SDKFetcher.SDKContext namedtuple object.  The attributes of the
      object are:
        version: The version that was prepared.
        target_tc: Target toolchain name.
        key_map: Dictionary that contains CacheReference objects for the SDK
          artifacts, indexed by cache key.
    """
    if version is None and self.sdk_path is None:
      version = self.GetDefaultVersion()
      if version is None:
        version, _ = self.UpdateDefaultVersion()
    components = list(components)

    key_map = {}
    fetch_urls = {}

    if not target_tc or not toolchain_url:
      metadata = self._GetMetadata(version)
      target_tc = target_tc or metadata['toolchain-tuple'][0]
      toolchain_url = toolchain_url or metadata['toolchain-url']

    # Fetch toolchains from separate location.
    if self.TARGET_TOOLCHAIN_KEY in components:
      fetch_urls[self.TARGET_TOOLCHAIN_KEY] = os.path.join(
          self.toolchain_path, toolchain_url % {'target': target_tc})
      components.remove(self.TARGET_TOOLCHAIN_KEY)

    # Fetch the Tast binary.
    tast_cmd_path = self._GetBinPackageGSPath(version, self.TAST_CMD_PATH)
    tast_remote_tests_path = self._GetBinPackageGSPath(
        version, self.TAST_REMOTE_TESTS_PATH)
    if tast_cmd_path and tast_remote_tests_path:
      fetch_urls[self.TAST_CMD_PATH] = tast_cmd_path
      fetch_urls[self.TAST_REMOTE_TESTS_PATH] = tast_remote_tests_path
    else:
      logging.warning('Failed to find Tast binaries to download.')

    # Also fetch QEMU binary if VM_IMAGE_TAR is specified.
    if constants.VM_IMAGE_TAR in components:
      qemu_bin_path = self._GetBinPackageGSPath(version, self.QEMU_BIN_PATH)
      seabios_bin_path = self._GetBinPackageGSPath(version,
                                                   self.SEABIOS_BIN_PATH)
      if qemu_bin_path and seabios_bin_path:
        fetch_urls[self.QEMU_BIN_PATH] = qemu_bin_path
        fetch_urls[self.SEABIOS_BIN_PATH] = seabios_bin_path
      else:
        logging.warning('Failed to find QEMU/Seabios binaries to download.')

    version_base = self._GetVersionGSBase(version)
    fetch_urls.update((t, os.path.join(version_base, t)) for t in components)
    try:
      for key, url in fetch_urls.iteritems():
        cache_key = self._GetCacheKeyForComponent(version, key)
        ref = self.tarball_cache.Lookup(cache_key)
        key_map[key] = ref
        ref.Acquire()
        if not ref.Exists(lock=True):
          # TODO(rcui): Parallelize this.  Requires acquiring locks *before*
          # generating worker processes; therefore the functionality needs to
          # be moved into the DiskCache class itself -
          # i.e.,DiskCache.ParallelSetDefault().
          try:
            self._UpdateTarball(url, ref)
          except gs.GSNoSuchKey:
            if key == constants.VM_IMAGE_TAR:
              logging.warning(
                  'No VM available for board %s. '
                  'Please try a different board, e.g. amd64-generic.',
                  self.board)
            else:
              raise

      self._FinalizePackages(version)
      ctx_version = version
      if self.sdk_path is not None:
        ctx_version = CUSTOM_VERSION
      yield self.SDKContext(ctx_version, target_tc, key_map)
    finally:
      # TODO(rcui): Move to using cros_build_lib.ContextManagerStack()
      cros_build_lib.SafeRun([ref.Release for ref in key_map.itervalues()])


class GomaError(Exception):
  """Indicates error with setting up Goma."""


@command.CommandDecorator(COMMAND_NAME)
class ChromeSDKCommand(command.CliCommand):
  """Set up an environment for building Chrome on Chrome OS.

  Pulls down SDK components for building and testing Chrome for Chrome OS,
  sets up the environment for building Chrome, and runs a command in the
  environment, starting a bash session if no command is specified.

  The bash session environment is set up by a user-configurable rc file located
  at ~/.chromite/chrome_sdk.bashrc.
  """

  # Note, this URL is not accessible outside of corp.
  _GOMA_DOWNLOAD_URL = ('https://clients5.google.com/cxx-compiler-service/'
                        'download/downloadurl')
  _GOMA_TGZ = 'goma-goobuntu.tgz'

  _CHROME_CLANG_DIR = 'third_party/llvm-build/Release+Asserts/bin'
  _HOST_BINUTILS_DIR = 'third_party/binutils/Linux_x64/Release/bin/'

  EBUILD_ENV = (
      # Compiler tools.
      'CXX',
      'CC',
      'AR',
      'AS',
      'LD',
      'NM',
      'RANLIB',
      'READELF',

      # Compiler flags.
      'CFLAGS',
      'CXXFLAGS',
      'CPPFLAGS',
      'LDFLAGS',

      # Misc settings.
      'GN_ARGS',
      'GOLD_SET',
      'USE',
  )

  SDK_GOMA_PORT_ENV = 'SDK_GOMA_PORT'
  SDK_GOMA_DIR_ENV = 'SDK_GOMA_DIR'

  GOMACC_PORT_CMD = ['./gomacc', 'port']

  # Override base class property to use cache related commandline options.
  use_caching_options = True

  @staticmethod
  def ValidateVersion(version):
    """Ensures that the version arg is potentially valid.

    See the argument description for supported version formats.
    """

    if (not re.match(r'^[0-9]+\.0\.0$', version) and
        not re.match(r'^R[0-9]+-[0-9]+\.[0-9]+\.[0-9]+', version)):
      raise argparse.ArgumentTypeError(
          '--version should be in the format 1234.0.0 or R56-1234.0.0')
    return version

  @classmethod
  def AddParser(cls, parser):
    super(ChromeSDKCommand, cls).AddParser(parser)
    parser.add_argument(
        '--board', required=True, help='The board SDK to use.')
    parser.add_argument(
        '--bashrc', type='path',
        default=constants.CHROME_SDK_BASHRC,
        help='A bashrc file used to set up the SDK shell environment. '
             'Defaults to %s.' % constants.CHROME_SDK_BASHRC)
    parser.add_argument(
        '--chroot', type='path',
        help='Path to a ChromeOS chroot to use. If set, '
             '<chroot>/build/<board> will be used as the sysroot that Chrome '
             'is built against. If chromeos-chrome was built, the build '
             'environment from the chroot will also be used. The version shown '
             'in the SDK shell prompt will have an asterisk prepended to it.')
    parser.add_argument(
        '--chrome-src', type='path',
        help='Specifies the location of a Chrome src/ directory.  Required if '
             'running with --clang if not running from a Chrome checkout.')
    parser.add_argument(
        '--clang', action='store_true', default=False,
        help='Sets up the environment for building with clang. For all '
             'boards, except X86-32, clang is the default.')
    parser.add_argument(
        '--cwd', type='path',
        help='Specifies a directory to switch to after setting up the SDK '
             'shell.  Defaults to the current directory.')
    parser.add_argument(
        '--internal', action='store_true', default=False,
        help='Sets up SDK for building official (internal) Chrome '
             'Chrome, rather than Chromium.')
    parser.add_argument(
        '--use-external-config', action='store_true', default=False,
        help='Use the external configuration for the specified board, even if '
             'an internal configuration is avalable.')
    parser.add_argument(
        '--sdk-path', type='local_or_gs_path',
        help='Provides a path, whether a local directory or a gs:// path, to '
             'pull SDK components from.')
    parser.add_argument(
        '--toolchain-path', type='local_or_gs_path',
        help='Provides a path, whether a local directory or a gs:// path, to '
             'pull toolchain components from.')
    parser.add_argument(
        '--gn-extra-args',
        help='Provides extra args to "gn gen". Uses the same format as '
             'gn gen, e.g. "foo = true bar = 1".')
    parser.add_argument(
        '--gn-gen', action='store_true', default=True, dest='gn_gen',
        help='Run "gn gen" if args.gn is stale.')
    parser.add_argument(
        '--nogn-gen', action='store_false', dest='gn_gen',
        help='Do not run "gn gen", warns if args.gn is stale.')
    parser.add_argument(
        '--nogoma', action='store_false', default=True, dest='goma',
        help='Disables Goma in the shell by removing it from the PATH and '
             'set use_goma=false to GN_ARGS.')
    parser.add_argument(
        '--nostart-goma', action='store_false', default=True, dest='start_goma',
        help='Skip starting goma and hope somebody else starts goma later.')
    parser.add_argument(
        '--gomadir', type='path',
        help='Use the goma installation at the specified PATH.')
    parser.add_argument(
        '--version', default=None, type=cls.ValidateVersion,
        help='Specify the SDK version to use. This can be a platform version '
             'ending in .0.0, e.g. 1234.0.0, in which case the full version '
             'will be extracted from the corresponding LATEST file for the '
             'specified board. If no LATEST file exists, an older version '
             'will be used if available. Alternatively, a full version may be '
             'specified, e.g. R56-1234.0.0, in which case that exact version '
             'will be used. Defaults to using the version specified in the '
             'CHROMEOS_LKGM file in the chromium checkout.')
    parser.add_argument(
        '--require-exact-version', default=False, action='store_true',
        help='Use the exact SDK version; do not attempt to use previous '
             'versions.')
    parser.add_argument(
        'cmd', nargs='*', default=None,
        help='The command to execute in the SDK environment.  Defaults to '
             'starting a bash shell.')
    parser.add_argument(
        '--download-vm', action='store_true', default=False,
        help='Additionally downloads a VM image from cloud storage.')
    parser.add_argument(
        '--thinlto', action='store_true', default=False,
        help='Enable ThinLTO in build.')
    parser.add_argument(
        '--cfi', action='store_true', default=False,
        help='Enable CFI in build.')

    parser.caching_group.add_argument(
        '--clear-sdk-cache', action='store_true',
        default=False,
        help='Removes everything in the SDK cache before starting.')

    group = parser.add_argument_group(
        'Metadata Overrides (Advanced)',
        description='Provide all of these overrides in order to remove '
                    'dependencies on metadata.json existence.')
    group.add_argument(
        '--target-tc', action='store', default=None,
        help='Override target toolchain name, e.g. x86_64-cros-linux-gnu')
    group.add_argument(
        '--toolchain-url', action='store', default=None,
        help='Override toolchain url format pattern, e.g. '
             '2014/04/%%(target)s-2014.04.23.220740.tar.xz')

  def __init__(self, options):
    super(ChromeSDKCommand, self).__init__(options)
    self.board = options.board
    # Lazy initialized.
    self.sdk = None
    # Initialized later based on options passed in.
    self.silent = True

  @staticmethod
  def _PS1Prefix(board, version, chroot=None):
    """Returns a string describing the sdk environment for use in PS1."""
    chroot_star = '*' if chroot else ''
    return '(sdk %s %s%s)' % (board, chroot_star, version)

  @staticmethod
  def _CreatePS1(board, version, chroot=None):
    """Returns PS1 string that sets commandline and xterm window caption.

    If a chroot path is set, then indicate we are using the sysroot from there
    instead of the stock sysroot by prepending an asterisk to the version.

    Args:
      board: The SDK board.
      version: The SDK version.
      chroot: The path to the chroot, if set.
    """
    current_ps1 = cros_build_lib.RunCommand(
        ['bash', '-l', '-c', 'echo "$PS1"'], print_cmd=False,
        capture_output=True).output.splitlines()
    if current_ps1:
      current_ps1 = current_ps1[-1]
    if not current_ps1:
      # Something went wrong, so use a fallback value.
      current_ps1 = r'\u@\h \w $ '
    ps1_prefix = ChromeSDKCommand._PS1Prefix(board, version, chroot)
    return '%s %s' % (ps1_prefix, current_ps1)

  def _BuildDir(self):
    """Returns a full path build directory."""
    return os.path.join(self.options.chrome_src, 'out_%s' % self.board,
                        'Release')

  def _FixGoldPath(self, var_contents, toolchain_path):
    """Point to the gold linker in the toolchain tarball.

    Accepts an already set environment variable in the form of '<cmd>
    -B<gold_path>', and overrides the gold_path to the correct path in the
    extracted toolchain tarball.

    Args:
      var_contents: The contents of the environment variable.
      toolchain_path: Path to the extracted toolchain tarball contents.

    Returns:
      Environment string that has correct gold path.
    """
    cmd, _, gold_path = var_contents.partition(' -B')
    gold_path = os.path.join(toolchain_path, gold_path.lstrip('/'))
    return '%s -B%s' % (cmd, gold_path)

  def _UpdateGnArgsIfStale(self, out_dir, build_label, gn_args, board):
    """Runs 'gn gen' if gn args are stale or logs a warning."""
    gn_args_file_path = os.path.join(
        self.options.chrome_src, out_dir, build_label, 'args.gn')

    if not self._StaleGnArgs(gn_args, gn_args_file_path):
      return

    if not self.options.gn_gen:
      logging.warning('To update gn args run:')
      logging.warning('gn gen out_$SDK_BOARD/Release --args="$GN_ARGS"')
      return

    logging.warning('Running gn gen')
    cros_build_lib.RunCommand(
        ['gn', 'gen', 'out_%s/Release' % board,
         '--args=%s' % gn_helpers.ToGNString(gn_args)],
        print_cmd=logging.getLogger().isEnabledFor(logging.DEBUG),
        cwd=self.options.chrome_src)

  def _StaleGnArgs(self, new_gn_args, gn_args_file_path):
    """Returns True if args.gn needs to be updated."""
    if not os.path.exists(gn_args_file_path):
      logging.warning('No args.gn file: %s', gn_args_file_path)
      return True

    old_gn_args = gn_helpers.FromGNArgs(osutils.ReadFile(gn_args_file_path))
    if new_gn_args == old_gn_args:
      return False

    logging.warning('Stale args.gn file: %s', gn_args_file_path)
    self._LogArgsDiff(old_gn_args, new_gn_args)
    return True

  def _LogArgsDiff(self, cur_args, new_args):
    """Logs the differences between |cur_args| and |new_args|."""
    cur_keys = set(cur_args.keys())
    new_keys = set(new_args.keys())

    for k in new_keys - cur_keys:
      logging.info('MISSING ARG: %s = %s', k, new_args[k])

    for k in cur_keys - new_keys:
      logging.info('EXTRA ARG: %s = %s', k, cur_args[k])

    for k in new_keys & cur_keys:
      v_cur = cur_args[k]
      v_new = new_args[k]
      if v_cur != v_new:
        logging.info('MISMATCHED ARG: %s: %s != %s', k, v_cur, v_new)

  def _SetupTCEnvironment(self, sdk_ctx, options, env, gn_is_clang):
    """Sets up toolchain-related environment variables."""
    target_tc_path = sdk_ctx.key_map[self.sdk.TARGET_TOOLCHAIN_KEY].path
    tc_bin_path = os.path.join(target_tc_path, 'bin')
    env['PATH'] = '%s:%s' % (tc_bin_path, os.environ['PATH'])

    for var in ('CXX', 'CC', 'LD'):
      env[var] = self._FixGoldPath(env[var], target_tc_path)

    chrome_clang_path = os.path.join(options.chrome_src, self._CHROME_CLANG_DIR)

    # Either we are forcing the use of clang through options or GN
    # args say we should be using clang.
    if options.clang or gn_is_clang:
      clang_prepend_flags = ['-Wno-unknown-warning-option']
      # crbug.com/686903
      clang_append_flags = ['-Wno-inline-asm']

      env['CC'] = ' '.join([sdk_ctx.target_tc + '-clang'] +
                           env['CC'].split()[1:] + clang_prepend_flags)
      env['CXX'] = ' '.join([sdk_ctx.target_tc + '-clang++'] +
                            env['CXX'].split()[1:] + clang_prepend_flags)
      env['CFLAGS'] = ' '.join(env['CFLAGS'].split() + clang_append_flags)
      env['CXXFLAGS'] = ' '.join(env['CXXFLAGS'].split() + clang_append_flags)
      env['LD'] = env['CXX']

    # Use cros readelf for the target builds. TODO: Delete it after Jan 2019
    # since READELF env variable should already be set,
    # https://crbug.com/917193.
    env.setdefault('READELF', sdk_ctx.target_tc + '-readelf')

    # For host compiler, we use the compiler that comes with Chrome
    # instead of the target compiler.
    env['CC_host'] = os.path.join(chrome_clang_path, 'clang')
    env['CXX_host'] = os.path.join(chrome_clang_path, 'clang++')
    env['LD_host'] = env['CXX_host']

    binutils_path = os.path.join(options.chrome_src, self._HOST_BINUTILS_DIR)
    env['AR_host'] = os.path.join(binutils_path, 'ar')
    env['NM_host'] = os.path.join(binutils_path, 'nm')
    env['READELF_host'] = os.path.join(binutils_path, 'readelf')

  def _ModifyPathForGomaBuild(self, compiler, tc_path=None):
    """Modify toolchain path for goma build.

    This function relativizes path of -B flag, but absolutize compiler path.
    Compiler path will be relativized in build/toolchain/cros/BUILD.gn for
    directory independent cache sharing in some distributed build system.
    """
    args = []
    for i, v in enumerate(compiler.split()):
      if v.startswith('-B'):
        v = '-B' + os.path.relpath(v[len('-B'):], self._BuildDir())
      elif i == 0 and os.path.basename(v) == v:
        v = os.path.join(tc_path, 'bin', v)
      args.append(v)
    return ' '.join(args)

  def _SetupEnvironment(self, board, sdk_ctx, options, goma_dir=None,
                        goma_port=None):
    """Sets environment variables to export to the SDK shell."""
    if options.chroot:
      sysroot = os.path.join(options.chroot, 'build', board)
      if not os.path.isdir(sysroot) and not options.cmd:
        logging.warning("Because --chroot is set, expected a sysroot to be at "
                        "%s, but couldn't find one.", sysroot)
    else:
      sysroot = sdk_ctx.key_map[constants.CHROME_SYSROOT_TAR].path

    environment = os.path.join(sdk_ctx.key_map[constants.CHROME_ENV_TAR].path,
                               'environment')
    if options.chroot:
      # Override with the environment from the chroot if available (i.e.
      # build_packages or emerge chromeos-chrome has been run for |board|).
      env_path = os.path.join(sysroot, 'var', 'db', 'pkg', 'chromeos-base',
                              'chromeos-chrome-*')
      env_glob = glob.glob(env_path)
      if len(env_glob) != 1:
        logging.warning('Multiple Chrome versions in %s. This can be resolved'
                        ' by running "eclean-$BOARD -d packages". Using'
                        ' environment from: %s', env_path, environment)
      elif not os.path.isdir(env_glob[0]):
        logging.warning('Environment path not found: %s. Using enviroment from:'
                        ' %s.', env_path, environment)
      else:
        chroot_env_file = os.path.join(env_glob[0], 'environment.bz2')
        if os.path.isfile(chroot_env_file):
          # Log a warning here since this is new behavior that is not obvious.
          logging.notice('Environment fetched from: %s', chroot_env_file)
          # Uncompress enviornment.bz2 to pass to osutils.SourceEnvironment.
          chroot_cache = os.path.join(options.cache_dir, COMMAND_NAME, 'chroot')
          osutils.SafeMakedirs(chroot_cache)
          environment = os.path.join(chroot_cache, 'environment_%s' % board)
          cros_build_lib.UncompressFile(chroot_env_file, environment)

    env = osutils.SourceEnvironment(environment, self.EBUILD_ENV)
    gn_args = gn_helpers.FromGNArgs(env['GN_ARGS'])
    self._SetupTCEnvironment(sdk_ctx, options, env, gn_args['is_clang'])

    # Add managed components to the PATH.
    env['PATH'] = '%s:%s' % (constants.CHROMITE_BIN_DIR, env['PATH'])
    env['PATH'] = '%s:%s' % (os.path.dirname(self.sdk.gs_ctx.gsutil_bin),
                             env['PATH'])

    # Export internally referenced variables.
    os.environ[self.sdk.SDK_BOARD_ENV] = board
    if options.sdk_path:
      os.environ[self.sdk.SDK_PATH_ENV] = options.sdk_path
    os.environ[self.sdk.SDK_VERSION_ENV] = sdk_ctx.version

    # Add board and sdk version as gn args so that tests can bind them in
    # test wrappers generated at compile time.
    gn_args['cros_board'] = board
    gn_args['cros_sdk_version'] = sdk_ctx.version

    # Export the board/version info in a more accessible way, so developers can
    # reference them in their chrome_sdk.bashrc files, as well as within the
    # chrome-sdk shell.
    for var in [self.sdk.SDK_VERSION_ENV, self.sdk.SDK_BOARD_ENV]:
      env[var.lstrip('%')] = os.environ[var]

    # Export Goma information.
    if goma_dir:
      env[self.SDK_GOMA_DIR_ENV] = goma_dir
    if goma_port:
      env[self.SDK_GOMA_PORT_ENV] = goma_port

    # SYSROOT is necessary for Goma and the sysroot wrapper.
    env['SYSROOT'] = sysroot

    gn_args['target_sysroot'] = sysroot
    gn_args.pop('pkg_config', None)
    # pkg_config only affects the target and comes from the sysroot.
    # host_pkg_config is used for programs compiled for use later in the build.
    gn_args['host_pkg_config'] = 'pkg-config'
    if options.clang:
      gn_args['is_clang'] = True
    if options.internal:
      gn_args['is_chrome_branded'] = True
      gn_args['is_official_build'] = True

      # TODO(https://crbug.com/917504): We'd like to use lld for all
      # configurations. However, it appears that there's a bug in how it emits
      # unwinding info on ARM, and we emit unwind info on builds that aren't
      # both official and branded. Until that bug is fixed, our use of lld has
      # to be restricted to builds where we don't emit unwinding info.
      gn_args['use_lld'] = True
    else:
      gn_args.pop('is_chrome_branded', None)
      gn_args.pop('is_official_build', None)
      gn_args.pop('internal_gles2_conform_tests', None)
      gn_args.pop('use_lld', None)
      # TODO(https://crbug.com/924155): Hack to keep Chromite rolling. Remove
      # it when either we're back on lld (see the TODO above), or when we get a
      # new-enough `environment` file.
      ld_flags = gn_args.get('cros_target_extra_ldflags')
      if ld_flags:
        ld_flags = ld_flags.replace('-Wl,-z,keep-text-section-prefix', '')
        gn_args['cros_target_extra_ldflags'] = ld_flags

    # For SimpleChrome, we use the binutils that comes bundled within Chrome.
    # We should not use the binutils from the host system.
    gn_args['linux_use_bundled_binutils'] = True

    # Need to reset these after the env vars have been fixed by
    # _SetupTCEnvironment.
    gn_args['cros_host_is_clang'] = True
    # v8 snapshot is built on the host, so we need to set this.
    # See crosbug/618346.
    gn_args['cros_v8_snapshot_is_clang'] = True
    #
    target_tc_path = sdk_ctx.key_map[self.sdk.TARGET_TOOLCHAIN_KEY].path
    modified_env_cc = self._ModifyPathForGomaBuild(env['CC'], target_tc_path)
    modified_env_cxx = self._ModifyPathForGomaBuild(env['CXX'], target_tc_path)
    gn_args['cros_target_cc'] = modified_env_cc.split()[0]
    gn_args['cros_target_cxx'] = modified_env_cxx.split()[0]
    gn_args['cros_target_ld'] = env['LD']
    gn_args['cros_target_nm'] = env['NM']
    gn_args['cros_target_readelf'] = env['READELF']
    gn_args['cros_target_extra_cflags'] = ' '.join(
        [env.get('CFLAGS', '')] + modified_env_cc.split()[1:])
    gn_args['cros_target_extra_cxxflags'] = ' '.join(
        [env.get('CXXFLAGS', '')] + modified_env_cxx.split()[1:])
    gn_args['cros_host_cc'] = self._ModifyPathForGomaBuild(env['CC_host'])
    gn_args['cros_host_cxx'] = self._ModifyPathForGomaBuild(env['CXX_host'])
    gn_args['cros_host_ld'] = env['LD_host']
    gn_args['cros_host_nm'] = env['NM_host']
    gn_args['cros_host_ar'] = env['AR_host']
    gn_args['cros_host_readelf'] = env['READELF_host']
    gn_args['cros_v8_snapshot_cc'] = self._ModifyPathForGomaBuild(
        env['CC_host'])
    gn_args['cros_v8_snapshot_cxx'] = self._ModifyPathForGomaBuild(
        env['CXX_host'])
    gn_args['cros_v8_snapshot_ld'] = env['LD_host']
    gn_args['cros_v8_snapshot_nm'] = env['NM_host']
    gn_args['cros_v8_snapshot_ar'] = env['AR_host']
    gn_args['cros_v8_snapshot_readelf'] = env['READELF_host']
    # No need to adjust CFLAGS and CXXFLAGS for GN since the only
    # adjustment made in _SetupTCEnvironment is for split debug which
    # is done with 'use_debug_fission'.

    # Enable goma if requested.
    if not options.goma:
      # If --nogoma option is explicitly set, disable goma, even if it is
      # used in the original GN_ARGS.
      gn_args['use_goma'] = False
    elif goma_dir:
      gn_args['use_goma'] = True

      # Disable automatic gomacc handling in gn since we handle it ourselves.
      gn_args['has_gomacc_path'] = True
      env['GOMACC_PATH'] = os.path.join(goma_dir, 'gomacc')

      # This is used to invoke host compiler via gomacc (e.g. v8_snapshot).
      gn_args['goma_dir'] = goma_dir

    gn_args.pop('internal_khronos_glcts_tests', None)  # crbug.com/588080

    # Disable ThinLTO and CFI for simplechrome. Tryjob machines do not have
    # enough file descriptors to use. crbug.com/789607
    if not options.thinlto and 'use_thin_lto' in gn_args:
      gn_args['use_thin_lto'] = False
    if not options.cfi and 'is_cfi' in gn_args:
      gn_args['is_cfi'] = False
      gn_args['use_cfi_cast'] = False
    # We need to remove the flag -Wl,-plugin-opt,-import-instr-limit=$num
    # from cros_target_extra_ldflags if options.thinlto is not set.
    # The format of ld flags is something like
    # '-Wl,-O1 -Wl,-O2 -Wl,--as-needed -stdlib=libc++'
    if not options.thinlto:
      extra_ldflags = gn_args.get('cros_target_extra_ldflags', '')

      ld_flags_list = extra_ldflags.split()
      ld_flags_list = (
          [f for f in ld_flags_list
           if not f.startswith('-Wl,-plugin-opt,-import-instr-limit')])
      if extra_ldflags:
        gn_args['cros_target_extra_ldflags'] = ' '.join(ld_flags_list)

    # We removed webcore debug symbols on release builds on arm.
    # See crbug.com/792999. However, we want to keep the symbols
    # for simplechrome builds.
    # TODO: remove the 'remove_webcore_debug_symbols' once we
    # change the ebuild file.
    gn_args['remove_webcore_debug_symbols'] = False
    gn_args['blink_symbol_level'] = -1

    # Remove symbol_level specified in the ebuild to use the default.
    # Currently that is 1 when is_debug=false, instead of 2 specified by the
    # ebuild. This results in faster builds in Simple Chrome.
    if 'symbol_level' in gn_args:
      symbol_level = gn_args.pop('symbol_level')
      logging.info('Removing symbol_level = %d from gn args, use '
                   '--gn-extra-args to specify a non default value.',
                   symbol_level)

    if options.gn_extra_args:
      gn_args.update(gn_helpers.FromGNArgs(options.gn_extra_args))

    gn_args_env = gn_helpers.ToGNString(gn_args)
    env['GN_ARGS'] = gn_args_env

    # PS1 sets the command line prompt and xterm window caption.
    full_version = sdk_ctx.version
    if full_version != CUSTOM_VERSION:
      full_version = self.sdk.GetFullVersion(sdk_ctx.version)
    env['PS1'] = self._CreatePS1(self.board, full_version,
                                 chroot=options.chroot)

    # Set the useful part of PS1 for users with a custom PROMPT_COMMAND.
    env['CROS_PS1_PREFIX'] = self._PS1Prefix(self.board, full_version,
                                             chroot=options.chroot)

    out_dir = 'out_%s' % self.board
    env['builddir_name'] = out_dir

    build_label = 'Release'

    # This is used by landmines.py to prevent collisions when building both
    # chromeos and android from shared source.
    # For context, see crbug.com/407417
    env['CHROMIUM_OUT_DIR'] = os.path.join(options.chrome_src, out_dir)

    self._UpdateGnArgsIfStale(out_dir, build_label, gn_args, env['SDK_BOARD'])

    return env

  @staticmethod
  def _VerifyGoma(user_rc):
    """Verify that the user has no goma installations set up in user_rc.

    If the user does have a goma installation set up, verify that it's for
    ChromeOS.

    Args:
      user_rc: User-supplied rc file.
    """
    user_env = osutils.SourceEnvironment(user_rc, ['PATH'])
    goma_ctl = osutils.Which('goma_ctl.py', user_env.get('PATH'))
    if goma_ctl is not None:
      logging.warning(
          '%s is adding Goma to the PATH.  Using that Goma instead of the '
          'managed Goma install.', user_rc)

  @staticmethod
  def _VerifyChromiteBin(user_rc):
    """Verify that the user has not set a chromite bin/ dir in user_rc.

    Args:
      user_rc: User-supplied rc file.
    """
    user_env = osutils.SourceEnvironment(user_rc, ['PATH'])
    chromite_bin = osutils.Which('parallel_emerge', user_env.get('PATH'))
    if chromite_bin is not None:
      logging.warning(
          '%s is adding chromite/bin to the PATH.  Remove it from the PATH to '
          'use the the default Chromite.', user_rc)

  @contextlib.contextmanager
  def _GetRCFile(self, env, user_rc):
    """Returns path to dynamically created bashrc file.

    The bashrc file sets the environment variables contained in |env|, as well
    as sources the user-editable chrome_sdk.bashrc file in the user's home
    directory.  That rc file is created if it doesn't already exist.

    Args:
      env: A dictionary of environment variables that will be set by the rc
        file.
      user_rc: User-supplied rc file.
    """
    if not os.path.exists(user_rc):
      osutils.Touch(user_rc, makedirs=True)

    self._VerifyGoma(user_rc)
    self._VerifyChromiteBin(user_rc)

    # We need a temporary rc file to 'wrap' the user configuration file,
    # because running with '--rcfile' causes bash to ignore bash special
    # variables passed through subprocess.Popen, such as PS1.  So we set them
    # here.
    #
    # Having a wrapper rc file will also allow us to inject bash functions into
    # the environment, not just variables.
    with osutils.TempDir() as tempdir:
      # Only source the user's ~/.bashrc if running in interactive mode.
      contents = [
          '[[ -e ~/.bashrc && $- == *i* ]] && . ~/.bashrc\n',
      ]

      for key, value in env.iteritems():
        contents.append("export %s='%s'\n" % (key, value))
      contents.append('. "%s"\n' % user_rc)

      rc_file = os.path.join(tempdir, 'rcfile')
      osutils.WriteFile(rc_file, contents)
      yield rc_file

  def _GomaPort(self, goma_dir):
    """Returns current active Goma port."""
    port = cros_build_lib.RunCommand(
        self.GOMACC_PORT_CMD, cwd=goma_dir, debug_level=logging.DEBUG,
        error_code_ok=True, capture_output=True).output.strip()
    return port

  def _FetchGoma(self):
    """Fetch, install, and start Goma, using cached version if it exists.

    Returns:
      A tuple (dir, port) containing the path to the cached goma/ dir and the
      Goma port.
    """
    common_path = os.path.join(self.options.cache_dir, constants.COMMON_CACHE)
    common_cache = cache.DiskCache(common_path)

    goma_dir = self.options.gomadir
    if not goma_dir:
      ref = common_cache.Lookup(('goma', '2'))
      if not ref.Exists():
        Log('Installing Goma.', silent=self.silent)
        with osutils.TempDir() as tempdir:
          goma_dir = os.path.join(tempdir, 'goma')
          osutils.SafeMakedirs(goma_dir)
          with osutils.ChdirContext(tempdir):
            try:
              result = retry_util.RunCurl(['--fail', self._GOMA_DOWNLOAD_URL],
                                          stdout_to_pipe=True)
              if result.returncode:
                raise GomaError('Failed to fetch Goma Download URL')
              download_url = result.output.strip()
              result = retry_util.RunCurl(
                  ['--fail', '%s/%s' % (download_url, self._GOMA_TGZ),
                   '--output', self._GOMA_TGZ])
              if result.returncode:
                raise GomaError('Failed to fetch Goma')
            except retry_util.DownloadError:
              raise GomaError('Failed to fetch Goma')
            result = cros_build_lib.DebugRunCommand(
                ['tar', 'xf', self._GOMA_TGZ,
                 '--strip=1', '-C', goma_dir])
            if result.returncode:
              raise GomaError('Failed to extract Goma')
            result = cros_build_lib.DebugRunCommand(
                [os.path.join(goma_dir, 'goma_ctl.py'), 'update'],
                extra_env={'PLATFORM': 'goobuntu'})
            if result.returncode:
              raise GomaError('Failed to install Goma')
          ref.SetDefault(goma_dir)
      goma_dir = ref.path

    port = None
    if self.options.start_goma:
      Log('Starting Goma.', silent=self.silent)
      cros_build_lib.DebugRunCommand(
          [os.path.join(goma_dir, 'goma_ctl.py'), 'ensure_start'])
      port = self._GomaPort(goma_dir)
      Log('Goma is started on port %s', port, silent=self.silent)
      if not port:
        raise GomaError('No Goma port detected')

    return goma_dir, port

  def Run(self):
    """Perform the command."""
    if os.environ.get(SDKFetcher.SDK_VERSION_ENV) is not None:
      cros_build_lib.Die('Already in an SDK shell.')

    src_path = self.options.chrome_src or os.getcwd()
    checkout = path_util.DetermineCheckout(src_path)
    if not checkout.chrome_src_dir:
      cros_build_lib.Die('Chrome checkout not found at %s', src_path)
    self.options.chrome_src = checkout.chrome_src_dir

    if self.options.clang and not self.options.chrome_src:
      cros_build_lib.Die('--clang requires --chrome-src to be set.')

    if self.options.version and self.options.sdk_path:
      cros_build_lib.Die('Cannot specify both --version and --sdk-path.')

    if self.options.cfi and not self.options.thinlto:
      cros_build_lib.Die('CFI requires ThinLTO.')

    self.silent = bool(self.options.cmd)
    # Lazy initialize because SDKFetcher creates a GSContext() object in its
    # constructor, which may block on user input.
    self.sdk = SDKFetcher(
        self.options.cache_dir, self.options.board,
        clear_cache=self.options.clear_sdk_cache,
        chrome_src=self.options.chrome_src,
        sdk_path=self.options.sdk_path,
        toolchain_path=self.options.toolchain_path,
        silent=self.silent,
        use_external_config=self.options.use_external_config,
        require_exact_version=self.options.require_exact_version
    )

    prepare_version = self.options.version
    if not prepare_version and not self.options.sdk_path:
      prepare_version, _ = self.sdk.UpdateDefaultVersion()

    components = [self.sdk.TARGET_TOOLCHAIN_KEY, constants.CHROME_ENV_TAR]
    if not self.options.chroot:
      components.append(constants.CHROME_SYSROOT_TAR)
    if self.options.download_vm:
      components.append(constants.VM_IMAGE_TAR)

    goma_dir = None
    goma_port = None
    if self.options.goma:
      try:
        goma_dir, goma_port = self._FetchGoma()
      except GomaError as e:
        logging.error('Goma: %s.  Bypass by running with --nogoma.', e)

    with self.sdk.Prepare(components, version=prepare_version,
                          target_tc=self.options.target_tc,
                          toolchain_url=self.options.toolchain_url) as ctx:
      env = self._SetupEnvironment(self.options.board, ctx, self.options,
                                   goma_dir=goma_dir, goma_port=goma_port)

      with self._GetRCFile(env, self.options.bashrc) as rcfile:
        bash_cmd = ['/bin/bash']

        extra_env = None
        if not self.options.cmd:
          bash_cmd.extend(['--rcfile', rcfile, '-i'])
        else:
          # The '"$@"' expands out to the properly quoted positional args
          # coming after the '--'.
          bash_cmd.extend(['-c', '"$@"', '--'])
          bash_cmd.extend(self.options.cmd)
          # When run in noninteractive mode, bash sources the rc file set in
          # BASH_ENV, and ignores the --rcfile flag.
          extra_env = {'BASH_ENV': rcfile}

        # Bash behaves differently when it detects that it's being launched by
        # sshd - it ignores the BASH_ENV variable.  So prevent ssh-related
        # environment variables from being passed through.
        os.environ.pop('SSH_CLIENT', None)
        os.environ.pop('SSH_CONNECTION', None)
        os.environ.pop('SSH_TTY', None)

        cmd_result = cros_build_lib.RunCommand(
            bash_cmd, print_cmd=False, debug_level=logging.CRITICAL,
            error_code_ok=True, extra_env=extra_env, cwd=self.options.cwd)
        if self.options.cmd:
          return cmd_result.returncode
