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

"""Toolchain and related functionality."""

import base64
import collections
import datetime
import glob
import json
import logging
import os
import re
import shutil
from typing import Iterable, Optional

from chromite.cbuildbot import afdo
from chromite.lib import alerts
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import git
from chromite.lib import gob_util
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 timeout_util
from chromite.lib.parser import package_info
from chromite.utils import pformat


class PrepareForBuildReturn(object):
  """Return values for PrepareForBuild call."""
  UNSPECIFIED = 0
  # Build is necessary to generate artifacts.
  NEEDED = 1
  # Defer to other artifacts.  Used primarily for aggregation of artifact
  # results.
  UNKNOWN = 2
  # Artifacts are already generated.  The build is pointless.
  POINTLESS = 3


# URLs
# FIXME(tcwang): Remove access to GS buckets from this lib.
# There are plans in the future to remove all network
# operations from chromite, including access to GS buckets.
# Need to use build API and recipes to communicate to GS buckets in
# the future.
ORDERFILE_GS_URL_UNVETTED = (
    'gs://chromeos-toolchain-artifacts/orderfile/unvetted')
ORDERFILE_GS_URL_VETTED = 'gs://chromeos-prebuilt/afdo-job/orderfiles/vetted'
BENCHMARK_AFDO_GS_URL = (
    'gs://chromeos-toolchain-artifacts/afdo/unvetted/benchmark')
CWP_AFDO_GS_URL = 'gs://chromeos-prebuilt/afdo-job/cwp/chrome/'
KERNEL_PROFILE_URL = 'gs://chromeos-prebuilt/afdo-job/cwp/kernel/'
AFDO_GS_URL_VETTED = 'gs://chromeos-prebuilt/afdo-job/vetted/'
KERNEL_AFDO_GS_URL_VETTED = os.path.join(AFDO_GS_URL_VETTED, 'kernel')
BENCHMARK_AFDO_GS_URL_VETTED = os.path.join(AFDO_GS_URL_VETTED, 'benchmarks')
CWP_AFDO_GS_URL_VETTED = os.path.join(AFDO_GS_URL_VETTED, 'cwp')
RELEASE_AFDO_GS_URL_VETTED = os.path.join(AFDO_GS_URL_VETTED, 'release')

# Constants
AFDO_SUFFIX = '.afdo'
BZ2_COMPRESSION_SUFFIX = '.bz2'
XZ_COMPRESSION_SUFFIX = '.xz'
KERNEL_AFDO_COMPRESSION_SUFFIX = '.gcov.xz'
# FIXME: we should only use constants.SOURCE_ROOT and use
# path_util.ToChrootPath to convert to inchroot path when needed. So we
# need fix all the use cases for this variable (we can remove all but one
# when legacy is retired).
TOOLCHAIN_UTILS_PATH = os.path.join(constants.CHROOT_SOURCE_ROOT,
                                    'src/third_party/toolchain-utils')
AFDO_PROFILE_PATH_IN_CHROMIUM = 'src/chromeos/profiles/%s.afdo.newest.txt'
MERGED_AFDO_NAME = 'chromeos-chrome-amd64-%s'

# How old can the Kernel AFDO data be? (in days).
KERNEL_ALLOWED_STALE_DAYS = 42
# How old can the Kernel AFDO data be before sheriff got noticed? (in days).
KERNEL_WARN_STALE_DAYS = 14

# For merging release Chrome profiles.
RELEASE_CWP_MERGE_WEIGHT = 75
RELEASE_BENCHMARK_MERGE_WEIGHT = 100 - RELEASE_CWP_MERGE_WEIGHT

# Paths used in AFDO generation.
_AFDO_GENERATE_LLVM_PROF = '/usr/bin/create_llvm_prof'
_CHROME_DEBUG_BIN = os.path.join('%(root)s', '%(sysroot)s/usr/lib/debug',
                                 'opt/google/chrome/chrome.debug')

# Set of boards that can generate the AFDO profile (can generate 'perf'
# data with LBR events). Currently, it needs to be a device that has
# at least 4GB of memory.
#
# This must be consistent with the definitions in autotest.
AFDO_DATA_GENERATORS_LLVM = ('chell')
CHROME_AFDO_VERIFIER_BOARDS = {'chell': 'atom', 'eve': 'bigcore'}
KERNEL_AFDO_VERIFIER_BOARDS = {
    'chell': '3.18',
    'eve': '4.4',
    'octopus': '4.14',
    'banon': '4.19'
}

AFDO_ALERT_RECIPIENTS = ['chromeos-toolchain-oncall1@google.com']

# Full path to the chromiumos-overlay directory.
_CHROMIUMOS_OVERLAY = os.path.join(constants.CHROMITE_DIR, '..',
                                   constants.CHROMIUMOS_OVERLAY_DIR)

# RegExps
# NOTE: These regexp are copied from cbuildbot/afdo.py. Keep two copies
# until deployed and then remove the one in cbuildbot/afdo.py.
CHROOT_ROOT = os.path.join('%(build_root)s', constants.DEFAULT_CHROOT_DIR)
CHROOT_TMP_DIR = os.path.join('%(root)s', 'tmp')
AFDO_VARIABLE_REGEX = r'AFDO_FILE\["%s"\]'
AFDO_ARTIFACT_EBUILD_REGEX = r'^(?P<bef>%s=)(?P<name>("[^"]*"|.*))(?P<aft>.*)'
AFDO_ARTIFACT_EBUILD_REPL = r'\g<bef>"%s"\g<aft>'

ChromeVersion = collections.namedtuple(
    'ChromeVersion', ['major', 'minor', 'build', 'patch', 'revision'])

BENCHMARK_PROFILE_NAME_REGEX = r"""
       ^chromeos-chrome-amd64-
       (\d+)\.                    # Major
       (\d+)\.                    # Minor
       (\d+)\.                    # Build
       (\d+)                      # Patch
       (?:_rc)?-r(\d+)            # Revision
       (-merged)?\.
       afdo(?:\.bz2)?$            # We don't care about the presence of .bz2,
                                  # so we use the ignore-group '?:' operator.
"""

BenchmarkProfileVersion = collections.namedtuple(
    'BenchmarkProfileVersion',
    ['major', 'minor', 'build', 'patch', 'revision', 'is_merged'])

CWP_PROFILE_NAME_REGEX = r"""
      ^R(\d+)-                      # Major
       (\d+)\.                      # Build
       (\d+)-                       # Patch
       (\d+)                        # Clock; breaks ties sometimes.
       (?:\.afdo|\.gcov)?           # Optional: CWP for Chrome has `afdo`,
                                    # and kernel has `gcov`. Also this regex
                                    # is also used to match names in ebuild and
                                    # sometimes names in ebuild don't have
                                    # suffix.
       (?:\.xz)?$                   # We don't care about the presence of xz
    """

CWPProfileVersion = collections.namedtuple('CWPProfileVersion',
                                           ['major', 'build', 'patch', 'clock'])

MERGED_PROFILE_NAME_REGEX = r"""
      ^chromeos-chrome
      -(?:orderfile|amd64)                       # prefix for either orderfile
                                                 # or release profile.
      # CWP parts
      -(?:field|atom|bigcore)                    # Valid names
      -(\d+)                                     # Major
      -(\d+)                                     # Build
      \.(\d+)                                    # Patch
      -(\d+)                                     # Clock; breaks ties sometimes.
      # Benchmark parts
      -benchmark
      -(\d+)                                     # Major
      \.(\d+)                                    # Minor
      \.(\d+)                                    # Build
      \.(\d+)                                    # Patch
      -r(\d+)                                    # Revision
      (?:\.orderfile|-redacted\.afdo)            # suffix for either orderfile
                                                 # or release profile.
      (?:\.xz)?$
"""

CHROME_ARCH_VERSION = '%(package)s-%(arch)s-%(version)s'
CHROME_PERF_AFDO_FILE = '%(package)s-%(arch)s-%(versionnorev)s.perf.data'
CHROME_BENCHMARK_AFDO_FILE = '%s%s' % (CHROME_ARCH_VERSION, AFDO_SUFFIX)
CHROME_DEBUG_BINARY_NAME = '%s.debug' % CHROME_ARCH_VERSION


class Error(Exception):
  """Base module error class."""


class PrepareForBuildHandlerError(Error):
  """Error for PrepareForBuildHandler class."""


class BundleArtifactsHandlerError(Error):
  """Error for BundleArtifactsHandler class."""


class GetUpdatedFilesForCommitError(Error):
  """Error for GetUpdatedFilesForCommit class."""


class NoArtifactsToBundleError(Error):
  """Error for bundling empty collection of artifacts."""


class GenerateChromeOrderfileError(Error):
  """Error for GenerateChromeOrderfile class."""


class ProfilesNameHelperError(Error):
  """Error for helper functions related to profile naming."""


class GenerateBenchmarkAFDOProfilesError(Error):
  """Error for GenerateBenchmarkAFDOProfiles class."""


class UpdateEbuildWithAFDOArtifactsError(Error):
  """Error for UpdateEbuildWithAFDOArtifacts class."""


class PublishVettedAFDOArtifactsError(Error):
  """Error for publishing vetted afdo artifacts."""


def _ParseBenchmarkProfileName(profile_name):
  """Parse the name of a benchmark profile for Chrome.

  Examples:
    with input: profile_name='chromeos-chrome-amd64-77.0.3849.0_rc-r1.afdo'
    the function returns:
    BenchmarkProfileVersion(
      major=77, minor=0, build=3849, patch=0, revision=1, is_merged=False)

  Args:
    profile_name: The name of a benchmark profile.

  Returns:
    Named tuple of BenchmarkProfileVersion. With the input above, returns
  """
  pattern = re.compile(BENCHMARK_PROFILE_NAME_REGEX, re.VERBOSE)
  match = pattern.match(profile_name)
  if not match:
    raise ProfilesNameHelperError('Unparseable benchmark profile name: %s' %
                                  profile_name)

  groups = match.groups()
  version_groups = groups[:-1]
  is_merged = groups[-1]
  return BenchmarkProfileVersion(
      *[int(x) for x in version_groups], is_merged=bool(is_merged))


def _ParseCWPProfileName(profile_name):
  """Parse the name of a CWP profile for Chrome.

  Examples:
    With input profile_name='R77-3809.38-1562580965.afdo',
    the function returns:
    CWPProfileVersion(major=77, build=3809, patch=38, clock=1562580965)

  Args:
    profile_name: The name of a CWP profile.

  Returns:
    Named tuple of CWPProfileVersion.
  """
  pattern = re.compile(CWP_PROFILE_NAME_REGEX, re.VERBOSE)
  match = pattern.match(profile_name)
  if not match:
    raise ProfilesNameHelperError('Unparseable CWP profile name: %s' %
                                  profile_name)
  return CWPProfileVersion(*[int(x) for x in match.groups()])


def _ParseMergedProfileName(artifact_name):
  """Parse the name of an orderfile or a release profile for Chrome.

  Examples:
    With input: profile_name='chromeos-chrome-orderfile
    -field-77-3809.38-1562580965
    -benchmark-77.0.3849.0_rc-r1.orderfile.xz'
    the function returns:
    (BenchmarkProfileVersion(
     major=77, minor=0, build=3849, patch=0, revision=1, is_merged=False),
     CWPProfileVersion(major=77, build=3809, patch=38, clock=1562580965))

  Args:
    artifact_name: The name of an orderfile, or a release AFDO profile.

  Returns:
    A tuple of (BenchmarkProfileVersion, CWPProfileVersion)
  """
  pattern = re.compile(MERGED_PROFILE_NAME_REGEX, re.VERBOSE)
  match = pattern.match(artifact_name)
  if not match:
    raise ProfilesNameHelperError('Unparseable merged AFDO name: %s' %
                                  artifact_name)
  groups = match.groups()
  cwp_groups = groups[:4]
  benchmark_groups = groups[4:]
  return (BenchmarkProfileVersion(
      *[int(x) for x in benchmark_groups],
      is_merged=False), CWPProfileVersion(*[int(x) for x in cwp_groups]))


def _FindEbuildPath(package, buildroot=None, board=None):
  """Find the path to ebuild (in chroot or outside).

  Args:
    package: Name of the package. chromeos-chrome or chromeos-kernel-X_XX.
    buildroot: Optional. The path to build root, when used outside chroot.
    When omitted, the return path is relative inside chroot.
    board: Optional. A string of the name of the board.

  Returns:
    The full path to the versioned ebuild file. The path is either
    relative inside chroot, or outside chroot, depending on the buildroot arg.
  """
  valid_package_names = [
      'chromeos-kernel-' + x.replace('.', '_')
      for x in KERNEL_AFDO_VERIFIER_BOARDS.values()
  ] + ['chromeos-chrome']
  if package not in valid_package_names:
    raise ValueError('Invalid package name %s to look up ebuild.' % package)

  if board:
    equery_prog = 'equery-%s' % board
  else:
    equery_prog = 'equery'
  equery_cmd = [equery_prog, 'w', package]
  ebuild_file = cros_build_lib.run(
      equery_cmd, enter_chroot=True, stdout=True,
      encoding='utf-8').output.rstrip()
  if not buildroot:
    return ebuild_file

  basepath = '/mnt/host/source'
  if not ebuild_file.startswith(basepath):
    raise ValueError('Unexpected ebuild path: %s' % ebuild_file)
  ebuild_path = os.path.relpath(ebuild_file, basepath)
  return os.path.join(buildroot, ebuild_path)


def _GetArtifactVersionInChromium(arch, chrome_root):
  """Find the version (name) of AFDO artifact from chromium source.

  Args:
    arch: There are two AFDO profiles in chromium: atom or bigcore
    chrome_root: The path to Chrome root.

  Returns:
    The name of the AFDO artifact found in the chroot.
    None if not found.

  Raises:
    ValueError: when "arch" is not a supported.
    RuntimeError: when the file containing AFDO profile name can't be found.
  """
  if arch not in list(CHROME_AFDO_VERIFIER_BOARDS.values()):
    raise ValueError('Invalid architecture %s to use in AFDO profile' % arch)

  if not os.path.exists(chrome_root):
    raise RuntimeError('chrome_root %s does not exist.' % chrome_root)

  profile_file = os.path.join(chrome_root, AFDO_PROFILE_PATH_IN_CHROMIUM % arch)
  if not os.path.exists(profile_file):
    logging.info(
        'Files in chrome_root profile: %r',
        os.listdir(
            os.path.join(chrome_root, AFDO_PROFILE_PATH_IN_CHROMIUM % arch,
                         '..')))
    raise RuntimeError('File %s containing profile name does not exist' %
                       (profile_file,))

  return osutils.ReadFile(profile_file)


def _GetArtifactVersionInEbuild(package, variable, buildroot=None):
  """Find the version (name) of AFDO artifact from files in ebuild.

  Args:
    package: The name of the package to search in ebuild.
    variable: Use this variable directly as regex to search.
    buildroot: Optional. When omitted, search ebuild file inside
    chroot. Otherwise, use the path to search ebuild file outside.

  Returns:
    The name of the AFDO artifact found in the ebuild.
    None if not found.
  """
  ebuild_file = _FindEbuildPath(package, buildroot=buildroot)
  pattern = re.compile(AFDO_ARTIFACT_EBUILD_REGEX % variable)
  with open(ebuild_file) as f:
    for line in f:
      matched = pattern.match(line)
      if matched:
        ret = matched.group('name')
        if ret.startswith('"') and ret.endswith('"'):
          return ret[1:-1]
        return ret

  logging.info('%s is not found in the ebuild: %s', variable, ebuild_file)
  return None


