#!/usr/bin/python
"""Script to bootstrap the chroot using new toolchain.

This script allows you to build/install a customized version of gcc/binutils,
either by specifying branch or a local directory.

This script must be executed outside chroot.

Below is some typical usage -

## Build gcc located at /local/gcc/dir and do a bootstrap using the new compiler
## for the chromeos root.  The script tries to find a valid chromeos tree all
## the way up from your current working directory.
./build_tool.py --gcc_dir=/loca/gcc/dir --bootstrap

## Build binutils, using remote branch "mobile_toolchain_v17" and do a bootstrap
## using the new binutils for the chromeos root. The script tries to find a
## valid chromeos tree all the way up from your current working directory.
./build_tool.py --binutils_branch=cros/mobile_toolchain_v17 \
    --chromeos_root=/chromeos/dir --bootstrap

## Same as above except only do it for board daisy - no bootstrapping involved.
./build_tool.py --binutils_branch=cros/mobile_toolchain_v16 \
    --chromeos_root=/chromeos/dir --board=daisy
"""

__author__ = 'shenhan@google.com (Han Shen)'

import optparse
import os
import re
import sys

import repo_to_repo
from utils import command_executer
from utils import logger
from utils import misc

REPO_PATH_PATTERN = 'src/third_party/{0}'
TEMP_BRANCH_NAME = 'internal_testing_branch_no_use'
CHROMIUMOS_OVERLAY_PATH = 'src/third_party/chromiumos-overlay'
EBUILD_PATH_PATTERN = 'src/third_party/chromiumos-overlay/sys-devel/{0}'


