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

"""Build stages related to a secondary workspace directory.

A workspace is a compelete ChromeOS checkout and may contain it's own chroot,
.cache directory, etc. Conceptually, cbuildbot_launch creates a workspace for
the intitial ChromeOS build, but these stages are for creating a secondary
build.

This might be useful if a build needs to work with more than one branch at a
time, or make changes to ChromeOS code without changing the code it is currently
running.

A secondary workspace may not be inside an existing ChromeOS repo checkout.
Also, the initial sync will usually take about 40 minutes, so performance should
be considered carefully.
"""

from __future__ import print_function

import os
import re

from chromite.cbuildbot import cbuildbot_run
from chromite.cbuildbot import commands
from chromite.cbuildbot import manifest_version
from chromite.cbuildbot import trybot_patch_pool
from chromite.cbuildbot.stages import artifact_stages
from chromite.cbuildbot.stages import generic_stages
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 cros_sdk_lib
from chromite.lib import failures_lib
from chromite.lib import gs
from chromite.lib import osutils
from chromite.lib import path_util
from chromite.lib import portage_util
from chromite.lib import request_build
from chromite.lib import retry_util
from chromite.lib import timeout_util
from chromite.lib.parser import package_info


BUILD_PACKAGES_PREBUILTS = '10774.0.0'
BUILD_PACKAGES_WITH_DEBUG_SYMBOLS = '6302.0.0'
CROS_RUN_UNITTESTS = '6773.0.0'
BUILD_IMAGE_BUILDER_PATH = '8183.0.0'
BUILD_IMAGE_ECLEAN_FLAG = '8318.0.0'
ANDROID_BREAKPAD = '9667.0.0'
SETUP_BOARD_PORT_COMPLETE = '11802.0.0'


class InvalidWorkspace(failures_lib.StepFailure):
  """Raised when a workspace isn't usable."""


def ChrootArgs(options):
  """cros_sdk command line arguments.

  To ensure consistent arguments passed into cros_sdk for workspace stages,
  compute them here.

  Args:
    options: self._run.options

  Returns:
    List of command line arguments, normally passed into run as chroot_args.
  """
  chroot_args = ['--cache-dir', options.cache_dir]
  if options.chrome_root:
    chroot_args += ['--chrome_root', options.chrome_root]

  return chroot_args


class WorkspaceStageBase(generic_stages.BuilderStage):
  """Base class for Workspace stages."""
  def __init__(self, builder_run, buildstore, build_root, **kwargs):
    """Initializer.

    Properties for subclasses:
      self._build_root to access the workspace directory,
      self._orig_root to access the original buildroot.

    Args:
      builder_run: BuilderRun object.
      buildstore: BuildStore instance to make DB calls with.
      build_root: Fully qualified path to use as a string.
    """
    super(WorkspaceStageBase, self).__init__(
        builder_run, buildstore, build_root=build_root,
        **kwargs)

    self._orig_root = builder_run.buildroot

  def GetWorkspaceRepo(self):
    """Fetch a repo object for the workspace.

    Returns:
      repository.RepoRepository instance for the workspace.
    """
    # TODO: Properly select the manifest. Currently hard coded to internal
    # branch checkouts.
    manifest_url = config_lib.GetSiteParams().MANIFEST_INT_URL

    # Workspace repos use the workspace URL / branch.
    return self.GetRepoRepository(
        manifest_repo_url=manifest_url,
        branch=self._run.config.workspace_branch)

  def GetWorkspaceVersionInfo(self):
    """Fetch a VersionInfo for the workspace.

    Only valid after the workspace has been synced.

    Returns:
      manifest-version.VersionInfo object based on the workspace checkout.
    """
    return manifest_version.VersionInfo.from_repo(self._build_root)

  def AfterLimit(self, limit):
    """Is worksapce version newer than cutoff limit?

    Args:
      limit: String version of format '123.0.0'

    Returns:
      bool: True if workspace has newer version than limit.
    """
    version_info = self.GetWorkspaceVersionInfo()
    return version_info > manifest_version.VersionInfo(limit)

  # Standardize manifest_versions paths for workspaces.

  @property
  def int_manifest_versions_path(self):
    """Path to use for internal manifest_versions."""
    return os.path.join(
        self._orig_root,
        config_lib.GetSiteParams().INTERNAL_MANIFEST_VERSIONS_PATH)

  @property
  def ext_manifest_versions_path(self):
    """Path to use for external manifest_versions."""
    return os.path.join(
        self._orig_root,
        config_lib.GetSiteParams().EXTERNAL_MANIFEST_VERSIONS_PATH)

  def GetWorkspaceReleaseTag(self):
    workspace_version_info = self.GetWorkspaceVersionInfo()

    if self._run.options.debug:
      build_identifier, _ = self._run.GetCIDBHandle()
      build_id = build_identifier.cidb_id
      return 'R%s-%s-b%s' % (
          workspace_version_info.chrome_branch,
          workspace_version_info.VersionString(),
          build_id)
    else:
      return 'R%s-%s' % (
          workspace_version_info.chrome_branch,
          workspace_version_info.VersionString())