def _GetCombinedAFDOName(cwp_versions, cwp_arch, benchmark_versions):
  """Construct a name mixing CWP and benchmark AFDO names.

  Examples:
    If benchmark AFDO is BenchmarkProfileVersion(
      major=77, minor=0, build=3849, patch=0, revision=1, is_merged=False)
    and CWP AFDO is CWPProfileVersion(
      major=77, build=3809, patch=38, clock=1562580965),
    and cwp_arch is 'atom',
    the returned name is:
    atom-77-3809.38-1562580965-benchmark-77.0.3849.0-r1

  Args:
    cwp_versions: CWP profile as a namedtuple CWPProfileVersion.
    cwp_arch: Architecture used to differentiate CWP profiles.
    benchmark_versions: Benchmark profile as a namedtuple
    BenchmarkProfileVersion.

  Returns:
    A name using the combination of CWP + benchmark AFDO names.
  """
  cwp_piece = '%s-%d-%d.%d-%d' % (cwp_arch, cwp_versions.major,
                                  cwp_versions.build, cwp_versions.patch,
                                  cwp_versions.clock)
  benchmark_piece = 'benchmark-%d.%d.%d.%d-r%d' % (
      benchmark_versions.major, benchmark_versions.minor,
      benchmark_versions.build, benchmark_versions.patch,
      benchmark_versions.revision)
  return '%s-%s' % (cwp_piece, benchmark_piece)


def _GetOrderfileName(chrome_root):
  """Construct an orderfile name for the current Chrome OS checkout.

  Args:
    chrome_root: The path to chrome_root.

  Returns:
    An orderfile name using CWP + benchmark AFDO name.
  """
  benchmark_afdo_version, cwp_afdo_version = _ParseMergedProfileName(
      _GetArtifactVersionInChromium(arch='atom', chrome_root=chrome_root))
  return 'chromeos-chrome-orderfile-%s' % (
      _GetCombinedAFDOName(cwp_afdo_version, 'field', benchmark_afdo_version))


def _GetBenchmarkAFDOName(buildroot, board):
  """Constructs a benchmark AFDO name for the current build root.

  Args:
    buildroot: The path to build root.
    board: The name of the board.

  Returns:
    A string similar to: chromeos-chrome-amd64-77.0.3849.0_rc-r1.afdo
  """
  cpv = portage_util.PortageqBestVisible(constants.CHROME_CP, cwd=buildroot)
  arch = portage_util.PortageqEnvvar('ARCH', board=board, allow_undefined=True)
  afdo_spec = {'package': cpv.package, 'arch': arch, 'version': cpv.version}
  afdo_file = CHROME_BENCHMARK_AFDO_FILE % afdo_spec
  try:
    _ParseBenchmarkProfileName(afdo_file)
  except ProfilesNameHelperError:
    # We want to avoid uploading a profile with an unparsable name. There's no
    # reason to upload a profile with unparsable name because no builds can
    # use it anyway. See crbug.com/1048725 for such instances.
    raise ValueError('Invalid to use %s as AFDO name because of unparsable' %
                     afdo_file)
  return afdo_file


def _CompressAFDOFiles(targets, input_dir, output_dir, suffix):
  """Compress files using AFDO compression type.

  Args:
    targets: List of files to compress. Only the basename is needed.
    input_dir: Paths to the targets (outside chroot). If None, use
    the targets as full path.
    output_dir: Paths to save the compressed file (outside chroot).
    suffix: Compression suffix.

  Returns:
    List of full paths of the generated tarballs.

  Raises:
    RuntimeError if the file to compress does not exist.
  """
  ret = []
  for t in targets:
    name = os.path.basename(t)
    compressed = name + suffix
    if input_dir:
      input_path = os.path.join(input_dir, name)
    else:
      input_path = t
    if not os.path.exists(input_path):
      raise RuntimeError('file %s to compress does not exist' % input_path)
    output_path = os.path.join(output_dir, compressed)
    cros_build_lib.CompressFile(input_path, output_path)
    ret.append(output_path)
  return ret


def _UploadAFDOArtifactToGSBucket(gs_url, local_path, rename=''):
  """Upload AFDO artifact to a centralized GS Bucket.

  Args:
    gs_url: The location to upload the artifact.
    local_path: Full local path to the file.
    rename: Optional. The name used in the bucket. If omitted, will use
    the same name as in local path.

  Raises:
    RuntimeError if the file to upload doesn't exist.
  """
  gs_context = gs.GSContext()

  if not os.path.exists(local_path):
    raise RuntimeError('file %s to upload does not exist' % local_path)

  if rename:
    remote_name = rename
  else:
    remote_name = os.path.basename(local_path)
  url = os.path.join(gs_url, remote_name)

  if gs_context.Exists(url):
    logging.info('URL %s already exists, skipping uploading...', url)
    return

  gs_context.Copy(local_path, url, acl='public-read')


def _MergeAFDOProfiles(chroot_profile_list,
                       chroot_output_profile,
                       use_compbinary=False):
  """Merges the given profile list.

  This function is copied over from afdo.py.

  Args:
    chroot_profile_list: a list of (profile_path, profile_weight).
      Profile_weight is an int that tells us how to weight the profile compared
      to everything else.
    chroot_output_profile: where to store the result profile.
    use_compbinary: whether to use the new compressed binary AFDO profile
      format.
  """
  if not chroot_profile_list:
    raise ValueError('Need profiles to merge')

  # A regular llvm-profdata command looks like:
  # llvm-profdata merge [-sample] -output=/path/to/output input1 [input2
  #                                                               [input3 ...]]
  #
  # Alternatively, we can specify inputs by `-weighted-input=A,file`, where A
  # is a multiplier of the sample counts in the profile.
  merge_command = [
      'llvm-profdata',
      'merge',
      '-sample',
      '-output=' + chroot_output_profile,
  ]

  merge_command += [
      '-weighted-input=%d,%s' % (weight, name)
      for name, weight in chroot_profile_list
  ]

  if use_compbinary:
    merge_command.append('-compbinary')

  cros_build_lib.run(merge_command, enter_chroot=True, print_cmd=True)


def _RedactAFDOProfile(input_path, output_path):
  """Redact ICF'ed symbols and indirect calls from AFDO profiles.

  ICF can cause inflation on AFDO sampling results, so we want to remove
  them from AFDO profiles used for Chrome.
  See http://crbug.com/916024 for more details.

  Indirect calls can cause the size increase of nacl, so we need to remove them
  from AFDO profiles.
  See http://crbug.com/1057153 for more details.

  Args:
    input_path: Full path to input AFDO profile.
    output_path: Full path to output AFDO profile.
  """

  profdata_command_base = ['llvm-profdata', 'merge', '-sample']
  # Convert the compbinary profiles to text profiles.
  input_to_text_temp = input_path + '.text.temp'
  convert_to_text_command = profdata_command_base + [
      '-text', input_path, '-output', input_to_text_temp
  ]
  cros_build_lib.run(convert_to_text_command, enter_chroot=True, print_cmd=True)

  # Call the redaction script.
  redacted_temp = input_path + '.redacted.temp'
  with open(input_to_text_temp, 'rb') as f:
    cros_build_lib.run(
        ['redact_textual_afdo_profile'],
        input=f,
        stdout=redacted_temp,
        enter_chroot=True,
        print_cmd=True,
    )

  # Call the remove indirect call script
  removed_temp = input_path + '.removed.temp'
  cros_build_lib.run(
      [
          'remove_indirect_calls',
          '--input=' + redacted_temp,
          '--output=' + removed_temp,
      ],
      enter_chroot=True,
      print_cmd=True,
  )

  # Remove cold functions in the profile. Trim the profile to contain 20k
  # functions, as our current profile has ~20k functions so this modification
  # brings less impact on prod.
  reduced_temp = input_path + '.reduced.temp'
  cros_build_lib.run(
      [
          'remove_cold_functions',
          '--input=' + removed_temp,
          '--output=' + reduced_temp,
          '--number=20000',
      ],
      enter_chroot=True,
      print_cmd=True,
  )

  # Convert the profiles back to compbinary profiles.
  # Using `compbinary` profiles saves us hundreds of MB of RAM per
  # compilation, since it allows profiles to be lazily loaded.
  convert_to_combinary_command = profdata_command_base + [
      '-compbinary',
      reduced_temp,
      '-output',
      output_path,
  ]
  cros_build_lib.run(
      convert_to_combinary_command, enter_chroot=True, print_cmd=True)


class GenerateChromeOrderfile(object):
  """Class to handle generation of orderfile for Chrome.

  This class takes orderfile containing symbols ordered by Call-Chain
  Clustering (C3), produced when linking Chrome, and uses a toolchain
  script to perform post processing to generate an orderfile that can
  be used for linking Chrome and creates tarball. The output of this
  script is a tarball of the orderfile and a tarball of the NM output
  of the built Chrome binary.

  The whole class runs outside chroot, so use paths relative outside
  chroot, except the functions noted otherwise.
  """

  PROCESS_SCRIPT = os.path.join(TOOLCHAIN_UTILS_PATH,
                                'orderfile/post_process_orderfile.py')
  CHROME_BINARY_PATH = ('/var/cache/chromeos-chrome/chrome-src-internal/'
                        'src/out_${BOARD}/Release/chrome')
  INPUT_ORDERFILE_PATH = ('/build/${BOARD}/opt/google/chrome/'
                          'chrome.orderfile.txt')

  def __init__(self, board, output_dir, chrome_root, chroot_path, chroot_args):
    """Construct an object for generating orderfile for Chrome.

    Args:
      board: Name of the board.
      output_dir: Directory (outside chroot) to save the output artifacts.
      chrome_root: Path to the Chrome source.
      chroot_path: Path to the chroot.
      chroot_args: The arguments used to enter the chroot.
    """
    self.output_dir = output_dir
    self.orderfile_name = _GetOrderfileName(chrome_root)
    self.chrome_binary = self.CHROME_BINARY_PATH.replace('${BOARD}', board)
    self.input_orderfile = self.INPUT_ORDERFILE_PATH.replace('${BOARD}', board)
    self.chroot_path = chroot_path
    self.working_dir = os.path.join(self.chroot_path, 'tmp')
    self.working_dir_inchroot = '/tmp'
    self.chroot_args = chroot_args
    self.tarballs = []

  def _CheckArguments(self):
    """Make sure the arguments received are correct."""
    if not os.path.isdir(self.output_dir):
      raise GenerateChromeOrderfileError(
          'Non-existent directory %s specified for --out-dir' %
          (self.output_dir,))

    chrome_binary_path_outside = os.path.join(self.chroot_path,
                                              self.chrome_binary[1:])
    if not os.path.exists(chrome_binary_path_outside):
      raise GenerateChromeOrderfileError(
          'Chrome binary does not exist at %s in chroot' %
          (chrome_binary_path_outside,))

    chrome_orderfile_path_outside = os.path.join(self.chroot_path,
                                                 self.input_orderfile[1:])
    if not os.path.exists(chrome_orderfile_path_outside):
      raise GenerateChromeOrderfileError(
          'No orderfile generated in the builder.')

  def _GenerateChromeNM(self):
    """Generate symbols by running nm command on Chrome binary.

    This command runs inside chroot.
    """
    cmd = ['llvm-nm', '-n', self.chrome_binary]
    result_inchroot = os.path.join(self.working_dir_inchroot,
                                   self.orderfile_name + '.nm')
    result_out_chroot = os.path.join(self.working_dir,
                                     self.orderfile_name + '.nm')

    try:
      cros_build_lib.run(
          cmd,
          stdout=result_out_chroot,
          enter_chroot=True,
          chroot_args=self.chroot_args)
    except cros_build_lib.RunCommandError:
      raise GenerateChromeOrderfileError(
          'Unable to run %s to get nm on Chrome binary' % (cmd))

    # Return path inside chroot
    return result_inchroot

  def _PostProcessOrderfile(self, chrome_nm):
    """Use toolchain script to do post-process on the orderfile.

    This command runs inside chroot.
    """
    result = os.path.join(self.working_dir_inchroot,
                          self.orderfile_name + '.orderfile')
    cmd = [
        self.PROCESS_SCRIPT, '--chrome', chrome_nm, '--input',
        self.input_orderfile, '--output', result
    ]

    try:
      cros_build_lib.run(
          cmd,
          enter_chroot=True,
          chroot_args=self.chroot_args,
          check=True,
          capture_output=True)
    except cros_build_lib.RunCommandError as e:
      raise GenerateChromeOrderfileError(
          f'Unable to run %s to process orderfile {cmd} '
          f'with error: {e.result.stdout} {e.result.stderr}.')

    # Return path inside chroot
    return result

  def Bundle(self):
    """Generate post-processed Chrome orderfile and create tarball."""
    self._CheckArguments()
    chrome_nm = self._GenerateChromeNM()
    orderfile = self._PostProcessOrderfile(chrome_nm)
    self.tarballs = _CompressAFDOFiles([chrome_nm, orderfile], self.working_dir,
                                       self.output_dir, XZ_COMPRESSION_SUFFIX)

  def Perform(self):
    """Generate post-processed Chrome orderfile and create tarball."""
    self.Bundle()
    for t in self.tarballs:
      _UploadAFDOArtifactToGSBucket(ORDERFILE_GS_URL_UNVETTED, t)


class UpdateEbuildWithAFDOArtifacts(object):
  """Class to update ebuild with unvetted AFDO artifacts.

  This class is used to verify an unvetted AFDO artifact, by patching
  the ebuild of the package with a dictionary of rules.

  This class runs inside chroot, so all the paths should be relative
  inside chroot.
  """

  def __init__(self, board, package, update_rules):
    """Construct an object for updating ebuild with AFDO artifacts.

    Args:
      board: Name of the board.
      package: Name of the package to test with.
      update_rules: A dict containing pairs of (key, value) used to
      patch ebuild. "key" will be used to search ebuild as an variable,
      and update that variable with "value".
    """
    self.board = board
    self.package = package
    self.update_rules = update_rules

  def _PatchEbuild(self, ebuild_file):
    """Patch the specified ebuild to use the artifact.

    Args:
      ebuild_file: path to the ebuild file.

    Raises:
      UpdateEbuildWithAFDOArtifactsError: If marker is not found.
    """
    original_ebuild = path_util.FromChrootPath(ebuild_file)
    modified_ebuild = '%s.new' % original_ebuild

    patterns = []
    replacements = []
    for name, value in self.update_rules.items():
      patterns.append(re.compile(AFDO_ARTIFACT_EBUILD_REGEX % name))
      replacements.append(AFDO_ARTIFACT_EBUILD_REPL % value)

    found = set()
    with open(original_ebuild) as original, \
         open(modified_ebuild, 'w') as modified:
      for line in original:
        matched = False
        for p, r in zip(patterns, replacements):
          matched = p.match(line)
          if matched:
            found.add(r)
            modified.write(p.sub(r, line))
            # Each line can only match one pattern
            break
        if not matched:
          modified.write(line)
    not_updated = set(replacements) - found
    if not_updated:
      logging.info('Unable to update %s in the ebuild', not_updated)
      raise UpdateEbuildWithAFDOArtifactsError(
          'Ebuild file does not have appropriate marker for AFDO/orderfile.')

    os.rename(modified_ebuild, original_ebuild)
    for name, value in self.update_rules.items():
      logging.info('Patched %s with (%s, %s)', original_ebuild, name, value)

  def _UpdateManifest(self, ebuild_file):
    """Regenerate the Manifest file. (To update orderfile)

    Args:
      ebuild_file: path to the ebuild file
    """
    ebuild_prog = 'ebuild-%s' % self.board
    cmd = [ebuild_prog, ebuild_file, 'manifest', '--force']
    cros_build_lib.run(cmd, enter_chroot=True)

  def Perform(self):
    """Main function to update ebuild with the rules."""
    ebuild = _FindEbuildPath(self.package, board=self.board)
    self._PatchEbuild(ebuild)
    # Patch the chrome 9999 ebuild too, as the manifest will use
    # 9999 ebuild.
    ebuild_9999 = os.path.join(
        os.path.dirname(ebuild), self.package + '-9999.ebuild')
    self._PatchEbuild(ebuild_9999)
    # Use 9999 ebuild to update manifest.
    self._UpdateManifest(ebuild_9999)