class Bootstrapper(object):
  """Class that handles bootstrap process.
  """

  def __init__(self,
               chromeos_root,
               gcc_branch=None,
               gcc_dir=None,
               binutils_branch=None,
               binutils_dir=None,
               board=None,
               disable_2nd_bootstrap=False,
               setup_tool_ebuild_file_only=False):
    self._chromeos_root = chromeos_root

    self._gcc_branch = gcc_branch
    self._gcc_branch_tree = None
    self._gcc_dir = gcc_dir
    self._gcc_ebuild_file = None
    self._gcc_ebuild_file_name = None

    self._binutils_branch = binutils_branch
    self._binutils_branch_tree = None
    self._binutils_dir = binutils_dir
    self._binutils_ebuild_file = None
    self._binutils_ebuild_file_name = None

    self._setup_tool_ebuild_file_only = setup_tool_ebuild_file_only

    self._ce = command_executer.GetCommandExecuter()
    self._logger = logger.GetLogger()
    self._board = board
    self._disable_2nd_bootstrap = disable_2nd_bootstrap

  def IsTreeSame(self, t1, t2):
    diff = 'diff -qr -x .git -x .svn "{0}" "{1}"'.format(t1, t2)
    if self._ce.RunCommand(diff, print_to_console=False) == 0:
      self._logger.LogOutput('"{0}" and "{1}" are the same."'.format(t1, t2))
      return True
    self._logger.LogWarning('"{0}" and "{1}" are different."'.format(t1, t2))
    return False

  def SubmitToLocalBranch(self):
    """Copy source code to the chromium source tree and submit it locally."""
    if self._gcc_dir:
      if not self.SubmitToolToLocalBranch(tool_name='gcc',
                                          tool_dir=self._gcc_dir):
        return False
      self._gcc_branch = TEMP_BRANCH_NAME

    if self._binutils_dir:
      if not self.SubmitToolToLocalBranch(tool_name='binutils',
                                          tool_dir=self._binutils_dir):
        return False
      self._binutils_branch = TEMP_BRANCH_NAME

    return True

  def SubmitToolToLocalBranch(self, tool_name, tool_dir):
    """Copy the source code to local chromium source tree.

    Args:
      tool_name: either 'gcc' or 'binutils'
      tool_dir: the tool source dir to be used
    Returns:
      True if all succeeded False otherwise.
    """

    # The next few steps creates an internal branch to sync with the tool dir
    # user provided.
    chrome_tool_dir = self.GetChromeOsToolDir(tool_name)

    # 0. Test to see if git tree is free of local changes.
    if not misc.IsGitTreeClean(chrome_tool_dir):
      self._logger.LogError('Git repository "{0}" not clean, aborted.'.format(
          chrome_tool_dir))
      return False

    # 1. Checkout/create a (new) branch for testing.
    command = 'cd "{0}" && git checkout -B {1}'.format(chrome_tool_dir,
                                                       TEMP_BRANCH_NAME)
    ret = self._ce.RunCommand(command)
    if ret:
      self._logger.LogError('Failed to create a temp branch for test, aborted.')
      return False

    if self.IsTreeSame(tool_dir, chrome_tool_dir):
      self._logger.LogOutput(
          '"{0}" and "{1}" are the same, sync skipped.'.format(tool_dir,
                                                               chrome_tool_dir))
      return True

    # 2. Sync sources from user provided tool dir to chromiumos tool git.
    local_tool_repo = repo_to_repo.FileRepo(tool_dir)
    chrome_tool_repo = repo_to_repo.GitRepo(chrome_tool_dir, TEMP_BRANCH_NAME)
    chrome_tool_repo._root_dir = chrome_tool_dir
    # Delete all stuff except '.git' before start mapping.
    self._ce.RunCommand(
        'cd {0} && find . -maxdepth 1 -not -name ".git" -not -name "." '
        r'\( -type f -exec rm {{}} \; -o '
        r'   -type d -exec rm -fr {{}} \; \)'.format(chrome_tool_dir))
    local_tool_repo.MapSources(chrome_tool_repo.GetRoot())

    # 3. Ensure after sync tree is the same.
    if self.IsTreeSame(tool_dir, chrome_tool_dir):
      self._logger.LogOutput('Sync successfully done.')
    else:
      self._logger.LogError('Sync not successful, aborted.')
      return False

    # 4. Commit all changes.
    # 4.1 Try to get some information about the tool dir we are using.
    cmd = 'cd {0} && git log -1 --pretty=oneline'.format(tool_dir)
    tool_dir_extra_info = None
    ret, tool_dir_extra_info, _ = self._ce.RunCommandWOutput(
        cmd,
        print_to_console=False)
    commit_message = 'Synced with tool source tree at - "{0}".'.format(tool_dir)
    if not ret:
      commit_message += '\nGit log for {0}:\n{1}'.format(tool_dir,
                                                         tool_dir_extra_info)

    if chrome_tool_repo.CommitLocally(commit_message):
      self._logger.LogError(
          'Commit to local branch "{0}" failed, aborted.'.format(
              TEMP_BRANCH_NAME))
      return False
    return True

  def CheckoutBranch(self):
    """Checkout working branch for the tools.

    Returns:
      True: if operation succeeds.
    """

    if self._gcc_branch:
      rv = self.CheckoutToolBranch('gcc', self._gcc_branch)
      if rv:
        self._gcc_branch_tree = rv
      else:
        return False

    if self._binutils_branch:
      rv = self.CheckoutToolBranch('binutils', self._binutils_branch)
      if rv:
        self._binutils_branch_tree = rv
      else:
        return False

    return True

  def CheckoutToolBranch(self, tool_name, tool_branch):
    """Checkout the tool branch for a certain tool.

    Args:
      tool_name: either 'gcc' or 'binutils'
      tool_branch: tool branch to use
    Returns:
      True: if operation succeeds. Otherwise False.
    """

    chrome_tool_dir = self.GetChromeOsToolDir(tool_name)
    command = 'cd "{0}" && git checkout {1}'.format(chrome_tool_dir,
                                                    tool_branch)
    if not self._ce.RunCommand(command, print_to_console=True):
      # Get 'TREE' value of this commit
      command = ('cd "{0}" && git cat-file -p {1} '
                 '| grep -E "^tree [a-f0-9]+$" '
                 '| cut -d" " -f2').format(chrome_tool_dir, tool_branch)
      ret, stdout, _ = self._ce.RunCommandWOutput(command,
                                                  print_to_console=False)
      # Pipe operation always has a zero return value. So need to check if
      # stdout is valid.
      if not ret and stdout and re.match('[0-9a-h]{40}', stdout.strip(),
                                         re.IGNORECASE):
        tool_branch_tree = stdout.strip()
        self._logger.LogOutput('Find tree for {0} branch "{1}" - "{2}"'.format(
            tool_name, tool_branch, tool_branch_tree))
        return tool_branch_tree
    self._logger.LogError(('Failed to checkout "{0}" or failed to '
                           'get tree value, aborted.').format(tool_branch))
    return None

  def FindEbuildFile(self):
    """Find the ebuild files for the tools.

    Returns:
      True: if operation succeeds.
    """

    if self._gcc_branch:
      (rv, ef, efn) = self.FindToolEbuildFile('gcc')
      if rv:
        self._gcc_ebuild_file = ef
        self._gcc_ebuild_file_name = efn
      else:
        return False

    if self._binutils_branch:
      (rv, ef, efn) = self.FindToolEbuildFile('binutils')
      if rv:
        self._binutils_ebuild_file = ef
        self._binutils_ebuild_file_name = efn
      else:
        return False

    return True

  def FindToolEbuildFile(self, tool_name):
    """Find ebuild file for a specific tool.

    Args:
      tool_name: either "gcc" or "binutils".
    Returns:
      A triplet that consisits of whether operation succeeds or not,
      tool ebuild file full path and tool ebuild file name.
    """

    # To get the active gcc ebuild file, we need a workable chroot first.
    if not os.path.exists(os.path.join(
        self._chromeos_root, 'chroot')) and self._ce.RunCommand(
            'cd "{0}" && cros_sdk --create'.format(self._chromeos_root)):
      self._logger.LogError(('Failed to install a initial chroot, aborted.\n'
                             'If previous bootstrap failed, do a '
                             '"cros_sdk --delete" to remove '
                             'in-complete chroot.'))
      return (False, None, None)

    rv, stdout, _ = self._ce.ChrootRunCommandWOutput(
        self._chromeos_root,
        'equery w sys-devel/{0}'.format(tool_name),
        print_to_console=True)
    if rv:
      self._logger.LogError(('Failed to execute inside chroot '
                             '"equery w sys-devel/{0}", aborted.').format(
                                 tool_name))
      return (False, None, None)
    m = re.match(r'^.*/({0}/(.*\.ebuild))$'.format(EBUILD_PATH_PATTERN.format(
        tool_name)), stdout)
    if not m:
      self._logger.LogError(
          ('Failed to find {0} ebuild file, aborted. '
           'If previous bootstrap failed, do a "cros_sdk --delete" to remove '
           'in-complete chroot.').format(tool_name))
      return (False, None, None)
    tool_ebuild_file = os.path.join(self._chromeos_root, m.group(1))
    tool_ebuild_file_name = m.group(2)

    return (True, tool_ebuild_file, tool_ebuild_file_name)

  def InplaceModifyEbuildFile(self):
    """Modify the ebuild file.

    Returns:
      True if operation succeeds.
    """

    # Note we shall not use remote branch name (eg. "cros/gcc.gnu.org/...") in
    # CROS_WORKON_COMMIT, we have to use GITHASH. So we call GitGetCommitHash on
    # tool_branch.
    if self._gcc_branch:
      tool_branch_githash = misc.GitGetCommitHash(
          self.GetChromeOsToolDir('gcc'), self._gcc_branch)
      if not tool_branch_githash:
        return False
      if not self.InplaceModifyToolEbuildFile(
          tool_branch_githash, self._gcc_branch_tree, self._gcc_ebuild_file):
        return False

    if self._binutils_branch:
      tool_branch_githash = misc.GitGetCommitHash(
          self.GetChromeOsToolDir('binutils'), self._binutils_branch)
      if not self.InplaceModifyToolEbuildFile(tool_branch_githash,
                                              self._binutils_branch_tree,
                                              self._binutils_ebuild_file):
        return False
    return True

  @staticmethod
  def ResetToolEbuildFile(chromeos_root, tool_name):
    """Reset tool ebuild file to clean state.

    Args:
      chromeos_root: chromeos source tree
      tool_name: either "gcc" or "binutils"
    Returns:
      True if operation succeds.
    """
    rv = misc.GetGitChangesAsList(
        os.path.join(chromeos_root, CHROMIUMOS_OVERLAY_PATH),
        path=('sys-devel/{0}/{0}-*.ebuild'.format(tool_name)),
        staged=False)
    if rv:
      cmd = 'cd {0} && git checkout --'.format(os.path.join(
          chromeos_root, CHROMIUMOS_OVERLAY_PATH))
      for g in rv:
        cmd += ' ' + g
      rv = command_executer.GetCommandExecuter().RunCommand(cmd)
      if rv:
        logger.GetLogger().LogWarning(
            'Failed to reset the ebuild file. Please refer to log above.')
        return False
    else:
      logger.GetLogger().LogWarning(
          'Note - did not find any modified {0} ebuild file.'.format(tool_name))
      # Fall through
    return True

  def GetChromeOsToolDir(self, tool_name):
    """Return the chromeos git dir for a specific tool.

    Args:
      tool_name: either 'gcc' or 'binutils'.
    Returns:
      Absolute git path for the tool.
    """

    return os.path.join(self._chromeos_root,
                        REPO_PATH_PATTERN.format(tool_name))

  def InplaceModifyToolEbuildFile(self, tool_branch_githash, tool_branch_tree,
                                  tool_ebuild_file):
    """Using sed to fill properly values into the ebuild file.

    Args:
      tool_branch_githash: githash for tool_branch
      tool_branch_tree: treeish for the tool branch
      tool_ebuild_file: tool ebuild file
    Returns:
      True: if operation succeeded.
    """

    command = ('sed -i '
               '-e \'/^CROS_WORKON_COMMIT=".*"/i'
               ' # The following line is modified by script.\' '
               '-e \'s!^CROS_WORKON_COMMIT=".*"$!CROS_WORKON_COMMIT="{0}"!\' '
               '-e \'/^CROS_WORKON_TREE=".*"/i'
               ' # The following line is modified by script.\' '
               '-e \'s!^CROS_WORKON_TREE=".*"$!CROS_WORKON_TREE="{1}"!\' '
               '{2}').format(tool_branch_githash, tool_branch_tree,
                             tool_ebuild_file)
    rv = self._ce.RunCommand(command)
    if rv:
      self._logger.LogError(
          'Failed to modify commit and tree value for "{0}"", aborted.'.format(
              tool_ebuild_file))
      return False

    # Warn that the ebuild file has been modified.
    self._logger.LogWarning(
        ('Ebuild file "{0}" is modified, to revert the file - \n'
         'bootstrap_compiler.py --chromeos_root={1} '
         '--reset_tool_ebuild_file').format(tool_ebuild_file,
                                            self._chromeos_root))
    return True

  def DoBuildForBoard(self):
    """Build tool for a specific board.

    Returns:
      True if operation succeeds.
    """

    if self._gcc_branch:
      if not self.DoBuildToolForBoard('gcc'):
        return False
    if self._binutils_branch:
      if not self.DoBuildToolForBoard('binutils'):
        return False
    return True

  def DoBuildToolForBoard(self, tool_name):
    """Build a specific tool for a specific board.

    Args:
      tool_name: either "gcc" or "binutils"
    Returns:
      True if operation succeeds.
    """

    boards_to_build = self._board.split(',')

    failed = []
    for board in boards_to_build:
      if board == 'host':
        command = 'sudo emerge sys-devel/{0}'.format(tool_name)
      else:
        target = misc.GetCtargetFromBoard(board, self._chromeos_root)
        if not target:
          self._logger.LogError('Unsupported board "{0}", skip.'.format(board))
          failed.append(board)
          continue
        command = 'sudo emerge cross-{0}/{1}'.format(target, tool_name)

      rv = self._ce.ChrootRunCommand(self._chromeos_root,
                                     command,
                                     print_to_console=True)
      if rv:
        self._logger.LogError('Build {0} failed for {1}, aborted.'.format(
            tool_name, board))
        failed.append(board)
      else:
        self._logger.LogOutput('Successfully built {0} for board {1}.'.format(
            tool_name, board))

    if failed:
      self._logger.LogError(
          'Failed to build {0} for the following board(s): "{1}"'.format(
              tool_name, ' '.join(failed)))
      return False
    # All boards build successfully
    return True

  def DoBootstrapping(self):
    """Do bootstrapping the chroot.

    This step firstly downloads a prestine sdk, then use this sdk to build the
    new sdk, finally use the new sdk to build every host package.

    Returns:
      True if operation succeeds.
    """

    logfile = os.path.join(self._chromeos_root, 'bootstrap.log')
    command = 'cd "{0}" && cros_sdk --delete --bootstrap |& tee "{1}"'.format(
        self._chromeos_root, logfile)
    rv = self._ce.RunCommand(command, print_to_console=True)
    if rv:
      self._logger.LogError('Bootstrapping failed, log file - "{0}"\n'.format(
          logfile))
      return False

    self._logger.LogOutput('Bootstrap succeeded.')
    return True

  def BuildAndInstallAmd64Host(self):
    """Build amd64-host (host) packages.

    Build all host packages in the newly-bootstrapped 'chroot' using *NEW*
    toolchain.

    So actually we perform 2 builds of all host packages -
      1. build new toolchain using old toolchain and build all host packages
         using the newly built toolchain
      2. build the new toolchain again but using new toolchain built in step 1,
         and build all host packages using the newly built toolchain

    Returns:
      True if operation succeeds.
    """

    cmd = ('cd {0} && cros_sdk -- -- ./setup_board --board=amd64-host '
           '--accept_licenses=@CHROMEOS --skip_chroot_upgrade --nousepkg '
           '--reuse_pkgs_from_local_boards').format(self._chromeos_root)
    rv = self._ce.RunCommand(cmd, print_to_console=True)
    if rv:
      self._logger.LogError('Build amd64-host failed.')
      return False

    # Package amd64-host into 'built-sdk.tar.xz'.
    sdk_package = os.path.join(self._chromeos_root, 'built-sdk.tar.xz')
    cmd = ('cd {0}/chroot/build/amd64-host && sudo XZ_OPT="-e9" '
           'tar --exclude="usr/lib/debug/*" --exclude="packages/*" '
           '--exclude="tmp/*" --exclude="usr/local/build/autotest/*" '
           '--sparse -I xz -vcf {1} . && sudo chmod a+r {1}').format(
               self._chromeos_root, sdk_package)
    rv = self._ce.RunCommand(cmd, print_to_console=True)
    if rv:
      self._logger.LogError('Failed to create "built-sdk.tar.xz".')
      return False

    # Install amd64-host into a new chroot.
    cmd = ('cd {0} && cros_sdk --chroot new-sdk-chroot --download --replace '
           '--nousepkg --url file://{1}').format(self._chromeos_root,
                                                 sdk_package)
    rv = self._ce.RunCommand(cmd, print_to_console=True)
    if rv:
      self._logger.LogError('Failed to install "built-sdk.tar.xz".')
      return False
    self._logger.LogOutput(
        'Successfully installed built-sdk.tar.xz into a new chroot.\nAll done.')

    # Rename the newly created new-sdk-chroot to chroot.
    cmd = ('cd {0} && sudo mv chroot chroot-old && '
           'sudo mv new-sdk-chroot chroot').format(self._chromeos_root)
    rv = self._ce.RunCommand(cmd, print_to_console=True)
    return rv == 0

  def Do(self):
    """Entrance of the class.

    Returns:
      True if everything is ok.
    """

    if (self.SubmitToLocalBranch() and self.CheckoutBranch() and
        self.FindEbuildFile() and self.InplaceModifyEbuildFile()):
      if self._setup_tool_ebuild_file_only:
        # Everything is done, we are good.
        ret = True
      else:
        if self._board:
          ret = self.DoBuildForBoard()
        else:
          # This implies '--bootstrap'.
          ret = (self.DoBootstrapping() and (self._disable_2nd_bootstrap or
                                             self.BuildAndInstallAmd64Host()))
    else:
      ret = False
    return ret