class SyncStage(WorkspaceStageBase):
  """Perform a repo sync."""

  category = constants.CI_INFRA_STAGE

  def __init__(self, builder_run, buildstore, build_root,
               external=False,
               branch=None,
               version=None,
               patch_pool=None,
               copy_repo=None,
               **kwargs):
    """Initializer.

    Args:
      builder_run: BuilderRun object.
      buildstore: BuildStore instance to make DB calls with.
      build_root: Path to sync into.
      external: Boolean telling if this an internal or external checkout.
      branch: Branch to sync, with default to master.
      version: Version number to sync too.
      patch_pool: None or a list of lib.patch.GerritPatch objects.
      copy_repo: None, or the copy of a repo to seed the sync from.
    """
    super(SyncStage, self).__init__(
        builder_run, buildstore, build_root=build_root, **kwargs)

    self.external = external
    self.branch = branch
    self.version = version
    self.patch_pool = patch_pool
    self.copy_repo = copy_repo

  def PerformStage(self):
    """Sync stuff!"""
    logging.info('SubWorkspaceSync')

    cmd = [
        os.path.join(constants.CHROMITE_DIR, 'scripts', 'repo_sync_manifest'),
        '--repo-root', self._build_root,
        '--manifest-versions-int', self.int_manifest_versions_path,
        '--manifest-versions-ext', self.ext_manifest_versions_path,
    ]

    if self.external:
      cmd += ['--external']

    if self.branch and not self.version:
      cmd += ['--branch', self.branch]

    if self.version:
      logging.PrintBuildbotStepText('Version: %s' % self.version)
      cmd += ['--version', self.version]

    if self.patch_pool:
      patch_options = []
      for patch in self.patch_pool:
        logging.PrintBuildbotLink(str(patch), patch.url)
        patch_options += ['--gerrit-patches', patch.gerrit_number_str]

      cmd += patch_options

    if self.copy_repo:
      cmd += ['--copy-repo', self.copy_repo]

    assert not (self.version and self.patch_pool), (
        'Can\'t cherry-pick "%s" into an official version "%s."' %
        (patch_options, self.version))

    cros_build_lib.run(cmd)


class WorkspaceSyncStage(WorkspaceStageBase):
  """Checkout both infra and workspace repos."""

  category = constants.CI_INFRA_STAGE

  def PerformStage(self):
    """Sync all the stuff!"""
    # Select changes to cherry-pick into the build, and filter them into
    # chromite versus branch changes.
    patch_pool = trybot_patch_pool.TrybotPatchPool.FromOptions(
        gerrit_patches=self._run.options.gerrit_patches)

    infra_pool = patch_pool.FilterFn(trybot_patch_pool.ChromiteFilter)
    branch_pool = patch_pool.FilterFn(trybot_patch_pool.ChromiteFilter,
                                      negate=True)

    SyncStage(
        self._run,
        self.buildstore,
        build_root=self._orig_root,
        external=True,
        branch='master',
        patch_pool=infra_pool,
        suffix=' [Infra]').Run()

    branch = self._run.config.workspace_branch

    SyncStage(
        self._run,
        self.buildstore,
        build_root=self._build_root,
        external=not self._run.config.internal,
        branch=branch,
        version=self._run.options.force_version,
        patch_pool=branch_pool,
        copy_repo=self._orig_root,
        suffix=' [%s]' % branch).Run()