def _RankValidBenchmarkProfiles(name):
  """Calculate a value used to rank valid benchmark profiles.

  Args:
    name: A name or a full path of a possible benchmark profile.

  Returns:
    A BenchmarkProfileNamedTuple used for ranking if the name
    is a valid benchmark profile. Otherwise, returns None.
  """
  try:
    version = _ParseBenchmarkProfileName(os.path.basename(name))
    # Filter out merged benchmark profiles.
    if version.is_merged:
      return None
    return version
  except ProfilesNameHelperError:
    return None


def _RankValidCWPProfiles(name):
  """Calculate a value used to rank valid CWP profiles.

  Args:
    name: A name or a full path of a possible CWP profile.

  Returns:
    The "clock" part of the CWP profile, used for ranking if the
    name is a valid CWP profile. Otherwise, returns None.
  """
  try:
    return _ParseCWPProfileName(os.path.basename(name)).clock
  except ProfilesNameHelperError:
    return None


def _RankValidOrderfiles(name):
  """Calculcate a value used to rank valid orderfiles.

  Args:
    name: A name or a full path of a possible orderfile.

  Returns:
    A tuple of (BenchmarkProfileNamedTuple, "clock" part of CWP profile),
    or returns None if the name is not a valid orderfile name.

  Raises:
    ValueError, if the parsed orderfile is not valid.
  """
  try:
    benchmark_part, cwp_part = _ParseMergedProfileName(os.path.basename(name))
    if benchmark_part.is_merged:
      raise ValueError(
          '-merged should not appear in orderfile or release AFDO name.')
    return benchmark_part, cwp_part.clock
  except ProfilesNameHelperError:
    return None


def _FindLatestAFDOArtifact(gs_url, ranking_function):
  """Find the latest AFDO artifact in a GS bucket.

  Always finds profiles that matches the current Chrome branch.

  Args:
    gs_url: The full path to GS bucket URL.
    ranking_function: A function used to evaluate a full url path.
    e.g. foo(x) should return a value that can use to rank the profile,
    or return None if the url x is not relevant.

  Returns:
    The name of the eligible latest AFDO artifact.

  Raises:
    RuntimeError: If no files matches the regex in the bucket.
    ValueError: if regex is not valid.
  """

  def _FilterResultsBasedOnBranch(branch):
    """Filter out results that doesn't belong to this branch."""
    # The branch should appear in the name either as:
    # R78-12371.22-1566207135 for kernel/CWP profiles
    # OR chromeos-chrome-amd64-78.0.3877.0 for benchmark profiles
    return [
        x for x in all_files
        if 'R%s' % branch in x.url or '-%s.' % branch in x.url
    ]

  gs_context = gs.GSContext()

  # Obtain all files from gs_url and filter out those not match
  # pattern. And filter out text files for legacy PFQ like
  # latest-chromeos-chrome-amd64-79.afdo
  all_files = [
      x for x in gs_context.List(gs_url, details=True) if 'latest-' not in x.url
  ]
  chrome_branch = _FindCurrentChromeBranch()
  results = _FilterResultsBasedOnBranch(chrome_branch)

  if not results:
    # If no results found, it's maybe because we just branched.
    # Try to find the latest profile from last branch.
    results = _FilterResultsBasedOnBranch(str(int(chrome_branch) - 1))
    if not results:
      raise RuntimeError('No files found on %s for branch %s' %
                         (gs_url, chrome_branch))

  ranked_results = [(ranking_function(x.url), x.url) for x in results]
  filtered_results = [x for x in ranked_results if x[0] is not None]
  if not filtered_results:
    raise RuntimeError('No valid latest artifact was found on %s'
                       '(example invalid artifact: %s).' %
                       (gs_url, results[0].url))

  latest = max(filtered_results)
  name = os.path.basename(latest[1])
  logging.info('Latest AFDO artifact in %s is %s', gs_url, name)
  return name


def _FindCurrentChromeBranch():
  """Find the current Chrome branch from Chrome ebuild.

  Returns:
    The branch version as a str.
  """
  chrome_ebuild = os.path.basename(_FindEbuildPath('chromeos-chrome'))
  pattern = re.compile(
      r'chromeos-chrome-(?P<branch>\d+)\.\d+\.\d+\.\d+(?:_rc)?-r\d+.ebuild')
  match = pattern.match(chrome_ebuild)
  if not match:
    raise ValueError('Unparseable chrome ebuild name: %s' % chrome_ebuild)

  return match.group('branch')


def _GetProfileAge(profile, artifact_type):
  """Tell the age of profile_version in days.

  Args:
    profile: Name of the profile. Different artifact_type has different
    format. For kernel_afdo, it looks like: R78-12371.11-1565602499.
    The last part is the timestamp.
    artifact_type: Only 'kernel_afdo' is supported now.

  Returns:
    Age of profile_version in days.

  Raises:
    ValueError: if the artifact_type is not supported.
  """

  if artifact_type == 'kernel_afdo':
    return (
        datetime.datetime.utcnow() -
        datetime.datetime.utcfromtimestamp(int(profile.split('-')[-1]))).days

  raise ValueError('Only kernel afdo is supported to check profile age.')


def _WarnSheriffAboutKernelProfileExpiration(kver, profile):
  """Send emails to toolchain sheriff to warn the soon expired profiles.

  Args:
    kver: Kernel version.
    profile: Name of the profile.
  """
  # FIXME(tcwang): Fix the subject and email format before deployment.
  subject_msg = (
      '[Test Async builder] Kernel AutoFDO profile too old for kernel %s' %
      kver)
  alert_msg = ('AutoFDO profile too old for kernel %s. Name=%s' % kver, profile)
  alerts.SendEmailLog(
      subject_msg,
      AFDO_ALERT_RECIPIENTS,
      server=alerts.SmtpServer(constants.GOLO_SMTP_SERVER),
      message=alert_msg)


_EbuildInfo = collections.namedtuple('_EbuildInfo', ['path', 'CPV'])


