# 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.

"""This script is used to upload host prebuilts as well as board BINHOSTS.

Prebuilts are uploaded using gsutil to Google Storage. After these prebuilts
are successfully uploaded, a file is updated with the proper BINHOST version.

To read more about prebuilts/binhost binary packages please refer to:
http://goto/chromeos-prebuilts

Example of uploading prebuilt amd64 host files to Google Storage:
upload_prebuilts -p /b/cbuild/build -s -u gs://chromeos-prebuilt

Example of uploading x86-dogfood binhosts to Google Storage:
upload_prebuilts -b x86-dogfood -p /b/cbuild/build/ -u gs://chromeos-prebuilt -g
"""

from __future__ import print_function

import datetime
import functools
import glob
import multiprocessing
import os
import sys
import tempfile

from chromite.cbuildbot import constants
from chromite.cbuildbot import commands
from chromite.lib import binpkg
from chromite.lib import commandline
from chromite.lib import cros_build_lib
from chromite.lib import cros_logging as logging
from chromite.lib import git
from chromite.lib import gs
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import portage_util
from chromite.lib import toolchain

# How many times to retry uploads.
_RETRIES = 10

# Multiplier for how long to sleep (in seconds) between retries; will delay
# (1*sleep) the first time, then (2*sleep), continuing via attempt * sleep.
_SLEEP_TIME = 60

# The length of time (in seconds) that Portage should wait before refetching
# binpkgs from the same binhost. We don't ever modify binhosts, so this should
# be something big.
_BINPKG_TTL = 60 * 60 * 24 * 365

_HOST_PACKAGES_PATH = 'chroot/var/lib/portage/pkgs'
_CATEGORIES_PATH = 'chroot/etc/portage/categories'
_PYM_PATH = 'chroot/usr/lib/portage/pym'
_HOST_ARCH = 'amd64'
_BOARD_PATH = 'chroot/build/%(board)s'
_REL_BOARD_PATH = 'board/%(target)s/%(version)s'
_REL_HOST_PATH = 'host/%(host_arch)s/%(target)s/%(version)s'
# Private overlays to look at for builds to filter
# relative to build path
_PRIVATE_OVERLAY_DIR = 'src/private-overlays'
_GOOGLESTORAGE_GSUTIL_FILE = 'googlestorage_acl.txt'
_BINHOST_BASE_URL = 'gs://chromeos-prebuilt'
_PREBUILT_BASE_DIR = 'src/third_party/chromiumos-overlay/chromeos/config/'
# Created in the event of new host targets becoming available
_PREBUILT_MAKE_CONF = {'amd64': os.path.join(_PREBUILT_BASE_DIR,
                                             'make.conf.amd64-host')}


class BuildTarget(object):
  """A board/variant/profile tuple."""

  def __init__(self, board_variant, profile=None):
    self.board_variant = board_variant
    self.board, _, self.variant = board_variant.partition('_')
    self.profile = profile

  def __str__(self):
    if self.profile:
      return '%s_%s' % (self.board_variant, self.profile)
    else:
      return self.board_variant

  def __eq__(self, other):
    return str(other) == str(self)

  def __hash__(self):
    return hash(str(self))


def UpdateLocalFile(filename, value, key='PORTAGE_BINHOST'):
  """Update the key in file with the value passed.

  File format:
    key="value"
  Note quotes are added automatically

  Args:
    filename: Name of file to modify.
    value: Value to write with the key.
    key: The variable key to update. (Default: PORTAGE_BINHOST)

  Returns:
    True if changes were made to the file.
  """
  if os.path.exists(filename):
    file_fh = open(filename)
  else:
    file_fh = open(filename, 'w+')
  file_lines = []
  found = False
  made_changes = False
  keyval_str = '%(key)s=%(value)s'
  for line in file_fh:
    # Strip newlines from end of line. We already add newlines below.
    line = line.rstrip("\n")

    if len(line.split('=')) != 2:
      # Skip any line that doesn't fit key=val.
      file_lines.append(line)
      continue

    file_var, file_val = line.split('=')
    if file_var == key:
      found = True
      print('Updating %s=%s to %s="%s"' % (file_var, file_val, key, value))
      value = '"%s"' % value
      made_changes |= (file_val != value)
      file_lines.append(keyval_str % {'key': key, 'value': value})
    else:
      file_lines.append(keyval_str % {'key': file_var, 'value': file_val})

  if not found:
    value = '"%s"' % value
    made_changes = True
    file_lines.append(keyval_str % {'key': key, 'value': value})

  file_fh.close()
  # write out new file
  osutils.WriteFile(filename, '\n'.join(file_lines) + '\n')
  return made_changes