class WorkspaceSyncChromeStage(WorkspaceStageBase):
  """Stage that syncs Chrome sources if needed."""
  category = constants.PRODUCT_CHROME_STAGE

  # 6 hours in seconds should be long enough to fetch Chrome. I hope.
  SYNC_CHROME_TIMEOUT = 6 * 60 * 60

  def DetermineChromeVersion(self):
    cpv = portage_util.PortageqBestVisible(constants.CHROME_CP,
                                           cwd=self._build_root)
    return cpv.version_no_rev.partition('_')[0]


  @failures_lib.SetFailureType(failures_lib.InfrastructureFailure)
  def PerformStage(self):
    chrome_version = self.DetermineChromeVersion()

    logging.PrintBuildbotStepText('tag %s' % chrome_version)

    sync_chrome = os.path.join(
        self._orig_root, 'chromite', 'bin', 'sync_chrome')

    # Branched gclient can use git-cache incompatibly, so use a temp one.
    with osutils.TempDir(prefix='dummy') as git_cache:
      # --reset tells sync_chrome to blow away local changes and to feel
      # free to delete any directories that get in the way of syncing. This
      # is needed for unattended operation.
      # --gclient is not specified here, sync_chrome will locate the one
      # on the $PATH.
      cmd = [sync_chrome,
             '--reset',
             '--tag', chrome_version,
             '--git_cache_dir', git_cache]

      if constants.USE_CHROME_INTERNAL in self._run.config.useflags:
        cmd += ['--internal']

      cmd += [self._run.options.chrome_root]
      with timeout_util.Timeout(self.SYNC_CHROME_TIMEOUT):
        retry_util.RunCommandWithRetries(
            constants.SYNC_RETRIES, cmd, cwd=self._build_root)


class WorkspaceUprevAndPublishStage(WorkspaceStageBase):
  """Uprev ebuilds, and immediately publish them.

  This stage updates ebuilds to top of branch with no verification, or prebuilt
  generation. This is generally intended only for branch builds.
  """
  config = 'push_overlays'

  def __init__(self, builder_run, buildstore, boards=None, **kwargs):
    super(WorkspaceUprevAndPublishStage, self).__init__(builder_run,
                                                        buildstore,
                                                        **kwargs)
    if boards is not None:
      self._boards = boards

  def PerformStage(self):
    """Perform the uprev and push."""
    commands.UprevPackages(self._orig_root, self._boards,
                           overlay_type=self._run.config.overlays,
                           workspace=self._build_root)

    logging.info('Pushing.')
    commands.UprevPush(self._orig_root,
                       overlay_type=self._run.config.push_overlays,
                       dryrun=self._run.options.debug,
                       workspace=self._build_root)


class WorkspacePublishBuildspecStage(WorkspaceStageBase):
  """Increment the ChromeOS version, and publish a buildspec."""

  def PerformStage(self):
    """Increment ChromeOS version, and publish buildpec."""
    repo = self.GetWorkspaceRepo()

    # TODO: Add 'patch' support somehow,
    if repo.branch == 'master':
      incr_type = 'build'
    else:
      incr_type = 'branch'

    build_spec_path = manifest_version.GenerateAndPublishOfficialBuildSpec(
        repo,
        incr_type,
        manifest_versions_int=self.int_manifest_versions_path,
        manifest_versions_ext=self.ext_manifest_versions_path,
        dryrun=self._run.options.debug)

    if self._run.options.debug:
      msg = 'DEBUG: Would have defined: %s' % build_spec_path
    else:
      msg = 'Defined: %s' % build_spec_path

    logging.PrintBuildbotStepText(msg)


class WorkspaceScheduleChildrenStage(WorkspaceStageBase):
  """Schedule child builds for this buildspec."""

  def PerformStage(self):
    """Schedule child builds for this buildspec."""
    # build_identifier, _ = self._run.GetCIDBHandle()
    # build_id = build_identifier.cidb_id
    # master_buildbucket_id = self._run.options.buildbucket_id
    version_info = self.GetWorkspaceVersionInfo()

    extra_args = [
        '--buildbot',
        '--version', version_info.VersionString(),
    ]

    if self._run.options.debug:
      extra_args.append('--debug')

    for child_name in self._run.config.slave_configs:
      child = request_build.RequestBuild(
          build_config=child_name,
          # See crbug.com/940969. These id's get children killed during
          # multiple quick builds.
          # master_cidb_id=build_id,
          # master_buildbucket_id=master_buildbucket_id,
          extra_args=extra_args,
      )
      result = child.Submit(dryrun=self._run.options.debug)

      logging.info(
          'Build_name %s buildbucket_id %s created_timestamp %s',
          result.build_config, result.buildbucket_id, result.created_ts)
      logging.PrintBuildbotLink(result.build_config, result.url)