class _CommonPrepareBundle(object):
  """Information about Ebuild files we care about."""

  def __init__(self,
               artifact_name,
               chroot=None,
               sysroot_path=None,
               build_target=None,
               input_artifacts=None,
               profile_info=None):
    self._gs_context = None
    self.artifact_name = artifact_name
    self.chroot = chroot
    self.sysroot_path = sysroot_path
    self.build_target = build_target
    # TODO(crbug/1019868): revisit when arch != amd64 becomes something we care
    # about.
    self.arch = 'amd64'
    self.input_artifacts = input_artifacts or {}
    self.profile_info = profile_info or {}
    self._ebuild_info = {}

  @property
  def gs_context(self):
    """Get the current GS context.  May create one."""
    if not self._gs_context:
      self._gs_context = gs.GSContext()
    return self._gs_context

  @property
  def chrome_branch(self):
    """Return the branch number for chrome."""
    pkg = constants.CHROME_PN
    info = self._ebuild_info.get(pkg, self._GetEbuildInfo(pkg))
    return info.CPV.version_no_rev.split('.')[0]

  def _GetEbuildInfo(self, package: str,
                     category: Optional[str] = None) -> _EbuildInfo:
    """Get the ebuild info for a cataegory/package in chromiumos-overlay.

    Args:
      package: package name (e.g. chromeos-chrome or chromeos-kernel-4_4)
      category: category (e.g. chromeos-base, or sys-kernel)

    Returns:
      _EbuildInfo for the stable ebuild.
    """
    if package in self._ebuild_info:
      return self._ebuild_info[package]

    if category is None:
      if package == constants.CHROME_PN:
        category = constants.CHROME_CN
      else:
        category = 'sys-kernel'

    # The stable ebuild path has at least one '.' in the version.
    paths = glob.glob(
        os.path.join(_CHROMIUMOS_OVERLAY, category, package, '*-*.*.ebuild'))
    if len(paths) == 1:
      PV = os.path.splitext(os.path.split(paths[0])[1])[0]
      info = _EbuildInfo(paths[0],
                         package_info.SplitCPV('%s/%s' % (category, PV)))
      self._ebuild_info[constants.CHROME_PN] = info
      return info
    else:
      latest_version = ChromeVersion(0, 0, 0, 0, 0)
      candidate = None
      for p in paths:
        PV = os.path.splitext(os.path.split(p)[1])[0]
        info = _EbuildInfo(p, package_info.SplitCPV('%s/%s' % (category, PV)))
        if not info.CPV.rev:
          # Ignore versions without a rev
          continue
        version_re = re.compile(
            r'^chromeos-chrome-(\d+)\.(\d+)\.(\d+)\.(\d+)_rc-r(\d+)')
        m = version_re.search(PV)
        assert m, f'failed to recognize Chrome ebuild name {p}'
        version = ChromeVersion(*[int(x) for x in m.groups()])
        if version > latest_version:
          latest_version = version
          candidate = info
      if not candidate:
        raise PrepareForBuildHandlerError(
            f'No valid Chrome ebuild found among: {paths}')
      self._ebuild_info[constants.CHROME_PN] = candidate
      return candidate

  def _GetBenchmarkAFDOName(self, template=CHROME_BENCHMARK_AFDO_FILE):
    """Get the name of the benchmark AFDO file from the Chrome ebuild."""
    cpv = self._GetEbuildInfo(constants.CHROME_PN).CPV
    afdo_spec = {
        'arch': self.arch,
        'package': cpv.package,
        'version': cpv.version,
        'versionnorev': cpv.version_no_rev.split('_')[0]
    }
    return template % afdo_spec

  def _GetArtifactVersionInGob(self, arch):
    """Find the version (name) of AFDO artifact from GoB.

    Args:
      arch: There are two AFDO profiles in chromium: atom or bigcore.

    Returns:
      The name of the AFDO artifact found on GoB, or None if not found.

    Raises:
      ValueError: when "arch" is not a supported.
      RuntimeError: when the file containing AFDO profile name can't be found.
    """
    if arch not in list(CHROME_AFDO_VERIFIER_BOARDS.values()):
      raise ValueError('Invalid architecture %s to use in AFDO profile' % arch)

    chrome_info = self._GetEbuildInfo(constants.CHROME_PN)
    rev = chrome_info.CPV.version_no_rev
    if rev.endswith('_rc'):
      rev = rev[:-3]
    profile_path = (
        'chromium/src/+/refs/tags/%s/chromeos/profiles/%s.afdo.newest.txt'
        '?format=text' % (rev, arch))

    contents = gob_util.FetchUrl(constants.EXTERNAL_GOB_HOST, profile_path)
    if not contents:
      raise RuntimeError('Could not fetch https://%s/%s' %
                         (constants.EXTERNAL_GOB_HOST, profile_path))

    return base64.decodebytes(contents).decode('utf-8')

  def _GetArtifactVersionInEbuild(self, package, variable):
    """Find the version (name) of AFDO artifact from the ebuild.

    Args:
      package: name of the package (such as, 'chromeos-chrome')
      variable: name of the variable to find.

    Returns:
      The name of the AFDO artifact found in the ebuild, or None if not found.
    """
    info = self._GetEbuildInfo(package)
    ebuild = info.path
    pattern = re.compile(AFDO_ARTIFACT_EBUILD_REGEX % variable)
    with open(ebuild) as f:
      for line in f:
        match = pattern.match(line)
        if match:
          ret = match.group('name')
          if ret.startswith('"') and ret.endswith('"'):
            return ret[1:-1]
          return ret

    logging.info('%s is not found in the ebuild: %s', variable, ebuild)
    return None

  def _GetOrderfileName(self):
    """Get the name of the orderfile."""
    artifact_version = self._GetArtifactVersionInGob(arch='atom')
    logging.info('Orderfile artifact version = %s', artifact_version)
    benchmark_afdo, cwp_afdo = _ParseMergedProfileName(artifact_version)
    return 'chromeos-chrome-orderfile-%s.orderfile' % (
        _GetCombinedAFDOName(cwp_afdo, 'field', benchmark_afdo))

  def _FindLatestOrderfileArtifact(self, gs_urls):
    """Find the latest Ordering file artifact in a bucket.

    Args:
      gs_urls: List of full gs:// directory paths to check.

    Returns:
      The path of the latest eligible ordering file artifact.

    Raises:
      See _FindLatestAFDOArtifact.
    """
    return self._FindLatestAFDOArtifact(gs_urls, self._RankValidOrderfiles)

  def _FindLatestAFDOArtifact(self, gs_urls, rank_func):
    """Find the latest AFDO artifact in a bucket.

    Args:
      gs_urls: List of full gs:// directory paths to check.
      rank_func: A function to compare two URLs.  It is passed two URLs, and
          returns whether the first is more or less preferred than the second:
            negative: less preferred.
            zero: equally preferred.
            positive: more preferred.

    Returns:
      The path of the latest eligible AFDO artifact.

    Raises:
      RuntimeError: If no files matches the regex in the bucket.
      ValueError: if regex is not valid.
    """

    def _FilesOnBranch(all_files, branch):
      """Return the files that are on this branch.

      Legacy PFQ results look like: latest-chromeos-chrome-amd64-79.afdo.
      The branch should appear in the name either as:
      - R78-12371.22-1566207135 for kernel/CWP profiles, OR
      - chromeos-chrome-amd64-78.0.3877.0 for benchmark profiles

      Args:
        all_files: (list(string)) list of files from GS.
        branch: (string) branch number.

      Returns:
        Files matching the branch.
      """
      # Filter out those not match pattern. And filter out text files for legacy
      # PFQ like latest-chromeos-chrome-amd64-79.afdo.
      return [
          x for x in all_files if 'latest-' not in x.url and
          ('R%s-' % branch in x.url or '-%s.' % branch in x.url)
      ]

    # Obtain all files from the gs_urls.
    all_files = []
    for gs_url in gs_urls:
      try:
        all_files += self.gs_context.List(gs_url, details=True)
      except gs.GSNoSuchKey:
        pass

    results = _FilesOnBranch(all_files, self.chrome_branch)
    if not results:
      # If no results found, it's maybe because we just branched.
      # Try to find the latest profile from last branch.
      results = _FilesOnBranch(all_files, str(int(self.chrome_branch) - 1))

    if not results:
      raise RuntimeError('No files for branch %s found in %s' %
                         (self.chrome_branch, ' '.join(gs_urls)))

    latest = None
    for res in results:
      rank = rank_func(res.url)
      if rank and (not latest or [rank, ''] > latest):
        latest = [rank, res.url]

    if not latest:
      raise RuntimeError('No valid latest artifact was found in %s'
                         '(example invalid artifact: %s).' %
                         (' '.join(gs_urls), results[0].url))

    name = latest[1]
    logging.info('Latest AFDO artifact is %s', name)
    return name

  def _AfdoTmpPath(self, path: str = '') -> str:
    """Return the directory for benchmark-afdo-generate artifacts.

    Args:
      path: path relative to the directory.

    Returns:
      Path to the directory.
    """
    gen_dir = '/tmp/benchmark-afdo-generate'
    if path:
      return os.path.join(gen_dir, path.lstrip(os.path.sep))
    else:
      return gen_dir

  def _FindArtifact(self, name: str, gs_urls: Iterable[str]) -> Optional[str]:
    """Find an artifact |name|, from a list of |gs_urls|.

    Args:
      name: The name of the artifact.
      gs_urls: List of full gs:// directory paths to check.

    Returns:
      The url of the located artifact, or None.
    """
    for url in gs_urls:
      path = os.path.join(url, name)
      if self.gs_context.Exists(path):
        return path
    return None

  def _UpdateEbuildWithArtifacts(self, package, update_rules):
    """Update a package ebuild file with artifacts.

    Args:
      package: name of package to update (no category.)
      update_rules: dict{'variable': 'value'} to apply.
    """
    info = self._GetEbuildInfo(package)
    self._PatchEbuild(info, update_rules, uprev=True)
    CPV_9999 = '%s/%s-9999' % (info.CPV.category, info.CPV.package)
    ebuild_9999 = os.path.join(
        os.path.dirname(info.path), '%s-9999.ebuild' % package)
    info_9999 = _EbuildInfo(ebuild_9999, package_info.SplitCPV(CPV_9999))
    self._PatchEbuild(info_9999, update_rules, uprev=False)

  def _PatchEbuild(self, info, rules, uprev):
    """Patch an ebuild file, possibly uprevving it.

    Args:
      info: _EbuildInfo describing the ebuild file.
      rules: dict of key:value pairs to apply to the ebuild.
      uprev: whether to increment the revision.  Should be False for 9999
          ebuilds, and True otherwise.

    Returns:
      Updated CPV for the ebuild.
    """
    logging.info('Patching %s with %s', info.path, str(rules))
    old_name = info.path
    new_name = '%s.new' % old_name

    _Patterns = collections.namedtuple('_Patterns', ['match', 'sub'])
    patterns = set(
        _Patterns(
            re.compile(AFDO_ARTIFACT_EBUILD_REGEX %
                       k), AFDO_ARTIFACT_EBUILD_REPL % v)
        for k, v in rules.items())

    want = patterns.copy()
    with open(old_name) as old, open(new_name, 'w') as new:
      for line in old:
        for match, sub in patterns:
          line, count = match.subn(sub, line, count=1)
          if count:
            want.remove((match, sub))
            # Can only match one pattern.
            break
        new.write(line)
      if want:
        logging.info('Unable to update %s in the ebuild', [x.sub for x in want])
        raise UpdateEbuildWithAFDOArtifactsError(
            'Ebuild file does not have appropriate marker for AFDO/orderfile.')

    CPV = info.CPV
    if uprev:
      assert CPV.version != '9999'
      new_rev = 'r%d' % (int(CPV.rev[1:]) + 1) if CPV.rev else 'r1'
      new_CPV = '%s/%s-%s-%s' % (CPV.category, CPV.package, CPV.version_no_rev,
                                 new_rev)
      new_path = os.path.join(
          os.path.dirname(info.path), '%s.ebuild' % os.path.basename(new_CPV))
      os.rename(new_name, new_path)
      osutils.SafeUnlink(old_name)
      ebuild_file = new_path
      CPV = _EbuildInfo(new_path, package_info.SplitCPV(new_CPV))
    else:
      assert CPV.version == '9999'
      os.rename(new_name, old_name)
      ebuild_file = old_name

    if self.build_target:
      ebuild_prog = 'ebuild-%s' % self.build_target
      cmd = [
          ebuild_prog,
          path_util.ToChrootPath(ebuild_file, self.chroot.path), 'manifest',
          '--force'
      ]
      cros_build_lib.run(cmd, enter_chroot=True)

    return CPV

  @staticmethod
  def _RankValidOrderfiles(url):
    """Rank the given URL for comparison."""
    try:
      bench, cwp = _ParseMergedProfileName(os.path.basename(url))
      if bench.is_merged:
        raise ValueError(
            '-merged should not appear in orderfile or release AFDO name.')
      return bench, cwp
    except ProfilesNameHelperError:
      return None

  @staticmethod
  def _RankValidBenchmarkProfiles(name):
    """Calculate a value used to rank valid benchmark profiles.

    Args:
      name: A name or a full path of a possible benchmark profile.

    Returns:
      A BenchmarkProfileNamedTuple used for ranking if the name
      is a valid benchmark profile. Otherwise, returns None.
    """
    try:
      version = _ParseBenchmarkProfileName(os.path.basename(name))
      # Filter out merged benchmark profiles.
      if version.is_merged:
        return None
      return version
    except ProfilesNameHelperError:
      return None

  @staticmethod
  def _RankValidCWPProfiles(name):
    """Calculate a value used to rank valid benchmark profiles.

    Args:
      name: A name or a full path of a possible benchmark profile.

    Returns:
      A BenchmarkProfileNamedTuple used for ranking if the name
      is a valid benchmark profile. Otherwise, returns None.
    """
    try:
      return _ParseCWPProfileName(os.path.basename(name)).clock
    except ProfilesNameHelperError:
      return None

  def _CreateReleaseChromeAFDO(self, cwp_url, bench_url, output_dir,
                               merged_name):
    """Create an AFDO profile to be used in release Chrome.

    This means we want to merge the CWP and benchmark AFDO profiles into
    one, and redact all ICF symbols.

    Args:
      cwp_url: Full (GS) path to the discovered CWP file to use.
      bench_url: Full (GS) path to the verified benchmark profile.
      output_dir: A directory to store the created artifact.  Must be inside of
          the chroot.
      merged_name: Basename for the merged profile.

    Returns:
      Full path to a generated release AFDO profile.
    """
    # Download the compressed profiles from GS.
    cwp_compressed = os.path.join(output_dir, os.path.basename(cwp_url))
    bench_compressed = os.path.join(output_dir, os.path.basename(bench_url))
    self.gs_context.Copy(cwp_url, cwp_compressed)
    self.gs_context.Copy(bench_url, bench_compressed)

    # Decompress the files.
    cwp_local = os.path.splitext(cwp_compressed)[0]
    bench_local = os.path.splitext(bench_compressed)[0]
    cros_build_lib.UncompressFile(cwp_compressed, cwp_local)
    cros_build_lib.UncompressFile(bench_compressed, bench_local)

    # Merge profiles.
    merge_weights = [(cwp_local, RELEASE_CWP_MERGE_WEIGHT),
                     (bench_local, RELEASE_BENCHMARK_MERGE_WEIGHT)]
    merged_path = os.path.join(output_dir, merged_name)
    self._MergeAFDOProfiles(merge_weights, merged_path)

    # Redact profiles.
    redacted_path = merged_path + '-redacted.afdo'
    # Trim the profile to contain 20k functions, as our current profile has
    # ~20k functions so this modification brings less impact on prod.
    self._ProcessAFDOProfile(
        merged_path,
        redacted_path,
        redact=True,
        remove=True,
        reduce_functions=20000,
        compbinary=True)

    return redacted_path

  def _MergeAFDOProfiles(self,
                         profile_list,
                         output_profile,
                         use_compbinary=False):
    """Merges the given profile list.

    This is ultimately derived from afdo.py, but runs OUTSIDE of the chroot.
    It converts paths to chroot-relative paths, and runs llvm-profdata in the
    chroot.

    Args:
      profile_list: a list of (profile_path, profile_weight).
        Profile_weight is an int that tells us how to weight the profile
        relative to everything else.
      output_profile: where to store the result profile.
      use_compbinary: whether to use the new compressed binary AFDO profile
        format.
    """
    if not profile_list:
      raise ValueError('Need profiles to merge')

    # A regular llvm-profdata command looks like:
    # llvm-profdata merge [-sample] -output=/path/to/output input1 [...]
    #
    # Alternatively, we can specify inputs by `-weighted-input=A,file`, where A
    # is a multiplier of the sample counts in the profile.
    merge_command = [
        'llvm-profdata',
        'merge',
        '-sample',
        '-output=' + self.chroot.chroot_path(output_profile),
    ] + [
        '-weighted-input=%d,%s' % (weight, self.chroot.chroot_path(name))
        for name, weight in profile_list
    ]

    # Here only because this was copied from afdo.py
    if use_compbinary:
      merge_command.append('-compbinary')
    cros_build_lib.run(merge_command, enter_chroot=True, print_cmd=True)

  def _ProcessAFDOProfile(self,
                          input_path,
                          output_path,
                          redact=False,
                          remove=False,
                          reduce_functions=None,
                          compbinary=False):
    """Process the AFDO profile with different editings.

    In this function, we will convert an AFDO profile into textual version,
    do the editings and convert it back.

    This function runs outside of the chroot, and enters the chroot.

    Args:
      input_path: Full path (outside chroot) to input AFDO profile.
      output_path: Full path (outside chroot) to output AFDO profile.
      redact: Redact ICF'ed symbols from AFDO profiles.
        ICF can cause inflation on AFDO sampling results, so we want to remove
        them from AFDO profiles used for Chrome.
        See http://crbug.com/916024 for more details.
      remove: Remove indirect call targets from the given profile.
      reduce_functions: Remove the cold functions in the profile until the
        given number is met.
      compbinary: Whether to convert the final profile into compbinary type.
    """
    profdata_command_base = ['llvm-profdata', 'merge', '-sample']
    # Convert the compbinary profiles to text profiles.
    input_to_text_temp = input_path + '.text.temp'
    cmd_to_text = profdata_command_base + [
        '-text',
        self.chroot.chroot_path(input_path), '-output',
        self.chroot.chroot_path(input_to_text_temp)
    ]
    cros_build_lib.run(cmd_to_text, enter_chroot=True, print_cmd=True)

    current_input_file = input_to_text_temp
    if redact:
      # Call the redaction script.
      redacted_temp = input_path + '.redacted.temp'
      with open(current_input_file, 'rb') as f:
        cros_build_lib.run(['redact_textual_afdo_profile'],
                           input=f,
                           stdout=redacted_temp,
                           enter_chroot=True,
                           print_cmd=True)
      current_input_file = redacted_temp

    if remove:
      # Call the remove indirect call script
      removed_temp = input_path + '.removed.temp'
      cros_build_lib.run(
          [
              'remove_indirect_calls',
              '--input=' + self.chroot.chroot_path(current_input_file),
              '--output=' + self.chroot.chroot_path(removed_temp),
          ],
          enter_chroot=True,
          print_cmd=True,
      )
      current_input_file = removed_temp

    if reduce_functions:
      # Remove cold functions in the profile. Trim the profile to contain 20k
      # functions, as our current profile has ~20k functions so this
      # modification brings less impact on prod.
      reduced_tmp = input_path + '.reduced.tmp'
      cros_build_lib.run(
          [
              'remove_cold_functions',
              '--input=' + self.chroot.chroot_path(current_input_file),
              '--output=' + self.chroot.chroot_path(reduced_tmp),
              '--number=' + str(reduce_functions),
          ],
          enter_chroot=True,
          print_cmd=True,
      )
      current_input_file = reduced_tmp

    # Convert the profiles back to binary profiles.
    cmd_to_binary = profdata_command_base + [
        self.chroot.chroot_path(current_input_file),
        '-output',
        self.chroot.chroot_path(output_path),
    ]
    if compbinary:
      # Using `compbinary` profiles saves us hundreds of MB of RAM per
      # compilation, since it allows profiles to be lazily loaded.
      cmd_to_binary.append('-compbinary')
    cros_build_lib.run(cmd_to_binary, enter_chroot=True, print_cmd=True)

  def _CreateAndUploadMergedAFDOProfile(self,
                                        unmerged_profile,
                                        output_dir,
                                        recent_to_merge=5,
                                        max_age_days=14):
    """Create a merged AFDO profile from recent AFDO profiles and upload it.

    Args:
      unmerged_profile: Path to the AFDO profile we've just created. No
        profiles whose names are lexicographically ordered after this are
        candidates for selection.
      output_dir: Path to location to store merged profiles for uploading.
      recent_to_merge: The maximum number of profiles to merge (include the
        current profile).
      max_age_days: Don't merge profiles older than max_age_days days old.

    Returns:
      The name of a merged profile if the AFDO profile is a candidate for
      merging and ready to be merged and uploaded. Otherwise, None.
    """
    if recent_to_merge == 1:
      # Merging the unmerged_profile into itself is a NOP.
      return None

    unmerged_name = os.path.basename(unmerged_profile)
    merged_suffix = '-merged'
    profile_suffix = AFDO_SUFFIX + BZ2_COMPRESSION_SUFFIX
    benchmark_url = self.input_artifacts.get(
        'UnverifiedChromeBenchmarkAfdoFile', [BENCHMARK_AFDO_GS_URL])[0]
    benchmark_listing = self.gs_context.List(
        os.path.join(benchmark_url, '*' + profile_suffix), details=True)

    if not benchmark_listing:
      raise RuntimeError(
          'GS URL %s has no valid benchmark profiles' %
          (self.input_artifacts.get('UnverifiedChromeBenchmarkAfdoFile',
                                    [BENCHMARK_AFDO_GS_URL])[0]))
    unmerged_version = _ParseBenchmarkProfileName(unmerged_name)

    def _GetOrderedMergeableProfiles(benchmark_listing):
      """Returns a list of mergeable profiles ordered by increasing version."""
      profile_versions = [(_ParseBenchmarkProfileName(os.path.basename(x.url)),
                           x) for x in benchmark_listing]
      # Exclude merged profiles, because merging merged profiles into merged
      # profiles is likely bad.
      candidates = sorted(
          (version, x)
          for version, x in profile_versions
          if unmerged_version >= version and not version.is_merged)
      return [x for _, x in candidates]

    benchmark_profiles = _GetOrderedMergeableProfiles(benchmark_listing)
    if not benchmark_profiles:
      logging.warning('Skipping merged profile creation: no merge candidates '
                      'found')
      return None

    # The input "unmerged_name" should never be in GS bucket, as recipe
    # builder executes only when the artifact not exists.
    if os.path.splitext(os.path.basename(
        benchmark_profiles[-1].url))[0] == unmerged_name:
      benchmark_profiles = benchmark_profiles[:-1]

    # assert os.path.splitext(os.path.basename(
    #    benchmark_profiles[-1].url))[0] != unmerged_name, unmerged_name

    base_time = datetime.datetime.fromtimestamp(
        os.path.getmtime(unmerged_profile))
    time_cutoff = base_time - datetime.timedelta(days=max_age_days)
    merge_candidates = [
        p for p in benchmark_profiles if p.creation_time >= time_cutoff
    ]

    # Pick (recent_to_merge-1) from the GS URL, because we also need to pick
    # the current profile locally.
    merge_candidates = merge_candidates[-(recent_to_merge - 1):]

    # This should never happen, but be sure we're not merging a profile into
    # itself anyway. It's really easy for that to silently slip through, and can
    # lead to overrepresentation of a single profile, which just causes more
    # noise.
    assert len(set(p.url for p in merge_candidates)) == len(merge_candidates)

    # Merging a profile into itself is pointless.
    if not merge_candidates:
      logging.warning('Skipping merged profile creation: we only have a single '
                      'merge candidate.')
      return None

    afdo_files = []
    for candidate in merge_candidates:
      # It would be slightly less complex to just name these off as
      # profile-1.afdo, profile-2.afdo, ... but the logs are more readable if we
      # keep the basename from gs://.
      candidate_name = os.path.basename(candidate.url)
      candidate_uncompressed = candidate_name[:-len(BZ2_COMPRESSION_SUFFIX)]

      copy_from = candidate.url
      copy_to = os.path.join(output_dir, candidate_name)
      copy_to_uncompressed = os.path.join(output_dir, candidate_uncompressed)

      self.gs_context.Copy(copy_from, copy_to)
      cros_build_lib.UncompressFile(copy_to, copy_to_uncompressed)
      afdo_files.append(copy_to_uncompressed)

    afdo_files.append(unmerged_profile)
    afdo_basename = os.path.basename(afdo_files[-1])
    assert afdo_basename.endswith(AFDO_SUFFIX)
    afdo_basename = afdo_basename[:-len(AFDO_SUFFIX)]

    raw_merged_basename = 'raw-' + afdo_basename + merged_suffix + AFDO_SUFFIX
    raw_merged_output_path = os.path.join(output_dir, raw_merged_basename)

    # Weight all profiles equally.
    self._MergeAFDOProfiles([(profile, 1) for profile in afdo_files],
                            raw_merged_output_path)

    profile_to_upload_basename = afdo_basename + merged_suffix + AFDO_SUFFIX
    profile_to_upload_path = os.path.join(output_dir,
                                          profile_to_upload_basename)

    # Remove indirect calls and remove cold functions
    # Since the benchmark precisions increased, the number of functions in
    # merged profiles also grow. To stabilize the impact on production
    # profiles for Android/Linux, reduce the number of functions to 70k,
    # which aligns with recent 3 merged benchmark profiles.
    # FIXME: see if a lower number (50K? 20K?) is equally as good.
    self._ProcessAFDOProfile(
        raw_merged_output_path,
        profile_to_upload_path,
        redact=False,
        remove=True,
        reduce_functions=70000,
        compbinary=False)

    result_basename = os.path.basename(profile_to_upload_path)
    return result_basename

  def _CleanupArtifactDirectory(self, src_dir):
    """Cleanup a directory before build so we can safely use the artifacts.

    Args:
      src_dir: A temp path holding the possible artifacts. It needs to be an
      absolute path.
    """
    assert os.path.isabs(src_dir), '%s needs to be an absolute path ' % src_dir
    check_dirs = [
        self.chroot.full_path(x)
        for x in [src_dir,
                  os.path.join(self.sysroot_path, src_dir[1:])]
    ]
    for directory in check_dirs:
      if not os.path.exists(directory):
        continue

      logging.info('toolchain-logs: Cleaning up %s before build', directory)
      osutils.RmDir(directory, sudo=True)