def RevGitFile(filename, data, retries=5, dryrun=False):
  """Update and push the git file.

  Args:
    filename: file to modify that is in a git repo already
    data: A dict of key/values to update in |filename|
    retries: The number of times to retry before giving up, default: 5
    dryrun: If True, do not actually commit the change.
  """
  prebuilt_branch = 'prebuilt_branch'
  cwd = os.path.abspath(os.path.dirname(filename))
  commit = git.RunGit(cwd, ['rev-parse', 'HEAD']).output.rstrip()
  description = '%s: updating %s' % (os.path.basename(filename),
                                     ', '.join(data.keys()))
  # UpdateLocalFile will print out the keys/values for us.
  print('Revving git file %s' % filename)

  try:
    git.CreatePushBranch(prebuilt_branch, cwd)
    for key, value in data.iteritems():
      UpdateLocalFile(filename, value, key)
    git.RunGit(cwd, ['add', filename])
    git.RunGit(cwd, ['commit', '-m', description])
    git.PushWithRetry(prebuilt_branch, cwd, dryrun=dryrun, retries=retries)
  finally:
    git.RunGit(cwd, ['checkout', commit])


def GetVersion():
  """Get the version to put in LATEST and update the git version with."""
  return datetime.datetime.now().strftime('%Y.%m.%d.%H%M%S')


def _GsUpload(gs_context, acl, local_file, remote_file):
  """Upload to GS bucket.

  Args:
    gs_context: A lib.gs.GSContext instance.
    acl: The ACL to use for uploading the file.
    local_file: The local file to be uploaded.
    remote_file: The remote location to upload to.
  """
  CANNED_ACLS = ['public-read', 'private', 'bucket-owner-read',
                 'authenticated-read', 'bucket-owner-full-control',
                 'public-read-write']
  if acl in CANNED_ACLS:
    gs_context.Copy(local_file, remote_file, acl=acl)
  else:
    # For private uploads we assume that the overlay board is set up properly
    # and a googlestore_acl.xml is present. Otherwise, this script errors.
    # We set version=0 here to ensure that the ACL is set only once (see
    # http://b/15883752#comment54).
    try:
      gs_context.Copy(local_file, remote_file, version=0)
    except gs.GSContextPreconditionFailed as ex:
      # If we received a GSContextPreconditionFailed error, we know that the
      # file exists now, but we don't know whether our specific update
      # succeeded. See http://b/15883752#comment62
      logging.warning(
          'Assuming upload succeeded despite PreconditionFailed errors: %s', ex)

    if acl.endswith('.xml'):
      # Apply the passed in ACL xml file to the uploaded object.
      gs_context.SetACL(remote_file, acl=acl)
    else:
      gs_context.ChangeACL(remote_file, acl_args_file=acl)


def RemoteUpload(gs_context, acl, files, pool=10):
  """Upload to google storage.

  Create a pool of process and call _GsUpload with the proper arguments.

  Args:
    gs_context: A lib.gs.GSContext instance.
    acl: The canned acl used for uploading. acl can be one of: "public-read",
         "public-read-write", "authenticated-read", "bucket-owner-read",
         "bucket-owner-full-control", or "private".
    files: dictionary with keys to local files and values to remote path.
    pool: integer of maximum proesses to have at the same time.

  Returns:
    Return a set of tuple arguments of the failed uploads
  """
  upload = functools.partial(_GsUpload, gs_context, acl)
  tasks = [[key, value] for key, value in files.iteritems()]
  parallel.RunTasksInProcessPool(upload, tasks, pool)


def GenerateUploadDict(base_local_path, base_remote_path, pkgs):
  """Build a dictionary of local remote file key pairs to upload.

  Args:
    base_local_path: The base path to the files on the local hard drive.
    base_remote_path: The base path to the remote paths.
    pkgs: The packages to upload.

  Returns:
    Returns a dictionary of local_path/remote_path pairs
  """
  upload_files = {}
  for pkg in pkgs:
    suffix = pkg['CPV'] + '.tbz2'
    local_path = os.path.join(base_local_path, suffix)
    assert os.path.exists(local_path), '%s does not exist' % local_path
    upload_files[local_path] = os.path.join(base_remote_path, suffix)

    if pkg.get('DEBUG_SYMBOLS') == 'yes':
      debugsuffix = pkg['CPV'] + '.debug.tbz2'
      local_path = os.path.join(base_local_path, debugsuffix)
      assert os.path.exists(local_path)
      upload_files[local_path] = os.path.join(base_remote_path, debugsuffix)

  return upload_files