class WorkspaceInitSDKStage(WorkspaceStageBase):
  """Stage that is responsible for initializing the SDK."""

  category = constants.CI_INFRA_STAGE

  def PerformStage(self):
    chroot_path = os.path.join(self._build_root,
                               constants.DEFAULT_CHROOT_DIR)

    # Worksapce chroots are always wiped by cleanup stage, no need to update.
    cmd = ['cros_sdk', '--create'] + ChrootArgs(self._run.options)

    commands.RunBuildScript(self._build_root, cmd, chromite_cmd=True,
                            extra_env=self._portage_extra_env)

    post_ver = cros_sdk_lib.GetChrootVersion(chroot_path)
    logging.PrintBuildbotStepText(post_ver)


class WorkspaceUpdateSDKStage(generic_stages.BuilderStage):
  """Stage that is responsible for updating the chroot."""

  option_name = 'build'
  category = constants.CI_INFRA_STAGE

  def PerformStage(self):
    """Do the work of updating the chroot."""
    usepkg_toolchain = (
        self._run.config.usepkg_toolchain and not self._latest_toolchain)

    commands.UpdateChroot(
        self._build_root,
        usepkg=usepkg_toolchain,
        extra_env=self._portage_extra_env,
        chroot_args=['--cache-dir', self._run.options.cache_dir])


class WorkspaceSetupBoardStage(generic_stages.BoardSpecificBuilderStage,
                               WorkspaceStageBase):
  """Stage that is responsible for building host pkgs and setting up a board."""
  category = constants.CI_INFRA_STAGE

  def PerformStage(self):
    usepkg = self._run.config.usepkg_build_packages
    func = (commands.SetupBoard if self.AfterLimit(SETUP_BOARD_PORT_COMPLETE)
            else commands.LegacySetupBoard)
    func(
        self._build_root, board=self._current_board, usepkg=usepkg,
        force=self._run.config.board_replace,
        profile=self._run.options.profile or self._run.config.profile,
        chroot_upgrade=True,
        chroot_args=ChrootArgs(self._run.options),
        extra_env=self._portage_extra_env)


class WorkspaceBuildPackagesStage(generic_stages.BoardSpecificBuilderStage,
                                  WorkspaceStageBase):
  """Build Chromium OS packages."""

  category = constants.PRODUCT_OS_STAGE

  def PerformStage(self):
    usepkg = False
    if self.AfterLimit(BUILD_PACKAGES_PREBUILTS):
      usepkg = self._run.config.usepkg_build_packages

    packages = self.GetListOfPackagesToBuild()

    cmd = ['./build_packages', '--board=%s' % self._current_board,
           '--accept_licenses=@CHROMEOS', '--skip_chroot_upgrade']

    if not self._run.options.tests:
      cmd.append('--nowithautotest')

    if self.AfterLimit(BUILD_PACKAGES_WITH_DEBUG_SYMBOLS):
      cmd.append('--withdebugsymbols')

    if not usepkg:
      cmd.extend(commands.LOCAL_BUILD_FLAGS)

    if self._run.config.nobuildretry:
      cmd.append('--nobuildretry')

    cmd.extend(packages)

    commands.RunBuildScript(
        self._build_root, cmd,
        enter_chroot=True,
        chroot_args=ChrootArgs(self._run.options),
        extra_env=self._portage_extra_env)