class PrepareForBuildHandler(_CommonPrepareBundle):
  """Methods for updating ebuilds for toolchain artifacts."""

  def __init__(self, artifact_name, chroot, sysroot_path, build_target,
               input_artifacts, profile_info):
    super().__init__(
        artifact_name,
        chroot,
        sysroot_path,
        build_target,
        input_artifacts=input_artifacts,
        profile_info=profile_info)
    self._prepare_func = getattr(self, '_Prepare' + artifact_name)

  def Prepare(self):
    return self._prepare_func()

  def _CommonPrepareBasedOnGsPathExists(self, name, url, key):
    """Helper function to determine if an artifact in the GS path or not."""
    gs_url = self.input_artifacts.get(key, [url])[0]
    path = os.path.join(gs_url, name)
    if self.gs_context.Exists(path):
      # Artifact already created.
      logging.info('Pointless build: Found %s on %s', name, path)
      return PrepareForBuildReturn.POINTLESS
    logging.info('Build needed: No %s found. %s does not exist', key, path)
    return PrepareForBuildReturn.NEEDED

  def _PrepareUnverifiedChromeLlvmOrderfile(self):
    """Prepare to build an unverified ordering file."""
    return self._CommonPrepareBasedOnGsPathExists(
        name=self._GetOrderfileName() + XZ_COMPRESSION_SUFFIX,
        url=ORDERFILE_GS_URL_UNVETTED,
        key='UnverifiedChromeLlvmOrderfile')

  def _PrepareVerifiedChromeLlvmOrderfile(self):
    """Prepare to verify an unvetted ordering file."""
    ret = PrepareForBuildReturn.NEEDED
    # We will look for the input artifact in the given path, but we only check
    # for the vetted artifact in the first location given.
    locations = self.input_artifacts.get('UnverifiedChromeLlvmOrderfile',
                                         [ORDERFILE_GS_URL_UNVETTED])
    path = self._FindLatestOrderfileArtifact(locations)
    loc, name = os.path.split(path)

    # If not given as an input_artifact, the vetted location is determined from
    # the first location given for the unvetted artifact.
    vetted_loc = self.input_artifacts.get('VerifiedChromeLlvmOrderfile',
                                          [None])[0]
    if not vetted_loc:
      vetted_loc = os.path.join(os.path.dirname(locations[0]), 'vetted')
    vetted_path = os.path.join(vetted_loc, name)
    if self.gs_context.Exists(vetted_path):
      # The latest unverified ordering file has already been verified.
      logging.info('Pointless build: "%s" exists.', vetted_path)
      ret = PrepareForBuildReturn.POINTLESS

    # If we don't have an SDK, then we cannot update the manifest.
    if self.chroot:
      self._PatchEbuild(
          self._GetEbuildInfo(constants.CHROME_PN), {
              'UNVETTED_ORDERFILE': os.path.splitext(name)[0],
              'UNVETTED_ORDERFILE_LOCATION': loc
          },
          uprev=True)
    else:
      logging.info('No chroot: not patching ebuild.')
    return ret

  def _PrepareChromeClangWarningsFile(self):
    # We always build this artifact.
    return PrepareForBuildReturn.NEEDED

  def _PrepareUnverifiedLlvmPgoFile(self):
    # If we have a chroot, make sure that the toolchain is set up to generate
    # the artifact.  Raise an error if we know it will fail.
    if self.chroot:
      llvm_pkg = 'sys-devel/llvm'
      use_flags = portage_util.GetInstalledPackageUseFlags(llvm_pkg)[llvm_pkg]
      if 'llvm_pgo_generate' not in use_flags:
        raise PrepareForBuildHandlerError(
            'sys-devel/llvm lacks llvm_pgo_generate: %s' % sorted(use_flags))

    # Always build this artifact.
    return PrepareForBuildReturn.NEEDED

  def _UnverifiedAfdoFileExists(self):
    """Check if the unverified AFDO benchmark file exists.

    This is used by both the UnverifiedChromeBenchmark Perf and Afdo file prep
    methods.

      PrepareForBuildReturn.
    """
    # We do not check for the existence of the (intermediate) perf.data file
    # since that is tied to the build, and the orchestrator decided that we
    # should run (no build to recycle).
    #
    # Check if there is already a published AFDO artifact for this version of
    # Chrome.
    return self._CommonPrepareBasedOnGsPathExists(
        name=self._GetBenchmarkAFDOName() + BZ2_COMPRESSION_SUFFIX,
        url=BENCHMARK_AFDO_GS_URL,
        key='UnverifiedChromeBenchmarkAfdoFile')

  def _PrepareUnverifiedChromeBenchmarkPerfFile(self):
    """Prepare to build the Chrome benchmark perf.data file."""
    return self._UnverifiedAfdoFileExists()

  def _PrepareUnverifiedChromeBenchmarkAfdoFile(self):
    """Prepare to build an Unverified Chrome benchmark AFDO file."""
    ret = self._UnverifiedAfdoFileExists()
    if self.chroot:
      # Fetch the CHROME_DEBUG_BINARY and UNVERIFIED_CHROME_BENCHMARK_PERF_FILE
      # artifacts and unpack them for the Bundle call.
      workdir_full = self.chroot.full_path(self._AfdoTmpPath())
      # Clean out the workdir.
      osutils.RmDir(workdir_full, ignore_missing=True, sudo=True)
      osutils.SafeMakedirs(workdir_full)

      bin_name = self._GetBenchmarkAFDOName(
          CHROME_DEBUG_BINARY_NAME) + BZ2_COMPRESSION_SUFFIX
      bin_compressed = self._AfdoTmpPath(bin_name)
      bin_url = self._FindArtifact(
          bin_name, self.input_artifacts.get('ChromeDebugBinary', []))
      cros_build_lib.run([
          'gsutil', '-o', 'Boto:num_retries=10', 'cp', '-v', '--', bin_url,
          bin_compressed
      ],
                         enter_chroot=True,
                         print_cmd=True)
      cros_build_lib.run(['bzip2', '-d', bin_compressed],
                         enter_chroot=True,
                         print_cmd=True)

      perf_name = (
          self._GetBenchmarkAFDOName(template=CHROME_PERF_AFDO_FILE) +
          BZ2_COMPRESSION_SUFFIX)
      perf_compressed = self._AfdoTmpPath(perf_name)
      perf_url = self._FindArtifact(
          perf_name,
          self.input_artifacts.get('UnverifiedChromeBenchmarkPerfFile', []))
      self.gs_context.Copy(perf_url, self.chroot.full_path(perf_compressed))
      cros_build_lib.run(['bzip2', '-d', perf_compressed],
                         enter_chroot=True,
                         print_cmd=True)
    return ret

  def _PrepareChromeAFDOProfileForAndroidLinux(self):
    """Prepare to build Chrome AFDO profile for Android/Linux."""
    if self._UnverifiedAfdoFileExists() == PrepareForBuildReturn.POINTLESS:
      # Only generate new Android/Linux profiles when there's a need to
      # generate new benchmark profiles
      return PrepareForBuildReturn.POINTLESS

    return self._CommonPrepareBasedOnGsPathExists(
        name=self._GetBenchmarkAFDOName() + '-merged' + BZ2_COMPRESSION_SUFFIX,
        url=BENCHMARK_AFDO_GS_URL,
        key='ChromeAFDOProfileForAndroidLinux')

  def _PrepareVerifiedChromeBenchmarkAfdoFile(self):
    """Unused: see _PrepareVerifiedReleaseAfdoFile."""
    raise PrepareForBuildHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _PrepareChromeDebugBinary(self):
    """See _PrepareUnverifiedChromeBenchmarkPerfFile."""
    return PrepareForBuildReturn.POINTLESS

  def _PrepareUnverifiedKernelCwpAfdoFile(self):
    """Unused: CWP is from elsewhere."""
    raise PrepareForBuildHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _PrepareVerifiedKernelCwpAfdoFile(self):
    """Prepare to verify the kernel CWP AFDO artifact."""
    ret = PrepareForBuildReturn.NEEDED
    kernel_version = self.profile_info.get('kernel_version')
    if not kernel_version:
      raise PrepareForBuildHandlerError(
          'Could not find kernel version to verify.')
    cwp_locs = [
        x for x in self.input_artifacts.get(
            'UnverifiedKernelCwpAfdoFile',
            [os.path.join(KERNEL_PROFILE_URL, kernel_version)])
    ]
    afdo_path = self._FindLatestAFDOArtifact(cwp_locs,
                                             self._RankValidCWPProfiles)

    published_path = os.path.join(
        self.input_artifacts.get(
            'VerifiedKernelCwpAfdoFile',
            [os.path.join(KERNEL_AFDO_GS_URL_VETTED, kernel_version)])[0],
        os.path.basename(afdo_path))
    if self.gs_context.Exists(published_path):
      # The verified artifact is already present: we are done.
      logging.info('Pointless build: "%s" exists.', published_path)
      ret = PrepareForBuildReturn.POINTLESS

    afdo_dir, afdo_name = os.path.split(
        afdo_path.replace(KERNEL_AFDO_COMPRESSION_SUFFIX, ''))
    # The package name cannot have dots, so an underscore is used instead.
    # For example: chromeos-kernel-4_4-4.4.214-r2087.ebuild.
    kernel_version = kernel_version.replace('.', '_')

    # Check freshness.
    age = _GetProfileAge(afdo_name, 'kernel_afdo')
    if age > KERNEL_ALLOWED_STALE_DAYS:
      logging.info('Found an expired afdo for kernel %s: %s, skip.',
                   kernel_version, afdo_name)
      ret = PrepareForBuildReturn.POINTLESS

    if age > KERNEL_WARN_STALE_DAYS:
      _WarnSheriffAboutKernelProfileExpiration(kernel_version, afdo_name)

    # If we don't have an SDK, then we cannot update the manifest.
    if self.chroot:
      self._PatchEbuild(
          self._GetEbuildInfo('chromeos-kernel-%s' % kernel_version,
                              'sys-kernel'), {
                                  'AFDO_PROFILE_VERSION': afdo_name,
                                  'AFDO_LOCATION': afdo_dir
                              },
          uprev=True)
    return ret

  def _PrepareUnverifiedChromeCwpAfdoFile(self):
    """Unused: CWP is from elsewhere."""
    raise PrepareForBuildHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _PrepareVerifiedChromeCwpAfdoFile(self):
    """Unused: see _PrepareVerifiedReleaseAfdoFile."""
    raise PrepareForBuildHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _PrepareVerifiedReleaseAfdoFile(self):
    """Prepare to verify the Chrome AFDO artifact and release it.

    See also "chrome_afdo" code elsewhere in this file.
    """
    ret = PrepareForBuildReturn.NEEDED
    profile = self.profile_info.get('chrome_cwp_profile')
    if not profile:
      raise PrepareForBuildHandlerError('Could not find profile name.')
    bench_locs = self.input_artifacts.get('UnverifiedChromeBenchmarkAfdoFile',
                                          [BENCHMARK_AFDO_GS_URL])
    cwp_locs = self.input_artifacts.get('UnverifiedChromeCwpAfdoFile',
                                        [CWP_AFDO_GS_URL])

    # This will raise a RuntimeError if no artifact is found.
    bench = self._FindLatestAFDOArtifact(bench_locs,
                                         self._RankValidBenchmarkProfiles)
    cwp = self._FindLatestAFDOArtifact(cwp_locs, self._RankValidCWPProfiles)
    bench_name = os.path.split(bench)[1]
    cwp_name = os.path.split(cwp)[1]

    # Check to see if we already have a verified AFDO profile.
    # We only look at the first path in the list of vetted locations, since that
    # is where we will publish the verified profile.
    published_loc = self.input_artifacts.get('VerifiedReleaseAfdoFile',
                                             [RELEASE_AFDO_GS_URL_VETTED])[0]
    merged_name = MERGED_AFDO_NAME % _GetCombinedAFDOName(
        _ParseCWPProfileName(os.path.splitext(cwp_name)[0]), profile,
        _ParseBenchmarkProfileName(os.path.splitext(bench_name)[0]))
    published_name = merged_name + '-redacted.afdo' + XZ_COMPRESSION_SUFFIX
    published_path = os.path.join(published_loc, published_name)

    if self.gs_context.Exists(published_path):
      # The verified artifact is already present: we are done.
      logging.info('Pointless build: "%s" exists.', published_path)
      ret = PrepareForBuildReturn.POINTLESS

    # If we don't have an SDK, then we cannot update the manifest.
    if self.chroot:
      # Generate the AFDO profile to verify in ${CHROOT}/tmp/.
      with self.chroot.tempdir() as tempdir:
        art = self._CreateReleaseChromeAFDO(cwp, bench, tempdir, merged_name)
        afdo_profile = os.path.join(self.chroot.tmp, os.path.basename(art))
        os.rename(art, afdo_profile)
      self._PatchEbuild(
          self._GetEbuildInfo(constants.CHROME_PN),
          {'UNVETTED_AFDO_FILE': self.chroot.chroot_path(afdo_profile)},
          uprev=True)
    return ret

  def _PrepareToolchainWarningLogs(self):
    # We always build this artifact.
    # Cleanup the temp directory that holds the artifacts
    self._CleanupArtifactDirectory('/tmp/fatal_clang_warnings')
    return PrepareForBuildReturn.NEEDED

  def _PrepareClangCrashDiagnoses(self):
    # We always build this artifact.
    # Cleanup the temp directory that holds the artifacts
    self._CleanupArtifactDirectory('/tmp/clang_crash_diagnostics')
    return PrepareForBuildReturn.UNKNOWN

  def _PrepareCompilerRusageLogs(self):
    # We always build this artifact.
    # Cleanup the temp directory that holds the artifacts
    self._CleanupArtifactDirectory('/tmp/compiler_rusage')
    return PrepareForBuildReturn.UNKNOWN