def GetBoardOverlay(build_path, target):
  """Get the path to the board variant.

  Args:
    build_path: The path to the root of the build directory
    target: The target board as a BuildTarget object.

  Returns:
    The last overlay configured for the given board as a string.
  """
  board = target.board_variant
  overlays = portage_util.FindOverlays(constants.BOTH_OVERLAYS, board,
                                       buildroot=build_path)
  # We only care about the last entry.
  return overlays[-1]


def DeterminePrebuiltConfFile(build_path, target):
  """Determine the prebuilt.conf file that needs to be updated for prebuilts.

  Args:
    build_path: The path to the root of the build directory
    target: String representation of the board. This includes host and board
      targets

  Returns:
    A string path to a prebuilt.conf file to be updated.
  """
  if _HOST_ARCH == target:
    # We are host.
    # Without more examples of hosts this is a kludge for now.
    # TODO(Scottz): as new host targets come online expand this to
    # work more like boards.
    make_path = _PREBUILT_MAKE_CONF[target]
  else:
    # We are a board
    board = GetBoardOverlay(build_path, target)
    make_path = os.path.join(board, 'prebuilt.conf')

  return make_path


def UpdateBinhostConfFile(path, key, value):
  """Update binhost config file file with key=value.

  Args:
    path: Filename to update.
    key: Key to update.
    value: New value for key.
  """
  cwd, filename = os.path.split(os.path.abspath(path))
  osutils.SafeMakedirs(cwd)
  if not git.GetCurrentBranch(cwd):
    git.CreatePushBranch(constants.STABLE_EBUILD_BRANCH, cwd, sync=False)
  osutils.WriteFile(path, '', mode='a')
  if UpdateLocalFile(path, value, key):
    desc = '%s: %s %s' % (filename, 'updating' if value else 'clearing', key)
    git.AddPath(path)
    git.Commit(cwd, desc)

def GenerateHtmlIndex(files, index, board, version):
  """Given the list of |files|, generate an index.html at |index|.

  Args:
    files: The list of files to link to.
    index: The path to the html index.
    board: Name of the board this index is for.
    version: Build version this index is for.
  """
  head = """<html>
<head>
 <title>Package Prebuilt Index: %(board)s / %(version)s</title>
</head>
<body>
<h2>Package Prebuilt Index: %(board)s / %(version)s</h2>"""
  head %= {
      'board': board,
      'version': version,
  }

  files = files + [
      '.|Google Storage Index',
      '..|',
  ]
  commands.GenerateHtmlIndex(index, files, head=head)


def _GrabAllRemotePackageIndexes(binhost_urls):
  """Grab all of the packages files associated with a list of binhost_urls.

  Args:
    binhost_urls: The URLs for the directories containing the Packages files we
                  want to grab.

  Returns:
    A list of PackageIndex objects.
  """
  pkg_indexes = []
  for url in binhost_urls:
    pkg_index = binpkg.GrabRemotePackageIndex(url)
    if pkg_index:
      pkg_indexes.append(pkg_index)
  return pkg_indexes