class WorkspaceUnitTestStage(generic_stages.BoardSpecificBuilderStage,
                             WorkspaceStageBase):
  """Run unit tests."""
  option_name = 'tests'
  config_name = 'unittests'
  category = constants.PRODUCT_OS_STAGE

  # If the unit tests take longer than 90 minutes, abort. They usually take
  # thirty minutes to run, but they can take twice as long if the machine is
  # under load (e.g. in canary groups).
  #
  # If the processes hang, parallel_emerge will print a status report after 60
  # minutes, so we picked 90 minutes because it gives us a little buffer time.
  UNIT_TEST_TIMEOUT = 90 * 60

  def WaitUntilReady(self):
    """Decide if we should run the unittest stage."""
    # See crbug.com/937328.
    if not self.AfterLimit(CROS_RUN_UNITTESTS):
      logging.PrintBuildbotStepWarnings()
      logging.warning('cros_run_unit_tests does not exist on this branch.')
      return False

    return True

  def PerformStage(self):
    extra_env = {}
    if self._run.config.useflags:
      extra_env['USE'] = ' '.join(self._run.config.useflags)
    r = ' Reached UnitTestStage timeout.'
    with timeout_util.Timeout(self.UNIT_TEST_TIMEOUT, reason_message=r):
      try:
        commands.RunUnitTests(
            self._build_root,
            self._current_board,
            blacklist=self._run.config.unittest_blacklist,
            build_stage=self._run.config.build_packages,
            chroot_args=ChrootArgs(self._run.options),
            extra_env=extra_env)
      except failures_lib.BuildScriptFailure:
        logging.PrintBuildbotStepWarnings()
        logging.warning('Unittests failed. Ignored crbug.com/936123.')


class WorkspaceBuildImageStage(generic_stages.BoardSpecificBuilderStage,
                               WorkspaceStageBase):
  """Build standard Chromium OS images."""

  option_name = 'build'
  config_name = 'images'
  category = constants.PRODUCT_OS_STAGE

  def PerformStage(self):

    # Collect build_image arguments.
    version = self.GetWorkspaceReleaseTag()
    rootfs_verification = self._run.config.rootfs_verification
    disk_layout = self._run.config.disk_layout
    builder_path = '/'.join([self._bot_id, version])

    # We only build base, dev, and test images from this stage.
    images_can_build = set(['base', 'dev', 'test'])
    images_to_build = set(self._run.config.images).intersection(
        images_can_build)
    assert images_to_build

    # Build up command line.
    cmd = ['./build_image',
           '--board', self._current_board,
           '--replace',
           '--version', version]

    if self.AfterLimit(BUILD_IMAGE_ECLEAN_FLAG):
      cmd += ['--noeclean']

    if not rootfs_verification:
      cmd += ['--noenable_rootfs_verification']

    if disk_layout:
      cmd += ['--disk_layout', disk_layout]

    if self.AfterLimit(BUILD_IMAGE_BUILDER_PATH):
      cmd += ['--builder_path', builder_path]

    cmd += sorted(images_to_build)

    # Run command.
    commands.RunBuildScript(
        self._build_root,
        cmd,
        enter_chroot=True,
        extra_env=self._portage_extra_env,
        chroot_args=ChrootArgs(self._run.options))