class BundleArtifactHandler(_CommonPrepareBundle):
  """Methods for updating ebuilds for toolchain artifacts."""

  def __init__(self, artifact_name, chroot, sysroot_path, build_target,
               output_dir, profile_info):
    super().__init__(
        artifact_name,
        chroot,
        sysroot_path,
        build_target,
        profile_info=profile_info)
    self._bundle_func = getattr(self, '_Bundle' + artifact_name)
    self.output_dir = output_dir

  def Bundle(self):
    return self._bundle_func()

  def _BundleUnverifiedChromeLlvmOrderfile(self):
    """Bundle to build an unverified ordering file."""
    with self.chroot.tempdir() as tempdir:
      GenerateChromeOrderfile(
          board=self.build_target,
          output_dir=tempdir,
          chrome_root=self.chroot.chrome_root,
          chroot_path=self.chroot.path,
          chroot_args=self.chroot.get_enter_args()).Bundle()

      files = []
      for path in osutils.DirectoryIterator(tempdir):
        if os.path.isfile(path):
          rel_path = os.path.relpath(path, tempdir)
          files.append(os.path.join(self.output_dir, rel_path))
      osutils.CopyDirContents(tempdir, self.output_dir, allow_nonempty=True)

    return files

  def _BundleVerifiedChromeLlvmOrderfile(self):
    """Bundle vetted ordering file."""
    orderfile_name = self._GetArtifactVersionInEbuild(
        constants.CHROME_PN, 'UNVETTED_ORDERFILE') + XZ_COMPRESSION_SUFFIX
    # Strip the leading / from sysroot_path.
    orderfile_path = self.chroot.full_path(self.sysroot_path,
                                           'opt/google/chrome', orderfile_name)
    verified_orderfile = os.path.join(self.output_dir, orderfile_name)
    shutil.copy2(orderfile_path, verified_orderfile)
    return [verified_orderfile]

  def _BundleChromeClangWarningsFile(self):
    """Bundle clang-tidy warnings file."""
    with self.chroot.tempdir() as tempdir:
      in_chroot_tempdir = self.chroot.chroot_path(tempdir)
      now = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d')
      clang_tidy_tarball = (f'{self.build_target}.{now}'
                            '.clang_tidy_warnings.tar.xz')
      cmd = [
          'cros_generate_tidy_warnings', '--out-file', clang_tidy_tarball,
          '--out-dir', in_chroot_tempdir, '--board', self.build_target,
          '--logs-dir',
          os.path.join('/tmp/clang-tidy-logs', self.build_target)
      ]
      cros_build_lib.run(cmd, cwd=self.chroot.path, enter_chroot=True)
      artifact_path = os.path.join(self.output_dir, clang_tidy_tarball)
      shutil.copy2(os.path.join(tempdir, clang_tidy_tarball), artifact_path)
    return [artifact_path]

  def _GetProfileNames(self, datadir):
    """Return list of profiles.

    This function is for ease in test writing.

    Args:
      datadir: Absolute path to build/coverage_data in the sysroot.

    Returns:
      list of chroot-relative paths to profiles found.
    """
    return [
        self.chroot.chroot_path(os.path.join(dir_name, file_name))
        for dir_name, _, files in os.walk(datadir)
        for file_name in files
        if os.path.basename(dir_name) == 'raw_profiles'
    ]

  def _BundleUnverifiedLlvmPgoFile(self):
    """Bundle the unverified PGO profile for llvm."""
    # What is the CPV for the compiler?
    llvm_cpv = portage_util.FindPackageNameMatches('sys-devel/llvm')[0]

    files = []
    # Find all of the raw profile data.
    datadir = self.chroot.full_path(self.sysroot_path, 'build', 'coverage_data')
    profiles = self._GetProfileNames(datadir)
    if not profiles:
      raise BundleArtifactsHandlerError('No raw profiles found in %s' % datadir)

    # Capture the clang version.
    clang_version_str = cros_build_lib.sudo_run(
        ['clang', '--version'],
        enter_chroot=True,
        stdout=True,
        encoding='utf-8').output.splitlines()[0].strip()
    # TODO(crbug.com/1132918): There's a git-r3 bug that caused the LLVM build
    # failed to find the upstream URL, so use the string contains the local
    # path to clang source instead.
    match = re.search(r'(?:llvm-project|clang) ([A-Fa-f0-9]{40})\)$',
                      clang_version_str)
    if not match:
      raise BundleArtifactsHandlerError(
          "Can't recognize the version string %s" % clang_version_str)
    head_sha = match.group(1)
    profdata_base = '%s-%s' % (llvm_cpv.pv, head_sha)
    metadata_path = os.path.join(self.output_dir,
                                 profdata_base + '.llvm_metadata.json')
    pformat.json({'head_sha': head_sha}, fp=metadata_path, compact=True)
    files.append(metadata_path)
    metadata_path = os.path.join(self.output_dir, 'llvm_metadata.json')
    pformat.json({'head_sha': head_sha}, fp=metadata_path, compact=True)
    files.append(metadata_path)

    # Create a tarball with the merged profile data.  The name will be of the
    # form '{llvm-package-pv}-{clang-head_sha}.llvm_profdata.tar.zx.
    with self.chroot.tempdir() as tempdir:
      raw_list = os.path.join(tempdir, 'profraw_list')
      with open(raw_list, 'w') as f:
        f.write('\n'.join(profiles))
      basename = '%s.llvm.profdata' % profdata_base
      merged_path = os.path.join(tempdir, basename)
      cros_build_lib.sudo_run([
          'llvm-profdata', 'merge', '-f',
          self.chroot.chroot_path(raw_list), '-output',
          self.chroot.chroot_path(merged_path)
      ],
                              cwd=tempdir,
                              enter_chroot=True)
      artifact = os.path.join(self.output_dir, '%s.tar.xz' % basename)
      cros_build_lib.CreateTarball(artifact, cwd=tempdir, inputs=[basename])
      files.append(artifact)
    return files

  def _BundleUnverifiedChromeBenchmarkPerfFile(self):
    """Bundle the unverified Chrome benchmark perf.data file.

    The perf.data file is created in the HW Test, and afdo_process needs the
    matching unstripped Chrome binary in order to generate the profile.
    """
    return []

  def _BundleChromeDebugBinary(self):
    """Bundle the unstripped Chrome binary."""
    debug_bin_inside = _CHROME_DEBUG_BIN % {
        'root': '',
        'sysroot': self.sysroot_path
    }
    binary_name = self._GetBenchmarkAFDOName(CHROME_DEBUG_BINARY_NAME)
    bin_path = os.path.join(self.output_dir,
                            binary_name + BZ2_COMPRESSION_SUFFIX)
    with open(bin_path, 'w') as f:
      cros_build_lib.run(['bzip2', '-c', debug_bin_inside],
                         stdout=f,
                         enter_chroot=True,
                         print_cmd=True)
    return [bin_path]

  def _BundleUnverifiedChromeBenchmarkAfdoFile(self):
    files = []
    # If the name of the provided binary is not 'chrome.unstripped', then
    # create_llvm_prof demands it exactly matches the name of the unstripped
    # binary.  Create a symbolic link named 'chrome.unstripped'.
    CHROME_UNSTRIPPED_NAME = 'chrome.unstripped'
    bin_path_in = self._AfdoTmpPath(CHROME_UNSTRIPPED_NAME)
    osutils.SafeSymlink(
        self._GetBenchmarkAFDOName(CHROME_DEBUG_BINARY_NAME),
        self.chroot.full_path(bin_path_in))
    perf_path_inside = self._AfdoTmpPath(
        self._GetBenchmarkAFDOName(template=CHROME_PERF_AFDO_FILE))
    afdo_name = self._GetBenchmarkAFDOName()
    afdo_path_inside = self._AfdoTmpPath(afdo_name)
    # Generate the afdo profile.
    cros_build_lib.run(
        [
            _AFDO_GENERATE_LLVM_PROF,
            '--binary=%s' % self._AfdoTmpPath(CHROME_UNSTRIPPED_NAME),
            '--profile=%s' % perf_path_inside,
            '--out=%s' % afdo_path_inside,
            # Do not set any sample threshold, so the AFDO profile can be as
            # precise as the raw profile.
            '--sample_threshold_frac=0',
        ],
        enter_chroot=True,
        print_cmd=True)
    logging.info('Generated %s AFDO profile %s', self.arch, afdo_name)

    # Compress and deliver the profile.
    afdo_path = os.path.join(self.output_dir,
                             afdo_name + BZ2_COMPRESSION_SUFFIX)
    with open(afdo_path, 'w') as f:
      cros_build_lib.run(['bzip2', '-c', afdo_path_inside],
                         stdout=f,
                         enter_chroot=True,
                         print_cmd=True)
    files.append(afdo_path)
    return files

  def _BundleChromeAFDOProfileForAndroidLinux(self):
    """Bundle Android/Linux Chrome profiles."""
    afdo_name = self._GetBenchmarkAFDOName()
    output_dir_full = self.chroot.full_path(self._AfdoTmpPath())
    afdo_path = os.path.join(output_dir_full, afdo_name)
    # The _BundleUnverifiedChromeBenchmarkAfdoFile should always run
    # before this, so the AFDO profile should already be created.
    assert os.path.exists(afdo_path), (
        'No new AFDO profile created before creating Android/Linux profiles')

    files = []
    # Merge recent benchmark profiles for Android/Linux use
    merged_profile = self._CreateAndUploadMergedAFDOProfile(
        os.path.join(output_dir_full, afdo_name), output_dir_full)
    if not merged_profile:
      return []

    merged_profile_inside = self._AfdoTmpPath(os.path.basename(merged_profile))
    merged_profile_compressed = os.path.join(
        self.output_dir,
        os.path.basename(merged_profile) + BZ2_COMPRESSION_SUFFIX)

    with open(merged_profile_compressed, 'wb') as f:
      cros_build_lib.run(['bzip2', '-c', merged_profile_inside],
                         stdout=f,
                         enter_chroot=True,
                         print_cmd=True)
    files.append(merged_profile_compressed)
    return files

  def _BundleVerifiedChromeBenchmarkAfdoFile(self):
    """Unused: see _BundleVerifiedReleaseAfdoFile."""
    raise BundleArtifactsHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _BundleUnverifiedKernelCwpAfdoFile(self):
    """Unused: this artifact comes from CWP."""
    raise BundleArtifactsHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _BundleVerifiedKernelCwpAfdoFile(self):
    """Bundle the verified kernel CWP AFDO file."""
    kernel_version = self.profile_info.get('kernel_version')
    if not kernel_version:
      raise BundleArtifactsHandlerError('kernel_version not provided.')
    kernel_version = kernel_version.replace('.', '_')
    profile_name = self._GetArtifactVersionInEbuild(
        'chromeos-kernel-%s' % kernel_version,
        'AFDO_PROFILE_VERSION') + KERNEL_AFDO_COMPRESSION_SUFFIX
    # The verified profile is in the sysroot with a name similar to:
    # /usr/lib/debug/boot/chromeos-kernel-4_4-R82-12874.0-1581935639.gcov.xz
    profile_path = os.path.join(
        self.chroot.path, self.sysroot_path[1:], 'usr', 'lib', 'debug', 'boot',
        'chromeos-kernel-%s-%s' % (kernel_version, profile_name))
    verified_profile = os.path.join(self.output_dir, profile_name)
    shutil.copy2(profile_path, verified_profile)
    return [verified_profile]

  def _BundleUnverifiedChromeCwpAfdoFile(self):
    """Unused: this artifact comes from CWP."""
    raise BundleArtifactsHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _BundleVerifiedChromeCwpAfdoFile(self):
    """Unused: see _BundleVerifiedReleaseAfdoFile."""
    raise BundleArtifactsHandlerError('Unexpected artifact type %s.' %
                                      self.artifact_name)

  def _BundleVerifiedReleaseAfdoFile(self):
    """Bundle the verified Release AFDO file for Chrome."""
    profile_path = self.chroot.full_path(
        self._GetArtifactVersionInEbuild(constants.CHROME_PN,
                                         'UNVETTED_AFDO_FILE'))
    return _CompressAFDOFiles([profile_path], None, self.output_dir,
                              XZ_COMPRESSION_SUFFIX)

  @staticmethod
  def _ListTransitiveFiles(base_directory: str):
    for dir_path, _dir_names, file_names in os.walk(base_directory):
      for file_name in file_names:
        yield os.path.join(dir_path, file_name)

  def _CollectFiles(self, src_dir, dest_dir, include_file):
    """Collect the files with any of file_exts from path to working_dir.

    Args:
      src_dir: the path to the directory to copy files from.
      dest_dir: the path of the directory to copy files to (will be created if
                it doesn't exist and files need to be copied).
      include_file: a callable that returns True if a file should be copied;
                    False otherwise.

    Returns:
      A list of all files that were copied, relative to `src_dir`.
    """
    check_dirs = [
        self.chroot.full_path(x) for x in [
            src_dir,
            os.path.join(self.sysroot_path,
                         src_dir[1:] if os.path.isabs(src_dir) else src_dir)
        ]
    ]

    logging.info('toolchain-logs: checking %s', check_dirs)
    output = []
    for directory in check_dirs:
      if not os.path.isdir(directory):
        logging.info("toolchain-logs: %s doesn't exist", directory)
        continue

      for src_path in self._ListTransitiveFiles(directory):
        rel_path = os.path.relpath(src_path, start=directory)
        logging.info('toolchain-logs: checking %s', rel_path)
        if not include_file(rel_path):
          logging.warning('toolchain-logs: skipped file: %s', rel_path)
          continue

        dest_path = os.path.join(dest_dir, rel_path)
        while os.path.exists(dest_path):
          file_noext, file_ext = os.path.splitext(dest_path)
          dest_path = f'{file_noext}0{file_ext}'

        osutils.SafeMakedirs(os.path.dirname(dest_path))
        rel_dest_path = os.path.relpath(dest_path, start=dest_dir)

        logging.info('toolchain-logs: adding path %s as %s', src_path,
                     dest_path)
        shutil.copy(src_path, dest_path)
        output.append(rel_dest_path)

    logging.info('%d files collected', len(output))
    return output

  def _CreateBundle(self, src_dir, tarball, destination, extension=None):
    """Bundle the files from src_dir into a tar.xz file.

    Args:
      src_dir: the path to the directory to copy files from.
      tarball: name of the generated tarballfile (build target, time stamp,
        and .tar.xz extension will be added automatically)
      destination: path to create tarball in
      extension: type of file to search for in src_dir.
        If extension is None (default), all file types will be allowed.

    Returns:
      Path to the generated tar.xz file
    """

    def FilterFile(file_path):
      return extension is None or file_path.endswith(extension)

    files = self._CollectFiles(src_dir, destination, include_file=FilterFile)
    if not files:
      logging.info('No data found for %s, skip bundle artifact', tarball)
      raise NoArtifactsToBundleError(f'No {extension} files in {src_dir}')

    now = datetime.datetime.strftime(datetime.datetime.now(), '%Y%m%d')
    name = f'{self.build_target}.{now}.{tarball}.tar.xz'
    output_compressed = os.path.join(self.output_dir, name)
    cros_build_lib.CreateTarball(output_compressed, destination, inputs=files)

    return output_compressed

  def _BundleToolchainWarningLogs(self):
    """Bundle the compiler warnings for upload for werror checker."""
    with self.chroot.tempdir() as tempdir:
      try:
        return [
            self._CreateBundle('/tmp/fatal_clang_warnings',
                               'fatal_clang_warnings', tempdir, '.json')
        ]
      except NoArtifactsToBundleError:
        return []

  def _BundleClangCrashDiagnoses(self):
    """Bundle all clang crash diagnoses in chroot for uploading.

      See bugs.chromium.org/p/chromium/issues/detail?id=1056904 for context.
    """
    with osutils.TempDir(prefix='clang_crash_diagnoses_tarball') as tempdir:
      try:
        return [
            self._CreateBundle('/tmp/clang_crash_diagnostics',
                               'clang_crash_diagnoses', tempdir)
        ]
      except NoArtifactsToBundleError:
        return []

  def _BundleCompilerRusageLogs(self):
    """Bundle the rusage files created by compiler invocations.

    This is useful for monitoring changes in compiler performance.
    These files are created when the TOOLCHAIN_RUSAGE_OUTPUT variable
    is set in the environment for monitoring compiler performance.
    """
    with self.chroot.tempdir() as tempdir:
      try:
        return [
            self._CreateBundle('/tmp/compiler_rusage', 'compiler_rusage_logs',
                               tempdir, '.json')
        ]
      except NoArtifactsToBundleError:
        return []