class PrebuiltUploader(object):
  """Synchronize host and board prebuilts."""

  def __init__(self, upload_location, acl, binhost_base_url, pkg_indexes,
               build_path, packages, skip_upload, binhost_conf_dir, dryrun,
               target, slave_targets, version):
    """Constructor for prebuilt uploader object.

    This object can upload host or prebuilt files to Google Storage.

    Args:
      upload_location: The upload location.
      acl: The canned acl used for uploading to Google Storage. acl can be one
           of: "public-read", "public-read-write", "authenticated-read",
           "bucket-owner-read", "bucket-owner-full-control", "project-private",
           or "private" (see "gsutil help acls"). If we are not uploading to
           Google Storage, this parameter is unused.
      binhost_base_url: The URL used for downloading the prebuilts.
      pkg_indexes: Old uploaded prebuilts to compare against. Instead of
          uploading duplicate files, we just link to the old files.
      build_path: The path to the directory containing the chroot.
      packages: Packages to upload.
      skip_upload: Don't actually upload the tarballs.
      binhost_conf_dir: Directory where to store binhost.conf files.
      dryrun: Don't push or upload prebuilts.
      target: BuildTarget managed by this builder.
      slave_targets: List of BuildTargets managed by slave builders.
      version: A unique string, intended to be included in the upload path,
          which identifies the version number of the uploaded prebuilts.
    """
    self._upload_location = upload_location
    self._acl = acl
    self._binhost_base_url = binhost_base_url
    self._pkg_indexes = pkg_indexes
    self._build_path = build_path
    self._packages = set(packages)
    self._found_packages = set()
    self._skip_upload = skip_upload
    self._binhost_conf_dir = binhost_conf_dir
    self._dryrun = dryrun
    self._target = target
    self._slave_targets = slave_targets
    self._version = version
    self._gs_context = gs.GSContext(retries=_RETRIES, sleep=_SLEEP_TIME,
                                    dry_run=self._dryrun)

  def _Upload(self, local_file, remote_file):
    """Wrapper around _GsUpload"""
    _GsUpload(self._gs_context, self._acl, local_file, remote_file)

  def _ShouldFilterPackage(self, pkg):
    if not self._packages:
      return False
    pym_path = os.path.abspath(os.path.join(self._build_path, _PYM_PATH))
    sys.path.insert(0, pym_path)
    # pylint: disable=F0401
    import portage.versions
    cat, pkgname = portage.versions.catpkgsplit(pkg['CPV'])[0:2]
    cp = '%s/%s' % (cat, pkgname)
    self._found_packages.add(cp)
    return pkgname not in self._packages and cp not in self._packages

  def _UploadPrebuilt(self, package_path, url_suffix):
    """Upload host or board prebuilt files to Google Storage space.

    Args:
      package_path: The path to the packages dir.
      url_suffix: The remote subdirectory where we should upload the packages.
    """
    # Process Packages file, removing duplicates and filtered packages.
    pkg_index = binpkg.GrabLocalPackageIndex(package_path)
    pkg_index.SetUploadLocation(self._binhost_base_url, url_suffix)
    pkg_index.RemoveFilteredPackages(self._ShouldFilterPackage)
    uploads = pkg_index.ResolveDuplicateUploads(self._pkg_indexes)
    unmatched_pkgs = self._packages - self._found_packages
    if unmatched_pkgs:
      logging.warning('unable to match packages: %r' % unmatched_pkgs)

    # Write Packages file.
    pkg_index.header['TTL'] = _BINPKG_TTL
    tmp_packages_file = pkg_index.WriteToNamedTemporaryFile()

    remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
    assert remote_location.startswith('gs://')

    # Build list of files to upload. Manually include the dev-only files but
    # skip them if not present.
    # TODO(deymo): Upload dev-only-extras.tbz2 as dev-only-extras.tar.bz2
    # outside packages/ directory. See crbug.com/448178 for details.
    if os.path.exists(os.path.join(package_path, 'dev-only-extras.tbz2')):
      uploads.append({'CPV': 'dev-only-extras'})
    upload_files = GenerateUploadDict(package_path, remote_location, uploads)
    remote_file = '%s/Packages' % remote_location.rstrip('/')
    upload_files[tmp_packages_file.name] = remote_file

    RemoteUpload(self._gs_context, self._acl, upload_files)

    with tempfile.NamedTemporaryFile(
        prefix='chromite.upload_prebuilts.index.') as index:
      GenerateHtmlIndex(
          [x[len(remote_location) + 1:] for x in upload_files.values()],
          index.name, self._target, self._version)
      self._Upload(index.name, '%s/index.html' % remote_location.rstrip('/'))

      link_name = 'Prebuilts[%s]: %s' % (self._target, self._version)
      url = '%s%s/index.html' % (gs.PUBLIC_BASE_HTTPS_URL,
                                 remote_location[len(gs.BASE_GS_URL):])
      cros_build_lib.PrintBuildbotLink(link_name, url)

  def _UploadSdkTarball(self, board_path, url_suffix, prepackaged,
                        board_overlay_tarballs, board_overlay_upload_path,
                        toolchain_tarballs, toolchain_upload_path):
    """Upload a tarball of the sdk at the specified path to Google Storage.

    Args:
      board_path: The path to the board dir.
      url_suffix: The remote subdirectory where we should upload the packages.
      prepackaged: If given, a tarball that has been packaged outside of this
                   script and should be used.
      board_overlay_tarballs: List of board-specific overlay tarball
        specifications to upload. Items take the form "board:/path/to/tarball".
      board_overlay_upload_path: Path template under the bucket to place
        board-specific overlay tarballs.
      toolchain_tarballs: List of toolchain tarballs to upload.
      toolchain_upload_path: Path under the bucket to place toolchain tarballs.
    """
    remote_location = '%s/%s' % (self._upload_location.rstrip('/'), url_suffix)
    assert remote_location.startswith('gs://')
    boardname = os.path.basename(board_path.rstrip('/'))
    # We do not upload non SDK board tarballs,
    assert boardname == constants.CHROOT_BUILDER_BOARD
    assert prepackaged is not None

    version_str = self._version[len('chroot-'):]
    remote_tarfile = toolchain.GetSdkURL(
        for_gsutil=True, suburl='cros-sdk-%s.tar.xz' % (version_str,))
    # For SDK, also upload the manifest which is guaranteed to exist
    # by the builderstage.
    self._Upload(prepackaged + '.Manifest', remote_tarfile + '.Manifest')
    self._Upload(prepackaged, remote_tarfile)

    # Upload board-specific SDK overlays and toolchain tarballs, if given.
    for tarball_list, upload_path, qualifier_name in (
        (board_overlay_tarballs, board_overlay_upload_path, 'board'),
        (toolchain_tarballs, toolchain_upload_path, 'target')):
      for tarball in tarball_list:
        qualifier_val, local_path = tarball.split(':')
        suburl = upload_path % {qualifier_name: qualifier_val}
        remote_path = toolchain.GetSdkURL(for_gsutil=True, suburl=suburl)
        self._Upload(local_path, remote_path)

    # Finally, also update the pointer to the latest SDK on which polling
    # scripts rely.
    with osutils.TempDir() as tmpdir:
      pointerfile = os.path.join(tmpdir, 'cros-sdk-latest.conf')
      remote_pointerfile = toolchain.GetSdkURL(for_gsutil=True,
                                               suburl='cros-sdk-latest.conf')
      osutils.WriteFile(pointerfile, 'LATEST_SDK="%s"' % version_str)
      self._Upload(pointerfile, remote_pointerfile)

  def _GetTargets(self):
    """Retuns the list of targets to use."""
    targets = self._slave_targets[:]
    if self._target:
      targets.append(self._target)

    return targets

  def SyncHostPrebuilts(self, key, git_sync, sync_binhost_conf):
    """Synchronize host prebuilt files.

    This function will sync both the standard host packages, plus the host
    packages associated with all targets that have been "setup" with the
    current host's chroot. For instance, if this host has been used to build
    x86-generic, it will sync the host packages associated with
    'i686-pc-linux-gnu'. If this host has also been used to build arm-generic,
    it will also sync the host packages associated with
    'armv7a-cros-linux-gnueabi'.

    Args:
      key: The variable key to update in the git file.
      git_sync: If set, update make.conf of target to reference the latest
          prebuilt packages generated here.
      sync_binhost_conf: If set, update binhost config file in
          chromiumos-overlay for the host.
    """
    # Slave boards are listed before the master board so that the master board
    # takes priority (i.e. x86-generic preflight host prebuilts takes priority
    # over preflight host prebuilts from other builders.)
    binhost_urls = []
    for target in self._GetTargets():
      url_suffix = _REL_HOST_PATH % {'version': self._version,
                                     'host_arch': _HOST_ARCH,
                                     'target': target}
      packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')

      if self._target == target and not self._skip_upload:
        # Upload prebuilts.
        package_path = os.path.join(self._build_path, _HOST_PACKAGES_PATH)
        self._UploadPrebuilt(package_path, packages_url_suffix)

      # Record URL where prebuilts were uploaded.
      binhost_urls.append('%s/%s/' % (self._binhost_base_url.rstrip('/'),
                                      packages_url_suffix.rstrip('/')))

    binhost = ' '.join(binhost_urls)
    if git_sync:
      git_file = os.path.join(self._build_path, _PREBUILT_MAKE_CONF[_HOST_ARCH])
      RevGitFile(git_file, {key: binhost}, dryrun=self._dryrun)
    if sync_binhost_conf:
      binhost_conf = os.path.join(
          self._binhost_conf_dir, 'host', '%s-%s.conf' % (_HOST_ARCH, key))
      UpdateBinhostConfFile(binhost_conf, key, binhost)

  def SyncBoardPrebuilts(self, key, git_sync, sync_binhost_conf,
                         upload_board_tarball, prepackaged_board,
                         board_overlay_tarballs, board_overlay_upload_path,
                         toolchain_tarballs, toolchain_upload_path):
    """Synchronize board prebuilt files.

    Args:
      key: The variable key to update in the git file.
      git_sync: If set, update make.conf of target to reference the latest
          prebuilt packages generated here.
      sync_binhost_conf: If set, update binhost config file in
          chromiumos-overlay for the current board.
      upload_board_tarball: Include a tarball of the board in our upload.
      prepackaged_board: A tarball of the board built outside of this script.
      board_overlay_tarballs: List of board-specific overlay tarball
        specifications to upload. Items take the form "board:/path/to/tarball".
      board_overlay_upload_path: Path template under the bucket to place
        board-specific overlay tarballs.
      toolchain_tarballs: A list of toolchain tarballs to upload.
      toolchain_upload_path: Path under the bucket to place toolchain tarballs.
    """
    updated_binhosts = set()
    for target in self._GetTargets():
      board_path = os.path.join(self._build_path,
                                _BOARD_PATH % {'board': target.board_variant})
      package_path = os.path.join(board_path, 'packages')
      url_suffix = _REL_BOARD_PATH % {'target': target,
                                      'version': self._version}
      packages_url_suffix = '%s/packages' % url_suffix.rstrip('/')

      # Process the target board differently if it is the main --board.
      if self._target == target and not self._skip_upload:
        # This strips "chroot" prefix because that is sometimes added as the
        # --prepend-version argument (e.g. by chromiumos-sdk bot).
        # TODO(build): Clean it up to be less hard-coded.
        version_str = self._version[len('chroot-'):]

        # Upload board tarballs in the background.
        if upload_board_tarball:
          if toolchain_upload_path:
            toolchain_upload_path %= {'version': version_str}
          if board_overlay_upload_path:
            board_overlay_upload_path %= {'version': version_str}
          tar_process = multiprocessing.Process(
              target=self._UploadSdkTarball,
              args=(board_path, url_suffix, prepackaged_board,
                    board_overlay_tarballs, board_overlay_upload_path,
                    toolchain_tarballs, toolchain_upload_path))
          tar_process.start()

        # Upload prebuilts.
        self._UploadPrebuilt(package_path, packages_url_suffix)

        # Make sure we finished uploading the board tarballs.
        if upload_board_tarball:
          tar_process.join()
          assert tar_process.exitcode == 0
          # TODO(zbehan): This should be done cleaner.
          if target.board == constants.CHROOT_BUILDER_BOARD:
            sdk_conf = os.path.join(self._binhost_conf_dir,
                                    'host/sdk_version.conf')
            sdk_settings = {
                'SDK_LATEST_VERSION': version_str,
                'TC_PATH': toolchain_upload_path,
            }
            RevGitFile(sdk_conf, sdk_settings, dryrun=self._dryrun)

      # Record URL where prebuilts were uploaded.
      url_value = '%s/%s/' % (self._binhost_base_url.rstrip('/'),
                              packages_url_suffix.rstrip('/'))

      if git_sync:
        git_file = DeterminePrebuiltConfFile(self._build_path, target)
        RevGitFile(git_file, {key: url_value}, dryrun=self._dryrun)

      if sync_binhost_conf:
        # Update the binhost configuration file in git.
        binhost_conf = os.path.join(
            self._binhost_conf_dir, 'target', '%s-%s.conf' % (target, key))
        updated_binhosts.add(binhost_conf)
        UpdateBinhostConfFile(binhost_conf, key, url_value)

    if sync_binhost_conf:
      # Clear all old binhosts. The files must be left empty in case anybody
      # is referring to them.
      all_binhosts = set(glob.glob(os.path.join(
          self._binhost_conf_dir, 'target', '*-%s.conf' % key)))
      for binhost_conf in all_binhosts - updated_binhosts:
        UpdateBinhostConfFile(binhost_conf, key, '')