def Main(argv):
  parser = optparse.OptionParser()
  parser.add_option('-c',
                    '--chromeos_root',
                    dest='chromeos_root',
                    help=('Optional. ChromeOs root dir. '
                          'When not specified, chromeos root will be deduced '
                          'from current working directory.'))
  parser.add_option('--gcc_branch',
                    dest='gcc_branch',
                    help=('The branch to test against. '
                          'This branch must be a local branch '
                          'inside "src/third_party/gcc". '
                          'Notice, this must not be used with "--gcc_dir".'))
  parser.add_option('--binutils_branch',
                    dest='binutils_branch',
                    help=('The branch to test against binutils. '
                          'This branch must be a local branch '
                          'inside "src/third_party/binutils". '
                          'Notice, this must not be used with '
                          '"--binutils_dir".'))
  parser.add_option('-g',
                    '--gcc_dir',
                    dest='gcc_dir',
                    help=('Use a local gcc tree to do bootstrapping. '
                          'Notice, this must not be used with "--gcc_branch".'))
  parser.add_option('--binutils_dir',
                    dest='binutils_dir',
                    help=('Use a local binutils tree to do bootstrapping. '
                          'Notice, this must not be used with '
                          '"--binutils_branch".'))
  parser.add_option('--fixperm',
                    dest='fixperm',
                    default=False,
                    action='store_true',
                    help=('Fix the (notorious) permission error '
                          'while trying to bootstrap the chroot. '
                          'Note this takes an extra 10-15 minutes '
                          'and is only needed once per chromiumos tree.'))
  parser.add_option('--setup_tool_ebuild_file_only',
                    dest='setup_tool_ebuild_file_only',
                    default=False,
                    action='store_true',
                    help=('Setup gcc and/or binutils ebuild file '
                          'to pick up the branch (--gcc/binutils_branch) or '
                          'use gcc and/or binutils source (--gcc/binutils_dir) '
                          'and exit. Keep chroot as is. This should not be '
                          'used with --gcc/binutils_dir/branch options.'))
  parser.add_option('--reset_tool_ebuild_file',
                    dest='reset_tool_ebuild_file',
                    default=False,
                    action='store_true',
                    help=('Reset the modification that is done by this script.'
                          'Note, when this script is running, it will modify '
                          'the active gcc/binutils ebuild file. Use this '
                          'option to reset (what this script has done) '
                          'and exit. This should not be used with -- '
                          'gcc/binutils_dir/branch options.'))
  parser.add_option('--board',
                    dest='board',
                    default=None,
                    help=('Only build toolchain for specific board(s). '
                          'Use "host" to build for host. '
                          'Use "," to seperate multiple boards. '
                          'This does not perform a chroot bootstrap.'))
  parser.add_option('--bootstrap',
                    dest='bootstrap',
                    default=False,
                    action='store_true',
                    help=('Performs a chroot bootstrap. '
                          'Note, this will *destroy* your current chroot.'))
  parser.add_option('--disable-2nd-bootstrap',
                    dest='disable_2nd_bootstrap',
                    default=False,
                    action='store_true',
                    help=('Disable a second bootstrap '
                          '(build of amd64-host stage).'))

  options = parser.parse_args(argv)[0]
  # Trying to deduce chromeos root from current directory.
  if not options.chromeos_root:
    logger.GetLogger().LogOutput('Trying to deduce chromeos root ...')
    wdir = os.getcwd()
    while wdir and wdir != '/':
      if misc.IsChromeOsTree(wdir):
        logger.GetLogger().LogOutput('Find chromeos_root: {}'.format(wdir))
        options.chromeos_root = wdir
        break
      wdir = os.path.dirname(wdir)

  if not options.chromeos_root:
    parser.error('Missing or failing to deduce mandatory option "--chromeos".')
    return 1

  options.chromeos_root = os.path.abspath(os.path.expanduser(
      options.chromeos_root))

  if not os.path.isdir(options.chromeos_root):
    logger.GetLogger().LogError('"{0}" does not exist.'.format(
        options.chromeos_root))
    return 1

  if options.fixperm:
    # Fix perm error before continuing.
    cmd = (
        r'sudo find "{0}" \( -name ".cache" -type d -prune \) -o '
        r'\( -name "chroot" -type d -prune \) -o '
        r'\( -type f -exec chmod a+r {{}} \; \) -o '
        r'\( -type d -exec chmod a+rx {{}} \; \)').format(options.chromeos_root)
    logger.GetLogger().LogOutput(
        'Fixing perm issues for chromeos root, this might take some time.')
    command_executer.GetCommandExecuter().RunCommand(cmd)

  if options.reset_tool_ebuild_file:
    if (options.gcc_dir or options.gcc_branch or options.binutils_dir or
        options.binutils_branch):
      logger.GetLogger().LogWarning(
          'Ignoring any "--gcc/binutils_dir" and/or "--gcc/binutils_branch".')
    if options.setup_tool_ebuild_file_only:
      logger.GetLogger().LogError(
          ('Conflict options "--reset_tool_ebuild_file" '
           'and "--setup_tool_ebuild_file_only".'))
      return 1
    rv = Bootstrapper.ResetToolEbuildFile(options.chromeos_root, 'gcc')
    rv1 = Bootstrapper.ResetToolEbuildFile(options.chromeos_root, 'binutils')
    return 0 if (rv and rv1) else 1

  if options.gcc_dir:
    options.gcc_dir = os.path.abspath(os.path.expanduser(options.gcc_dir))
    if not os.path.isdir(options.gcc_dir):
      logger.GetLogger().LogError('"{0}" does not exist.'.format(
          options.gcc_dir))
      return 1

  if options.gcc_branch and options.gcc_dir:
    parser.error('Only one of "--gcc_dir" and "--gcc_branch" can be specified.')
    return 1

  if options.binutils_dir:
    options.binutils_dir = os.path.abspath(os.path.expanduser(
        options.binutils_dir))
    if not os.path.isdir(options.binutils_dir):
      logger.GetLogger().LogError('"{0}" does not exist.'.format(
          options.binutils_dir))
      return 1

  if options.binutils_branch and options.binutils_dir:
    parser.error('Only one of "--binutils_dir" and '
                 '"--binutils_branch" can be specified.')
    return 1

  if (not (options.binutils_branch or options.binutils_dir or options.gcc_branch
           or options.gcc_dir)):
    parser.error(('At least one of "--gcc_dir", "--gcc_branch", '
                  '"--binutils_dir" and "--binutils_branch" must '
                  'be specified.'))
    return 1

  if not options.board and not options.bootstrap:
    parser.error('You must specify either "--board" or "--bootstrap".')
    return 1

  if (options.board and options.bootstrap and
      not options.setup_tool_ebuild_file_only):
    parser.error('You must specify only one of "--board" and "--bootstrap".')
    return 1

  if not options.bootstrap and options.disable_2nd_bootstrap:
    parser.error('"--disable-2nd-bootstrap" has no effect '
                 'without specifying "--bootstrap".')
    return 1

  if Bootstrapper(
      options.chromeos_root,
      gcc_branch=options.gcc_branch,
      gcc_dir=options.gcc_dir,
      binutils_branch=options.binutils_branch,
      binutils_dir=options.binutils_dir,
      board=options.board,
      disable_2nd_bootstrap=options.disable_2nd_bootstrap,
      setup_tool_ebuild_file_only=options.setup_tool_ebuild_file_only).Do():
    return 0
  return 1


if __name__ == '__main__':
  retval = Main(sys.argv)
  sys.exit(retval)