def PrepareForBuild(artifact_name, chroot, sysroot_path, build_target,
                    input_artifacts, profile_info):
  """Prepare for building artifacts.

  This code is called OUTSIDE the chroot, before it is set up.

  Args:
    artifact_name: artifact name
    chroot: chroot_lib.Chroot instance for chroot.
    sysroot_path: path to sysroot, relative to chroot path, or None.
    build_target: name of build target, or None.
    input_artifacts: List(InputArtifactInfo) of available artifact locations.
    profile_info: dict(key=value)  See ArtifactProfileInfo.

  Returns:
    PrepareForBuildReturn
  """

  return PrepareForBuildHandler(
      artifact_name,
      chroot,
      sysroot_path,
      build_target,
      input_artifacts=input_artifacts,
      profile_info=profile_info).Prepare()


def BundleArtifacts(name, chroot, sysroot_path, build_target, output_dir,
                    profile_info):
  """Prepare for building artifacts.

  This code is called OUTSIDE the chroot, after it is set up.

  Args:
    name: artifact name
    chroot: chroot_lib.Chroot instance for chroot.
    sysroot_path: path to sysroot, relative to chroot path.
    chrome_root: path to chrome root.
    build_target: name of build target
    output_dir: path in which to place the artifacts.
    profile_info: dict(key=value)  See ArtifactProfileInfo.

  Returns:
    list of artifacts, relative to output_dir.
  """
  return BundleArtifactHandler(
      name,
      chroot,
      sysroot_path,
      build_target,
      output_dir,
      profile_info=profile_info).Bundle()


class GetUpdatedFilesHandler(object):
  """Find all changed files in the checkout and create a commit message."""

  @staticmethod
  def _UpdateKernelMetadata(kernel_version: str, profile_version: str):
    """Update afdo_metadata json file"""
    kernel_version = kernel_version.replace('.', '_')
    json_file = os.path.join(TOOLCHAIN_UTILS_PATH, 'afdo_metadata',
                             f'kernel_afdo_{kernel_version}.json')
    assert os.path.exists(json_file), (
      f'Metadata for {kernel_version} does not exist')
    afdo_versions = json.loads(osutils.ReadFile(json_file))
    kernel_name = f'chromeos-kernel-{kernel_version}'
    assert kernel_name in afdo_versions, (
      f'To update {kernel_name}, the entry should be in kernel_afdo.json')
    old_value = afdo_versions[kernel_name]['name']
    update_to_newer_profile = _RankValidCWPProfiles(
        old_value) < _RankValidCWPProfiles(profile_version)
    # This function is called after Bundle, so normally the profile is newer
    # is guaranteed because Bundle function only runs when a new profile is
    # needed to verify at the beginning of the builder. This check is to
    # make sure there's no other updates happen between the start of the
    # builder and the time of this function call.
    assert update_to_newer_profile, (
        f'Failed to update JSON file because {profile_version} is not '
        f'newer than {old_value}')
    afdo_versions[kernel_name]['name'] = profile_version
    pformat.json(afdo_versions, fp=json_file)
    return [json_file]

  def __init__(self, artifact_type, artifact_path, profile_info):
    self.artifact_path = artifact_path
    self.profile_info = profile_info
    if artifact_type == 'VerifiedKernelCwpAfdoFile':
      self._update_func = self.UpdateKernelProfileMetadata
    else:
      raise GetUpdatedFilesForCommitError(
          f'{artifact_type} has no handler in GetUpdatedFiles')

  def UpdateKernelProfileMetadata(self):
    kernel_version = self.profile_info.get('kernel_version')
    if not kernel_version:
      raise GetUpdatedFilesForCommitError('kernel_version not provided')
    # The path obtained from artifact_path is the full path, containing
    # extension, so we need to remove it here.
    profile_version = os.path.basename(self.artifact_path).replace(
        KERNEL_AFDO_COMPRESSION_SUFFIX, '')
    files = self._UpdateKernelMetadata(kernel_version, profile_version)
    commit_message = (
        f'afdo_metadata: Publish new kernel profiles for {kernel_version}\n\n'
        f'Update {kernel_version} to {profile_version}\n\n'
        'Automatically generated in kernel verifier.\n\n'
        'BUG=None\n'
        'TEST=Verified in kernel-release-afdo-verify-orchestrator\n')
    return files, commit_message

  def Update(self):
    return self._update_func()


def GetUpdatedFiles(artifact_type, artifact_path, profile_info):
  return GetUpdatedFilesHandler(artifact_type, artifact_path,
                                profile_info).Update()


# ###########################################################################
#
# TODO(crbug/1019868): delete once cbuildbot is gone.
# LEGACY CODE: used primarily by cbuildbot.
#
# ###########################################################################
def OrderfileUpdateChromeEbuild(board):
  """Update Chrome ebuild with latest unvetted orderfile.

  Args:
    board: Board type that was built on this machine.

  Returns:
    Status of the update.
  """

  orderfile_name = _FindLatestAFDOArtifact(ORDERFILE_GS_URL_UNVETTED,
                                           _RankValidOrderfiles)

  if not orderfile_name:
    logging.info('No eligible orderfile to verify.')
    return False

  updater = UpdateEbuildWithAFDOArtifacts(
      board=board,
      package='chromeos-chrome',
      update_rules={'UNVETTED_ORDERFILE': os.path.splitext(orderfile_name)[0]})
  updater.Perform()
  return True


def AFDOUpdateChromeEbuild(board):
  """Update Chrome ebuild with latest unvetted AFDO profiles.

  Args:
    board: Board to verify the Chrome afdo.

  Returns:
    Status of the update.
  """
  benchmark_afdo = _FindLatestAFDOArtifact(BENCHMARK_AFDO_GS_URL,
                                           _RankValidBenchmarkProfiles)
  arch = CHROME_AFDO_VERIFIER_BOARDS[board]
  url = os.path.join(CWP_AFDO_GS_URL, arch)
  cwp_afdo = _FindLatestAFDOArtifact(url, _RankValidCWPProfiles)

  if not benchmark_afdo or not cwp_afdo:
    logging.info('No eligible benchmark or cwp AFDO to verify.')
    return False

  with osutils.TempDir() as tempdir:
    result = _CreateReleaseChromeAFDO(
        os.path.splitext(cwp_afdo)[0], arch,
        os.path.splitext(benchmark_afdo)[0], tempdir)
    afdo_profile_for_verify = os.path.join('/tmp', os.path.basename(result))
    os.rename(result, afdo_profile_for_verify)

  updater = UpdateEbuildWithAFDOArtifacts(
      board=board,
      package='chromeos-chrome',
      update_rules={'UNVETTED_AFDO_FILE': afdo_profile_for_verify})
  updater.Perform()
  return True


def AFDOUpdateKernelEbuild(board):
  """Update kernel ebuild with latest unvetted AFDO profile.

  Args:
    board: Board to verify the kernel type.

  Returns:
    Status of the update.
  """

  # For kernel profiles, need to find out the current branch in order to
  # filter out profiles on other branches.
  url = os.path.join(KERNEL_PROFILE_URL, KERNEL_AFDO_VERIFIER_BOARDS[board])
  kernel_afdo = _FindLatestAFDOArtifact(url, _RankValidCWPProfiles)
  kver = KERNEL_AFDO_VERIFIER_BOARDS[board].replace('.', '_')
  # The kernel_afdo from GS bucket contains .gcov.xz suffix, but the name
  # of the afdo in kernel ebuild doesn't. Need to strip it out.
  kernel_afdo_in_ebuild = kernel_afdo.replace(KERNEL_AFDO_COMPRESSION_SUFFIX,
                                              '')

  # Check freshness
  age = _GetProfileAge(kernel_afdo_in_ebuild, 'kernel_afdo')
  if age > KERNEL_ALLOWED_STALE_DAYS:
    logging.info('Found an expired afdo for kernel %s: %s, skip.', kver,
                 kernel_afdo_in_ebuild)
    return False

  if age > KERNEL_WARN_STALE_DAYS:
    _WarnSheriffAboutKernelProfileExpiration(kver, kernel_afdo_in_ebuild)

  updater = UpdateEbuildWithAFDOArtifacts(
      board=board,
      package='chromeos-kernel-' + kver,
      update_rules={'AFDO_PROFILE_VERSION': kernel_afdo_in_ebuild})
  updater.Perform()
  return True


class GenerateBenchmarkAFDOProfile(object):
  """Class that generate benchmark AFDO profile.

  This class waits for the raw sampled profile data (perf.data) from another
  stage that runs hardware tests and uploads it to GS bucket. Once the profile
  is seen, this class downloads the raw profile, and processes it into
  LLVM-readable AFDO profiles. Then uploads the AFDO profile. This class also
  uploads an unstripped Chrome binary for debugging purpose if needed.
  """

  def __init__(self, board, output_dir, chroot_path, chroot_args):
    """Construct an object for generating benchmark profiles.

    Args:
      board: The name of the board.
      output_dir: The path to save output files.
      chroot_path: The chroot path.
      chroot_args: The arguments used to enter chroot.
    """
    self.board = board
    self.chroot_path = chroot_path
    self.chroot_args = chroot_args
    self.buildroot = os.path.join(chroot_path, '..')
    self.chrome_cpv = portage_util.PortageqBestVisible(
        constants.CHROME_CP, cwd=self.buildroot)
    self.arch = portage_util.PortageqEnvvar(
        'ARCH', board=board, allow_undefined=True)
    # Directory used to store intermediate artifacts
    self.working_dir = os.path.join(self.chroot_path, 'tmp')
    self.working_dir_inchroot = '/tmp'
    # Output directory
    self.output_dir = output_dir

  def _DecompressAFDOFile(self, to_decompress):
    """Decompress file used by AFDO process.

    Args:
      to_decompress: File to decompress.

    Returns:
      The full path to the uncompressed file.
    """
    basename = os.path.basename(to_decompress)
    dest_basename = os.path.splitext(basename)[0]
    dest = os.path.join(self.working_dir, dest_basename)
    cros_build_lib.UncompressFile(to_decompress, dest)
    return dest

  def _GetPerfAFDOName(self):
    """Construct a name for perf.data for current chrome version."""
    # The file name of the perf data is based only in the chrome version.
    # The test case that produces it does not know anything about the
    # revision number.
    # TODO(llozano): perf data filename should include the revision number.
    version_number = self.chrome_cpv.version_no_rev.split('_')[0]
    chrome_spec = {
        'package': self.chrome_cpv.package,
        'arch': self.arch,
        'versionnorev': version_number
    }
    return CHROME_PERF_AFDO_FILE % chrome_spec

  def _CheckAFDOPerfDataStatus(self):
    """Check whether AFDO perf data on GS bucket.

    Check if 'perf' data file for this architecture and release is available
    in GS.

    Returns:
      True if AFDO perf data is available. False otherwise.
    """
    gs_context = gs.GSContext()
    url = os.path.join(BENCHMARK_AFDO_GS_URL,
                       self._GetPerfAFDOName() + BZ2_COMPRESSION_SUFFIX)
    if not gs_context.Exists(url):
      logging.info('Could not find AFDO perf data at %s', url)
      return False

    logging.info('Found AFDO perf data at %s', url)
    return True

  def _WaitForAFDOPerfData(self):
    """Wait until hwtest finishes and the perf.data uploaded to GS bucket.

    Returns:
      True if hwtest finishes and perf.data is copied to local buildroot
      False if timeout.
    """
    try:
      timeout_util.WaitForReturnTrue(
          self._CheckAFDOPerfDataStatus,
          timeout=constants.AFDO_GENERATE_TIMEOUT,
          period=constants.SLEEP_TIMEOUT)
    except timeout_util.TimeoutError:
      logging.info('Could not find AFDO perf data before timeout')
      return False

    gs_context = gs.GSContext()
    url = os.path.join(BENCHMARK_AFDO_GS_URL,
                       self._GetPerfAFDOName() + BZ2_COMPRESSION_SUFFIX)
    dest_path = os.path.join(self.working_dir, url.rsplit('/', 1)[1])
    gs_context.Copy(url, dest_path)

    self._DecompressAFDOFile(dest_path)
    logging.info('Retrieved AFDO perf data to %s', dest_path)
    return True

  def _CreateAFDOFromPerfData(self):
    """Create LLVM-readable AFDO profile from raw sampled perf data.

    Returns:
      Name of the generated AFDO profile.
    """
    CHROME_UNSTRIPPED_NAME = 'chrome.unstripped'
    # create_llvm_prof demands the name of the profiled binary exactly matches
    # the name of the unstripped binary or it is named 'chrome.unstripped'.
    # So create a symbolic link with the appropriate name.
    debug_sym = os.path.join(self.working_dir, CHROME_UNSTRIPPED_NAME)
    debug_binary_inchroot = _CHROME_DEBUG_BIN % {
        'root': '',
        'sysroot': os.path.join('build', self.board)
    }
    osutils.SafeSymlink(debug_binary_inchroot, debug_sym)

    # Call create_llvm_prof tool to generated AFDO profile from 'perf' profile
    # These following paths are converted to the path relative inside chroot.
    debug_sym_inchroot = os.path.join(self.working_dir_inchroot,
                                      CHROME_UNSTRIPPED_NAME)
    perf_afdo_inchroot_path = os.path.join(self.working_dir_inchroot,
                                           self._GetPerfAFDOName())
    afdo_name = _GetBenchmarkAFDOName(self.buildroot, self.board)
    afdo_inchroot_path = os.path.join(self.working_dir_inchroot, afdo_name)
    afdo_cmd = [
        _AFDO_GENERATE_LLVM_PROF,
        '--binary=%s' % debug_sym_inchroot,
        '--profile=%s' % perf_afdo_inchroot_path,
        '--out=%s' % afdo_inchroot_path,
    ]
    cros_build_lib.run(
        afdo_cmd,
        enter_chroot=True,
        capture_output=True,
        print_cmd=True,
        chroot_args=self.chroot_args)

    logging.info('Generated %s AFDO profile %s', self.arch, afdo_name)
    return afdo_name

  def _UploadArtifacts(self, debug_bin, afdo_name):
    """Upload Chrome debug binary and AFDO profile with version info.

    Args:
      debug_bin: The name of debug Chrome binary.
      afdo_name: The name of AFDO profile.
    """

    afdo_spec = {
        'package': self.chrome_cpv.package,
        'arch': self.arch,
        'version': self.chrome_cpv.version
    }
    debug_bin_full_path = os.path.join(
        self.output_dir,
        os.path.basename(debug_bin) + BZ2_COMPRESSION_SUFFIX)
    chrome_version = CHROME_ARCH_VERSION % afdo_spec
    debug_bin_name_with_version = (
        chrome_version + '.debug' + BZ2_COMPRESSION_SUFFIX)

    # Upload Chrome debug binary and rename it
    _UploadAFDOArtifactToGSBucket(
        BENCHMARK_AFDO_GS_URL,
        debug_bin_full_path,
        rename=debug_bin_name_with_version)

    # Upload Benchmark AFDO profile as is
    _UploadAFDOArtifactToGSBucket(
        BENCHMARK_AFDO_GS_URL,
        os.path.join(self.output_dir, afdo_name + BZ2_COMPRESSION_SUFFIX))

  def _GenerateAFDOData(self):
    """Generate AFDO profile data from 'perf' data.

    Given the 'perf' profile, generate an AFDO profile using
    create_llvm_prof. It also compresses Chrome debug binary to upload.

    Returns:
      The name created AFDO artifact.
    """
    debug_bin = _CHROME_DEBUG_BIN % {
        'root': self.chroot_path,
        'sysroot': os.path.join('build', self.board)
    }
    afdo_name = self._CreateAFDOFromPerfData()

    # Because debug_bin and afdo file are in different paths, call the compress
    # function separately.
    _CompressAFDOFiles(
        targets=[debug_bin],
        input_dir=None,
        output_dir=self.output_dir,
        suffix=BZ2_COMPRESSION_SUFFIX)

    _CompressAFDOFiles(
        targets=[afdo_name],
        input_dir=self.working_dir,
        output_dir=self.output_dir,
        suffix=BZ2_COMPRESSION_SUFFIX)

    self._UploadArtifacts(debug_bin, afdo_name)
    return afdo_name

  def Perform(self):
    """Main function to generate benchmark AFDO profiles.

    Raises:
      GenerateBenchmarkAFDOProfilesError, if it never finds a perf.data
      file uploaded to GS bucket.
    """
    if self._WaitForAFDOPerfData():
      afdo_file = self._GenerateAFDOData()
      # FIXME(tcwang): reuse the CreateAndUploadMergedAFDOProfile from afdo.py
      # as a temporary solution to keep Android/Linux AFDO running.
      # Need to move the logic to this file, and run it either at generating
      # benchmark profiles, or at verifying Chrome profiles.
      gs_context = gs.GSContext()
      afdo.CreateAndUploadMergedAFDOProfile(gs_context, self.buildroot,
                                            afdo_file)
    else:
      raise GenerateBenchmarkAFDOProfilesError(
          'Could not find current "perf" profile.')