def _AddSlaveBoard(_option, _opt_str, value, parser):
  """Callback that adds a slave board to the list of slave targets."""
  parser.values.slave_targets.append(BuildTarget(value))


def _AddSlaveProfile(_option, _opt_str, value, parser):
  """Callback that adds a slave profile to the list of slave targets."""
  if not parser.values.slave_targets:
    parser.error('Must specify --slave-board before --slave-profile')
  if parser.values.slave_targets[-1].profile is not None:
    parser.error('Cannot specify --slave-profile twice for same board')
  parser.values.slave_targets[-1].profile = value


def ParseOptions(argv):
  """Returns options given by the user and the target specified.

  Args:
    argv: The args to parse.

  Returns:
    A tuple containing a parsed options object and BuildTarget.
    The target instance is None if no board is specified.
  """
  parser = commandline.OptionParser()
  parser.add_option('-H', '--binhost-base-url', dest='binhost_base_url',
                    default=_BINHOST_BASE_URL,
                    help='Base URL to use for binhost in make.conf updates')
  parser.add_option('', '--previous-binhost-url', action='append',
                    default=[], dest='previous_binhost_url',
                    help='Previous binhost URL')
  parser.add_option('-b', '--board', dest='board', default=None,
                    help='Board type that was built on this machine')
  parser.add_option('-B', '--prepackaged-tarball', dest='prepackaged_tarball',
                    default=None,
                    help='Board tarball prebuilt outside of this script.')
  parser.add_option('--board-overlay-tarball', dest='board_overlay_tarballs',
                    action='append', default=[],
                    help='Board-specific toolchain overlay tarball to upload. '
                    'Takes the form "board:/path/to/tarball".')
  parser.add_option('--board-overlay-upload-path', default='',
                    help='Path template for uploading board overlays.')
  parser.add_option('--toolchain-tarball', dest='toolchain_tarballs',
                    action='append', default=[],
                    help='Redistributable toolchain tarball.')
  parser.add_option('--toolchain-upload-path', default='',
                    help='Path to place toolchain tarballs in the sdk tree.')
  parser.add_option('', '--profile', dest='profile', default=None,
                    help='Profile that was built on this machine')
  parser.add_option('', '--slave-board', default=[], action='callback',
                    dest='slave_targets', type='string',
                    callback=_AddSlaveBoard,
                    help='Board type that was built on a slave machine. To '
                         'add a profile to this board, use --slave-profile.')
  parser.add_option('', '--slave-profile', action='callback', type='string',
                    callback=_AddSlaveProfile,
                    help='Board profile that was built on a slave machine. '
                         'Applies to previous slave board.')
  parser.add_option('-p', '--build-path', dest='build_path',
                    help='Path to the directory containing the chroot')
  parser.add_option('', '--packages', action='append',
                    default=[], dest='packages',
                    help='Only include the specified packages. '
                         '(Default is to include all packages.)')
  parser.add_option('-s', '--sync-host', dest='sync_host',
                    default=False, action='store_true',
                    help='Sync host prebuilts')
  parser.add_option('-g', '--git-sync', dest='git_sync',
                    default=False, action='store_true',
                    help='Enable git version sync (This commits to a repo.) '
                         'This is used by full builders to commit directly '
                         'to board overlays.')
  parser.add_option('-u', '--upload', dest='upload',
                    default=None,
                    help='Upload location')
  parser.add_option('-V', '--prepend-version', dest='prepend_version',
                    default=None,
                    help='Add an identifier to the front of the version')
  parser.add_option('-f', '--filters', dest='filters', action='store_true',
                    default=False,
                    help='Turn on filtering of private ebuild packages')
  parser.add_option('-k', '--key', dest='key',
                    default='PORTAGE_BINHOST',
                    help='Key to update in make.conf / binhost.conf')
  parser.add_option('', '--set-version', dest='set_version',
                    default=None,
                    help='Specify the version string')
  parser.add_option('', '--sync-binhost-conf', dest='sync_binhost_conf',
                    default=False, action='store_true',
                    help='Update binhost.conf in chromiumos-overlay or '
                         'chromeos-overlay. Commit the changes, but don\'t '
                         'push them. This is used for preflight binhosts.')
  parser.add_option('', '--binhost-conf-dir', dest='binhost_conf_dir',
                    help='Directory to commit binhost config with '
                         '--sync-binhost-conf.')
  parser.add_option('-P', '--private', dest='private', action='store_true',
                    default=False, help='Mark gs:// uploads as private.')
  parser.add_option('', '--skip-upload', dest='skip_upload',
                    action='store_true', default=False,
                    help='Skip upload step.')
  parser.add_option('', '--upload-board-tarball', dest='upload_board_tarball',
                    action='store_true', default=False,
                    help='Upload board tarball to Google Storage.')
  parser.add_option('-n', '--dry-run', dest='dryrun',
                    action='store_true', default=False,
                    help='Don\'t push or upload prebuilts.')

  options, args = parser.parse_args(argv)
  if not options.build_path:
    parser.error('you need provide a chroot path')
  if not options.upload and not options.skip_upload:
    parser.error('you need to provide an upload location using -u')
  if not options.set_version and options.skip_upload:
    parser.error('If you are using --skip-upload, you must specify a '
                 'version number using --set-version.')
  if args:
    parser.error('invalid arguments passed to upload_prebuilts: %r' % args)

  target = None
  if options.board:
    target = BuildTarget(options.board, options.profile)

  if target in options.slave_targets:
    parser.error('--board/--profile must not also be a slave target.')

  if len(set(options.slave_targets)) != len(options.slave_targets):
    parser.error('--slave-boards must not have duplicates.')

  if options.slave_targets and options.git_sync:
    parser.error('--slave-boards is not compatible with --git-sync')

  if (options.upload_board_tarball and options.skip_upload and
      options.board == 'amd64-host'):
    parser.error('--skip-upload is not compatible with '
                 '--upload-board-tarball and --board=amd64-host')

  if (options.upload_board_tarball and not options.skip_upload and
      not options.upload.startswith('gs://')):
    parser.error('--upload-board-tarball only works with gs:// URLs.\n'
                 '--upload must be a gs:// URL.')

  if options.upload_board_tarball and options.prepackaged_tarball is None:
    parser.error('--upload-board-tarball requires --prepackaged-tarball')

  if options.private:
    if options.sync_host:
      parser.error('--private and --sync-host/-s cannot be specified '
                   'together; we do not support private host prebuilts')

    if not options.upload or not options.upload.startswith('gs://'):
      parser.error('--private is only valid for gs:// URLs; '
                   '--upload must be a gs:// URL.')

    if options.binhost_base_url != _BINHOST_BASE_URL:
      parser.error('when using --private the --binhost-base-url '
                   'is automatically derived.')

  if options.sync_binhost_conf and not options.binhost_conf_dir:
    parser.error('--sync-binhost-conf requires --binhost-conf-dir')

  if options.board_overlay_tarballs and not options.board_overlay_upload_path:
    parser.error('--board-overlay-tarball requires --board-overlay-upload-path')

  return options, target