class WorkspaceDebugSymbolsStage(WorkspaceStageBase,
                                 generic_stages.BoardSpecificBuilderStage,
                                 generic_stages.ArchivingStageMixin):
  """Handles generation & upload of debug symbols."""

  config_name = 'debug_symbols'
  category = constants.PRODUCT_OS_STAGE

  @failures_lib.SetFailureType(failures_lib.InfrastructureFailure)
  def PerformStage(self):
    """Generate debug symbols and upload debug.tgz."""
    buildroot = self._build_root
    board = self._current_board

    # Generate breakpad symbols of Chrome OS binaries.
    commands.GenerateBreakpadSymbols(
        buildroot, board,
        self._run.options.debug_forced,
        chroot_args=ChrootArgs(self._run.options),
        extra_env=self._portage_extra_env)

    # Download android symbols (if this build has them), and Generate
    # breakpad symbols of Android binaries. This must be done after
    # GenerateBreakpadSymbols because it clobbers the output
    # directory.
    symbols_file = self.DownloadAndroidSymbols()

    if symbols_file:
      try:
        commands.GenerateAndroidBreakpadSymbols(
            buildroot, board, symbols_file,
            chroot_args=ChrootArgs(self._run.options),
            extra_env=self._portage_extra_env)
      except failures_lib.BuildScriptFailure:
        # Android breakpad symbol preparation is expected to work in
        # modern branches.
        if self.AfterLimit(ANDROID_BREAKPAD):
          raise

        # For older branches, we only process them on a best effort basis.
        logging.PrintBuildbotStepWarnings()
        logging.warning('Preparing Android symbols failed, ignoring..')

    # Upload them.
    self.UploadDebugTarball()

    # Upload debug/breakpad tarball.
    self.UploadDebugBreakpadTarball()

    # Upload them to crash server.
    if self._run.config.upload_symbols:
      self.UploadSymbols(buildroot, board)

  def UploadDebugTarball(self):
    """Generate and upload the debug tarball."""
    filename = commands.GenerateDebugTarball(
        buildroot=self._build_root,
        board=self._current_board,
        archive_path=self.archive_path,
        gdb_symbols=self._run.config.archive_build_debug,
        archive_name='debug.tgz',
        chroot_compression=False)
    self.UploadArtifact(filename, archive=False)

  def UploadDebugBreakpadTarball(self):
    """Generate and upload the debug tarball with only breakpad files."""
    filename = commands.GenerateDebugTarball(
        buildroot=self._build_root,
        board=self._current_board,
        archive_path=self.archive_path,
        gdb_symbols=False,
        archive_name='debug_breakpad.tar.xz',
        chroot_compression=False)
    self.UploadArtifact(filename, archive=False)

  def UploadSymbols(self, buildroot, board):
    """Upload generated debug symbols."""
    failed_name = 'failed_upload_symbols.list'
    failed_list = os.path.join(self.archive_path, failed_name)

    if self._run.options.debug:
      # For debug builds, limit ourselves to just uploading 1 symbol.
      # This way trybots and such still exercise this code.
      cnt = 1
      official = False
    else:
      cnt = None
      official = self._run.config.chromeos_official

    upload_passed = True
    try:
      commands.UploadSymbols(
          buildroot, board, official, cnt, failed_list,
          chroot_args=ChrootArgs(self._run.options),
          extra_env=self._portage_extra_env)
    except failures_lib.BuildScriptFailure:
      upload_passed = False

    if os.path.exists(failed_list):
      self.UploadArtifact(failed_name, archive=False)

      logging.notice('To upload the missing symbols from this build, run:')
      for url in self._GetUploadUrls(filename=failed_name):
        logging.notice('upload_symbols --failed-list %s %s',
                       os.path.join(url, failed_name),
                       os.path.join(url, 'debug_breakpad.tar.xz'))

    # Delay throwing the exception until after we uploaded the list.
    if not upload_passed:
      raise artifact_stages.DebugSymbolsUploadException(
          'Failed to upload all symbols.')

  def DetermineAndroidPackage(self):
    """Returns the active Android container package in use by the board.

    Workspace version of cbuildbot_run.DetermineAndroidPackage().

    Returns:
      String identifier for a package, or None
    """
    packages = portage_util.GetPackageDependencies(
        self._current_board, 'virtual/target-os',
        buildroot=self._build_root)

    android_packages = {p for p in packages
                        if p.startswith('chromeos-base/android-container-') or
                        p.startswith('chromeos-base/android-vm-')}

    assert len(android_packages) <= 1

    if android_packages:
      return next(iter(android_packages))
    else:
      return None

  def DetermineAndroidBranch(self, package):
    """Returns the Android branch in use by the active container ebuild.

    Workspace version of cbuildbot_run.DetermineAndroidBranch().

    Args:
      package: String name of Android package to get branch of.

    Returns:
      String with the android container branch name.
    """
    ebuild_path = portage_util.FindEbuildForBoardPackage(
        package, self._current_board, buildroot=self._build_root)
    host_ebuild_path = path_util.FromChrootPath(ebuild_path,
                                                source_path=self._build_root)
    # We assume all targets pull from the same branch and that we always
    # have at least one of the following targets.
    targets = constants.ANDROID_ALL_BUILD_TARGETS
    ebuild_content = osutils.SourceEnvironment(host_ebuild_path, targets)
    logging.info('Got ebuild env: %s', ebuild_content)
    for target in targets:
      if target in ebuild_content:
        branch = re.search(r'(.*?)-linux-', ebuild_content[target])
        if branch is not None:
          return branch.group(1)
    raise cbuildbot_run.NoAndroidBranchError(
        'Android branch could not be determined for %s (ebuild empty?)' %
        ebuild_path)

  def DetermineAndroidVersion(self, package):
    """Determine the current Android version in buildroot now and return it.

    This uses the typical portage logic to determine which version of Android
    is active right now in the buildroot.

    Workspace version of cbuildbot_run.DetermineAndroidVersion().

    Args:
      package: String name of Android package to get version of.

    Returns:
      The Android build ID of the container for the boards.
    """
    cpv = package_info.SplitCPV(package)
    return cpv.version_no_rev

  def DetermineAndroidABI(self):
    """Returns the Android ABI in use by the active container ebuild.

    Workspace version of cbuildbot_run.DetermineAndroidABI().

    Args:
      package: String name of Android package to get ABI version of.

    Returns:
      string defining ABI of the container.
    """
    use_flags = portage_util.GetInstalledPackageUseFlags(
        'sys-devel/arc-build', self._current_board,
        buildroot=self._build_root)
    if 'abi_x86_64' in use_flags.get('sys-devel/arc-build', []):
      return 'x86_64'
    elif 'abi_x86_32' in use_flags.get('sys-devel/arc-build', []):
      return 'x86'
    else:
      # ARM only supports 32-bit so it does not have abi_x86_{32,64} set. But it
      # is also the last possible ABI, so returning by default.
      return 'arm'

  def DetermineAndroidVariant(self, package):
    """Returns the Android variant in use by the active container ebuild."""

    all_use_flags = portage_util.GetInstalledPackageUseFlags(
        package, self._current_board, buildroot=self._build_root)
    for use_flags in all_use_flags.values():
      for use_flag in use_flags:
        if 'cheets_userdebug' in use_flag or 'cheets_sdk_userdebug' in use_flag:
          return 'userdebug'
        elif 'cheets_user' in use_flag or 'cheets_sdk_user' in use_flag:
          # TODO(b/120999609): bertha builds always download userdebug builds
          # at the moment because user builds are broken. Remove this clause
          # when resolved.
          if self.DetermineAndroidTarget(package) == 'bertha':
            return 'userdebug'
          return 'user'

    # We iterated through all the flags and could not find user or userdebug.
    # This should not be possible given that this code is only ran by
    # builders, which will never use local images.
    raise cbuildbot_run.NoAndroidVariantError(
        'Android Variant cannot be determined for the packge: %s' %
        package)

  def DetermineAndroidTarget(self, package):
    if package.startswith('chromeos-base/android-vm-'):
      return 'bertha'
    if package.startswith('chromeos-base/android-container-'):
      return 'cheets'

    raise cbuildbot_run.NoAndroidTargetError(
        'Android Target cannot be determined for the package: %s' %
        package)

  def DownloadAndroidSymbols(self):
    """Helper to download android container symbols, as needed.

    Determines which, if any, Android container this build includes, and
    downloads it's symbols.

    Returns:
      path to downloaded symbols file, or None if not downloaded.
    """
    android_package = self.DetermineAndroidPackage()
    if not android_package:
      logging.info('Android is not enabled on this board. Skipping symbols.')
      return None

    android_build_branch = self.DetermineAndroidBranch(android_package)
    android_version = self.DetermineAndroidVersion(android_package)
    arch = self.DetermineAndroidABI()
    variant = self.DetermineAndroidVariant(android_package)
    android_target = self.DetermineAndroidTarget(android_package)
    # For user builds, there are no suffix.
    # For userdebug builds, there is an explicit '_userdebug' suffix.
    suffix = ''
    if variant != 'user':
      suffix = '_' + variant

    logging.info(
        'Downloading symbols of Android %s (%s)...',
        android_version, android_build_branch)

    symbols_file_url = constants.ANDROID_SYMBOLS_URL_TEMPLATE % {
        'branch': android_build_branch,
        'target': android_target,
        'arch': arch,
        'version': android_version,
        'variant': variant,
        'suffix': suffix}

    # Should be based on self.archive_path, but we need a path inside
    # the workspace chroot, not infra chroot.
    symbols_file = os.path.join(self._build_root,
                                'buildbot_archive',
                                constants.ANDROID_SYMBOLS_FILE)
    gs_context = gs.GSContext()
    gs_context.Copy(symbols_file_url, symbols_file)

    return symbols_file