def CanGenerateAFDOData(board):
  """Does this board has the capability of generating its own AFDO data?"""
  return board in AFDO_DATA_GENERATORS_LLVM


def CanVerifyKernelAFDOData(board):
  """Does the board eligible to verify kernel AFDO profile.

  We use the name of the board to find the kernel version, so we only
  support using boards specified inside KERNEL_AFDO_VERIFIER_BOARDS.
  """
  return board in KERNEL_AFDO_VERIFIER_BOARDS


def CheckAFDOArtifactExists(buildroot, chrome_root, board, target):
  """Check if the artifact to upload in the builder already exists or not.

  Args:
    buildroot: The path to build root.
    chrome_root: The path to Chrome root.
    board: The name of the board.
    target: The target to check. It can be one of:
      "orderfile_generate": We need to check if the name of the orderfile to
      generate is already in the GS bucket or not.
      "orderfile_verify": We need to find if the latest unvetted orderfile is
      already verified or not.
      "benchmark_afdo": We need to check if the name of the benchmark AFDO
      profile is already in the GS bucket or not.
      "kernel_afdo": We need to check if the latest unvetted kernel profile is
      already verified or not.
      "chrome_afdo": We need to check if a release profile created with
      latest unvetted benchmark and CWP profiles is already verified or not.

  Returns:
    True if exists. False otherwise.

  Raises:
    ValueError if the target is invalid.
  """
  gs_context = gs.GSContext()
  if target == 'orderfile_generate':
    # For orderfile_generate builder, get the orderfile name from chrome ebuild
    orderfile_name = _GetOrderfileName(chrome_root)
    # Need to append the suffix
    orderfile_name += '.orderfile'
    return gs_context.Exists(
        os.path.join(ORDERFILE_GS_URL_UNVETTED,
                     orderfile_name + XZ_COMPRESSION_SUFFIX))

  if target == 'orderfile_verify':
    # Check if the latest unvetted orderfile is already verified
    orderfile_name = _FindLatestAFDOArtifact(ORDERFILE_GS_URL_UNVETTED,
                                             _RankValidOrderfiles)
    return gs_context.Exists(
        os.path.join(ORDERFILE_GS_URL_VETTED, orderfile_name))

  if target == 'benchmark_afdo':
    # For benchmark_afdo_generate builder, get the name from chrome ebuild
    afdo_name = _GetBenchmarkAFDOName(buildroot, board)
    return gs_context.Exists(
        os.path.join(BENCHMARK_AFDO_GS_URL, afdo_name + BZ2_COMPRESSION_SUFFIX))

  if target == 'kernel_afdo':
    # Check the latest unvetted kernel AFDO is already verified
    source_url = os.path.join(KERNEL_PROFILE_URL,
                              KERNEL_AFDO_VERIFIER_BOARDS[board])
    dest_url = os.path.join(KERNEL_AFDO_GS_URL_VETTED,
                            KERNEL_AFDO_VERIFIER_BOARDS[board])
    afdo_name = _FindLatestAFDOArtifact(source_url, _RankValidCWPProfiles)
    return gs_context.Exists(os.path.join(dest_url, afdo_name))

  if target == 'chrome_afdo':
    # Check the latest unvetted chrome AFDO profiles are verified
    benchmark_afdo = _FindLatestAFDOArtifact(BENCHMARK_AFDO_GS_URL,
                                             _RankValidBenchmarkProfiles)
    arch = CHROME_AFDO_VERIFIER_BOARDS[board]
    source_url = os.path.join(CWP_AFDO_GS_URL, arch)
    cwp_afdo = _FindLatestAFDOArtifact(source_url, _RankValidCWPProfiles)
    merged_name = MERGED_AFDO_NAME % (
        _GetCombinedAFDOName(
            _ParseCWPProfileName(os.path.splitext(cwp_afdo)[0]), arch,
            _ParseBenchmarkProfileName(os.path.splitext(benchmark_afdo)[0])))
    # The profile name also contained 'redacted' info
    merged_name += '-redacted.afdo'
    return gs_context.Exists(
        os.path.join(RELEASE_AFDO_GS_URL_VETTED,
                     merged_name + XZ_COMPRESSION_SUFFIX))

  raise ValueError('Unsupported target %s to check' % target)


def _UploadVettedAFDOArtifacts(artifact_type, subcategory=None):
  """Upload vetted artifact type to GS bucket.

  When we upload vetted artifacts, there is a race condition that
  a new unvetted artifact might just be uploaded after the builder
  starts. Thus we don't want to poll the bucket for latest vetted
  artifact, and instead we look within the ebuilds.

  Args:
    artifact_type: The type of AFDO artifact to upload. Supports:
    ('orderfile', 'kernel_afdo', 'benchmark_afdo', 'cwp_afdo')
    subcategory: Optional. Name of subcategory, used to upload
    kernel AFDO or CWP AFDO.

  Returns:
    Name of the AFDO artifact, if successfully uploaded. Otherwise
    returns None.

  Raises:
    ValueError: if artifact_type is not supported, or subcategory
    is not provided for kernel_afdo or cwp_afdo.
  """
  gs_context = gs.GSContext()
  if artifact_type == 'orderfile':
    artifact = _GetArtifactVersionInEbuild('chromeos-chrome',
                                           'UNVETTED_ORDERFILE')
    full_name = artifact + XZ_COMPRESSION_SUFFIX
    source_url = os.path.join(ORDERFILE_GS_URL_UNVETTED, full_name)
    dest_url = os.path.join(ORDERFILE_GS_URL_VETTED, full_name)
  elif artifact_type == 'kernel_afdo':
    if not subcategory:
      raise ValueError('Subcategory is required for kernel_afdo.')
    artifact = _GetArtifactVersionInEbuild(
        'chromeos-kernel-' + subcategory.replace('.', '_'),
        'AFDO_PROFILE_VERSION')
    full_name = artifact + KERNEL_AFDO_COMPRESSION_SUFFIX
    source_url = os.path.join(KERNEL_PROFILE_URL, subcategory, full_name)
    dest_url = os.path.join(KERNEL_AFDO_GS_URL_VETTED, subcategory, full_name)
  else:
    raise ValueError('Only orderfile and kernel_afdo are supported.')

  if gs_context.Exists(dest_url):
    return None

  logging.info('Copying artifact from %s to %s', source_url, dest_url)
  gs_context.Copy(source_url, dest_url, acl='public-read')

  return artifact


def _PublishVettedAFDOArtifacts(json_file, uploaded, title=None):
  """Publish the uploaded AFDO artifact to metadata.

  Since there're no better ways for PUpr to keep track of uploading
  new files in GS bucket, we need to commit a change to a metadata file
  to reflect the upload.

  Args:
    json_file: The path to the JSON file that contains the metadata.
    uploaded: Dict contains pairs of (package, artifact) showing the
    newest name of uploaded 'artifact' to update for the 'package'.
    title: Optional. Used for putting into commit message.

  Raises:
    PublishVettedAFDOArtifactsError:
    if the artifact to update is not already in the metadata file, or
    if the uploaded artifact is the same as in metadata file (no new
    AFDO artifact uploaded). This should be caught earlier before uploading.
  """
  branch = git.GetTrackingBranch(
      TOOLCHAIN_UTILS_PATH, for_checkout=False, for_push=True)

  # Perform a git pull first to sync the checkout containing metadata,
  # in case there are some updates during the builder was running.
  # Possible race conditions are:
  # (1) Concurrent running builders modifying the same file, but different
  # entries. e.g. kernel_afdo.json containing three kernel profiles.
  # Sync'ing in this case should be safe no matter what.
  # (2) Concurrent updates to modify the same entry. This is unsafe because
  # we might update an entry with an older profile. The checking logic in the
  # function should guarantee we always update to a newer artifact, otherwise
  # the builder fails.
  git.RunGit(TOOLCHAIN_UTILS_PATH, ['pull', branch.remote], print_cmd=True)

  afdo_versions = json.loads(osutils.ReadFile(json_file))
  if title:
    commit_message = title + '\n\n'
  else:
    commit_message = 'afdo_metadata: Publish new profiles.\n\n'

  commit_body = 'Update %s from %s to %s\n'
  for package, artifact in uploaded.items():
    if not artifact:
      # It's OK that one package has nothing to publish because it's not
      # uploaded. The case of all packages have nothing to publish is already
      # checked before this function.
      continue
    if package not in afdo_versions:
      raise PublishVettedAFDOArtifactsError('The key %s is not in JSON file.' %
                                            package)

    old_value = afdo_versions[package]['name']

    if package == 'benchmark':
      update_to_newer_profile = _RankValidBenchmarkProfiles(
          old_value) < _RankValidBenchmarkProfiles(artifact)
    else:
      update_to_newer_profile = _RankValidCWPProfiles(
          old_value) < _RankValidCWPProfiles(artifact)
    if not update_to_newer_profile:
      raise PublishVettedAFDOArtifactsError(
          'The artifact %s to update is not newer than the JSON file %s' %
          (artifact, old_value))

    afdo_versions[package]['name'] = artifact

    commit_message += commit_body % (package, str(old_value), artifact)

  pformat.json(afdo_versions, fp=json_file)

  modifications = git.RunGit(
      TOOLCHAIN_UTILS_PATH, ['status', '--porcelain', '-uno'],
      capture_output=True,
      print_cmd=True).output
  if not modifications:
    raise PublishVettedAFDOArtifactsError(
        'AFDO info for the ebuilds did not change.')
  logging.info('Git status: %s', modifications)
  git_diff = git.RunGit(
      TOOLCHAIN_UTILS_PATH, ['diff'], capture_output=True,
      print_cmd=True).output
  logging.info('Git diff: %s', git_diff)
  # Commit the change
  git.RunGit(
      TOOLCHAIN_UTILS_PATH, ['commit', '-a', '-m', commit_message],
      print_cmd=True)
  # Push the change, this should create a CL, and auto-submit it.
  git.GitPush(
      TOOLCHAIN_UTILS_PATH,
      'HEAD',
      git.RemoteRef(branch.remote, f'{branch.ref}%submit'),
      print_cmd=True)


def _CreateReleaseChromeAFDO(cwp_afdo, arch, benchmark_afdo, output_dir):
  """Create an AFDO profile to be used in release Chrome.

  This means we want to merge the CWP and benchmark AFDO profiles into
  one, and redact all ICF symbols.

  Args:
    cwp_afdo: Name of the verified CWP profile.
    arch: Architecture name of the CWP profile.
    benchmark_afdo: Name of the verified benchmark profile.
    output_dir: A directory to store all artifacts.

  Returns:
    Full path to a generated release AFDO profile.
  """
  gs_context = gs.GSContext()
  # Download profiles from gsutil.
  cwp_full_name = cwp_afdo + XZ_COMPRESSION_SUFFIX
  benchmark_full_name = benchmark_afdo + BZ2_COMPRESSION_SUFFIX

  cwp_afdo_url = os.path.join(CWP_AFDO_GS_URL, arch, cwp_full_name)
  cwp_afdo_local = os.path.join(output_dir, cwp_full_name)
  gs_context.Copy(cwp_afdo_url, cwp_afdo_local)

  benchmark_afdo_url = os.path.join(BENCHMARK_AFDO_GS_URL, benchmark_full_name)
  benchmark_afdo_local = os.path.join(output_dir, benchmark_full_name)
  gs_context.Copy(benchmark_afdo_url, benchmark_afdo_local)

  # Decompress the files.
  cwp_local_uncompressed = os.path.join(output_dir, cwp_afdo)
  cros_build_lib.UncompressFile(cwp_afdo_local, cwp_local_uncompressed)
  benchmark_local_uncompressed = os.path.join(output_dir, benchmark_afdo)
  cros_build_lib.UncompressFile(benchmark_afdo_local,
                                benchmark_local_uncompressed)

  # Merge profiles.
  merge_weights = [(cwp_local_uncompressed, RELEASE_CWP_MERGE_WEIGHT),
                   (benchmark_local_uncompressed,
                    RELEASE_BENCHMARK_MERGE_WEIGHT)]
  merged_profile_name = MERGED_AFDO_NAME % (
      _GetCombinedAFDOName(
          _ParseCWPProfileName(cwp_afdo), arch,
          _ParseBenchmarkProfileName(benchmark_afdo)))
  merged_profile = os.path.join(output_dir, merged_profile_name)
  _MergeAFDOProfiles(merge_weights, merged_profile)

  # Redact profiles.
  redacted_profile_name = merged_profile_name + '-redacted.afdo'
  redacted_profile = os.path.join(output_dir, redacted_profile_name)
  _RedactAFDOProfile(merged_profile, redacted_profile)

  return redacted_profile


def _UploadReleaseChromeAFDO():
  """Upload an AFDO profile to be used in release Chrome.

  Returns:
    Full path to the release AFDO profile uploaded.
  """
  with osutils.TempDir() as tempdir:
    # This path should be a full path to the profile
    profile_path = _GetArtifactVersionInEbuild('chromeos-chrome',
                                               'UNVETTED_AFDO_FILE')
    # Compress the final AFDO profile.
    ret = _CompressAFDOFiles([profile_path], None, tempdir,
                             XZ_COMPRESSION_SUFFIX)
    # Upload to GS bucket
    _UploadAFDOArtifactToGSBucket(RELEASE_AFDO_GS_URL_VETTED, ret[0])

    return profile_path


def UploadAndPublishVettedAFDOArtifacts(artifact_type, board):
  """Main function to upload a vetted AFDO artifact.

  As suggested by the name, this function first uploads the vetted artifact
  to GS bucket, and publishes the change to metadata file if needed.

  Args:
    artifact_type: Type of the artifact. 'Orderfile' or 'kernel_afdo'
    board: Name of the board.

  Returns:
    Status of the upload and publish.
  """

  uploaded = {}
  if artifact_type == 'chrome_afdo':
    # For current board, there is a release AFDO in chroot used for
    # verification.
    uploaded['chrome-afdo'] = _UploadReleaseChromeAFDO()
  elif artifact_type == 'kernel_afdo':
    kver = KERNEL_AFDO_VERIFIER_BOARDS[board]
    name = 'chromeos-kernel-' + kver.replace('.', '_')
    uploaded[name] = _UploadVettedAFDOArtifacts(artifact_type, kver)
    json_file = os.path.join(TOOLCHAIN_UTILS_PATH,
                             'afdo_metadata/kernel_afdo.json')
    title = 'afdo_metadata: Publish new profiles for kernel %s.' % kver
  else:
    uploaded['orderfile'] = _UploadVettedAFDOArtifacts('orderfile')

  if not [x for x in uploaded.values() if x]:
    # Nothing to publish to should be caught earlier
    return False

  if artifact_type == 'kernel_afdo':
    # No need to publish orderfile or chrome AFDO changes.
    # Skia autoroller can pick it up from uploads.
    _PublishVettedAFDOArtifacts(json_file, uploaded, title)
  return True