def main(argv):
  # Set umask to a sane value so that files created as root are readable.
  os.umask(0o22)

  options, target = ParseOptions(argv)

  # Calculate a list of Packages index files to compare against. Whenever we
  # upload a package, we check to make sure it's not already stored in one of
  # the packages files we uploaded. This list of packages files might contain
  # both board and host packages.
  pkg_indexes = _GrabAllRemotePackageIndexes(options.previous_binhost_url)

  if options.set_version:
    version = options.set_version
  else:
    version = GetVersion()

  if options.prepend_version:
    version = '%s-%s' % (options.prepend_version, version)

  acl = 'public-read'
  binhost_base_url = options.binhost_base_url

  if options.private:
    binhost_base_url = options.upload
    if target:
      acl = portage_util.FindOverlayFile(_GOOGLESTORAGE_GSUTIL_FILE,
                                         board=target.board_variant,
                                         buildroot=options.build_path)
      if acl is None:
        cros_build_lib.Die('No Google Storage ACL file %s found in %s overlay.',
                           _GOOGLESTORAGE_GSUTIL_FILE, target.board_variant)

  binhost_conf_dir = None
  if options.binhost_conf_dir:
    binhost_conf_dir = os.path.join(options.build_path,
                                    options.binhost_conf_dir)

  uploader = PrebuiltUploader(options.upload, acl, binhost_base_url,
                              pkg_indexes, options.build_path,
                              options.packages, options.skip_upload,
                              binhost_conf_dir, options.dryrun,
                              target, options.slave_targets, version)

  if options.sync_host:
    uploader.SyncHostPrebuilts(options.key, options.git_sync,
                               options.sync_binhost_conf)

  if options.board or options.slave_targets:
    uploader.SyncBoardPrebuilts(options.key, options.git_sync,
                                options.sync_binhost_conf,
                                options.upload_board_tarball,
                                options.prepackaged_tarball,
                                options.board_overlay_tarballs,
                                options.board_overlay_upload_path,
                                options.toolchain_tarballs,
                                options.toolchain_upload_path)
