# Copyright 2019 The ChromiumOS Authors
# 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
from pathlib import Path
import re
import shutil
from typing import Any, Callable, Iterable, List, Optional, Tuple

from chromite.lib import alerts
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import gob_util
from chromite.lib import gs
from chromite.lib import osutils
from chromite.lib.parser import package_info
from chromite.utils import pformat


class PrepareForBuildReturn:
    """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.
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/{arch}"
KERNEL_PROFILE_VETTED_URL = (
    "gs://chromeos-prebuilt/afdo-job/vetted/kernel/{arch}"
)
RELEASE_PROFILE_VETTED_URL = "gs://chromeos-prebuilt/afdo-job/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"
)
MERGED_AFDO_NAME = "chromeos-chrome-{arch}-{name}"

# How old can the Kernel AFDO data be? (in days).
KERNEL_ALLOWED_STALE_DAYS = 42
# How old can the Kernel AFDO data be before detective got noticed? (in days).
KERNEL_WARN_STALE_DAYS = 14
# How old an Arm profile can be before it gets replaced with atom.
CHROME_ARM_CWP_ALLOWED_STALE_DAYS = 21

# 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.
CHROME_AFDO_VERIFIER_BOARDS = {
    "chell": "atom",
    "eve": "bigcore",
    "trogdor": "arm",
}

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

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

# RegExps
AFDO_ARTIFACT_EBUILD_REGEX = (
    r'(?P<bef>\b%s\b=)(?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-(?:\w+)-
       (\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 profiles have ".afdo",
                                    # historically we had ".gcov", and
                                    # names in ebuilds sometimes don't
                                    # have this part at all.
       (?:\.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
      -(?:amd64|arm)                             # prefix for release profile.
      # CWP parts
      -(?:\w+)                                   # Profile type
      -(\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
      -redacted\.afdo                            # suffix for 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

CHROME_BINARY_PATH = (
    "/var/cache/chromeos-chrome/chrome-src-internal/"
    "src/out_{board}/Release/chrome"
)

# cros-artifacts go here in the chroot.
_PACKAGE_ARTIFACTS_PATH = "var/lib/chromeos/package-artifacts"


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 ProfilesNameHelperError(Error):
    """Error for helper functions related to profile naming."""


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


class NoProfilesInGsBucketError(Error):
    """Raised when _FindLatestAFDOArtifact doesn't find profiles."""


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 if the profile is parsable

    Raises if the name is not parsable.
    """
    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: str,
) -> Tuple[BenchmarkProfileVersion, CWPProfileVersion]:
    """Parse the name of a release profile for Chrome.

    Examples:
        With input: profile_name='chromeos-chrome-amd64
        -field-77-3809.38-1562580965
        -benchmark-77.0.3849.0_rc-r1.afdo.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 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 _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 _CompressAFDOFiles(
    targets: Iterable[Path], input_dir: Path, output_dir: Path, suffix: str
) -> List[Path]:
    """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)
        logging.info(
            "_CompressAFDOFiles produced %s, size %.1fMB",
            output_path,
            os.path.getsize(output_path) / (1024 * 1024),
        )
        ret.append(output_path)
    return ret


def _RankValidCWPProfiles(name: str) -> int:
    """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 _GetProfileAge(profile: str, artifact_type: str) -> int:
    """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' and 'cwp' are supported now.

    Returns:
        Age of profile_version in days.

    Raises:
        ValueError: if the artifact_type is not supported.
    """
    if artifact_type in ("kernel_afdo", "cwp"):
        return (
            datetime.datetime.now(tz=datetime.timezone.utc)
            - datetime.datetime.fromtimestamp(
                int(profile.split("-")[-1]), datetime.timezone.utc
            )
        ).days

    raise ValueError(
        f"'{artifact_type}' is currently not supported to check profile age."
    )


def _WarnDetectiveAboutKernelProfileExpiration(
    kver: str, profile_path: str
) -> None:
    """Send emails to toolchain detective to warn the soon expired profiles.

    Args:
        kver: Kernel version.
        profile_path: Absolute path to the profile.
    """
    subject_msg = (
        f"[Test Async builder] Kernel AutoFDO profile too old for kernel {kver}"
    )
    alert_msg = (
        f"The latest AutoFDO profile is too old for the kernel {kver}.\n"
        f"Path={profile_path}.\n"
        "Check if this is a known bug at "
        "https://buganizer.corp.google.com/issues?q=componentid:87200"
        "%20%22AutoFDO%20profile%20generation%20for%20kernel%22 or contact "
        "the cwp-team@google.com."
    )
    alerts.SendEmailLog(
        subject_msg,
        AFDO_ALERT_RECIPIENTS,
        message=alert_msg,
    )


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


class _CommonPrepareBundle:
    """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,
    ) -> None:
        self._gs_context = None
        self.artifact_name = artifact_name
        self.chroot = chroot
        self.sysroot_path = sysroot_path
        self.build_target = build_target
        self.input_artifacts = input_artifacts or {}
        self.profile_info = profile_info or {}
        self.profile = self.profile_info.get("chrome_cwp_profile", "")
        self.arch = self.profile_info.get("arch", "")
        if profile_info and not self.arch:
            raise ValueError("No 'arch' specified in ArtifactProfileInfo")
        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.split(".")[0]

    def _GetEbuildInfo(
        self, package: str, category: Optional[str] = None
    ) -> _EbuildInfo:
        """Get the ebuild info for a category/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.
        glob_path_str = os.path.join(
            _CHROMIUMOS_OVERLAY,
            category,
            package,
            "*-*.*.ebuild",
        )
        paths = glob.glob(glob_path_str)
        logging.info("Glob path %s yielded: %s", glob_path_str, paths)
        if len(paths) == 1:
            PV = os.path.splitext(os.path.split(paths[0])[1])[0]
            info = _EbuildInfo(
                paths[0], package_info.parse("%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.parse("%s/%s" % (category, PV))
                )
                if not info.CPV.revision:
                    # 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, wildcard_version=False
    ):
        """Get the name of the benchmark AFDO file from the Chrome ebuild.

        wildcard_version=True replaces chrome version with *.
        """
        pkg = self._GetEbuildInfo(constants.CHROME_PN).CPV
        if wildcard_version:
            ver = "*"
            vernorev = "*"
        else:
            ver = pkg.vr
            vernorev = pkg.version.split("_")[0]
        afdo_spec = {
            "arch": self.arch,
            "package": pkg.package,
            "version": ver,
            "versionnorev": vernorev,
        }
        return template % afdo_spec

    def _GetArtifactVersionInGob(self, profile_arch: str) -> str:
        """Find the version (name) of AFDO artifact from GoB.

        Args:
            profile_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 "profile_arch" is not a supported.
            RuntimeError: when the file containing AFDO profile_arch name can't
                be found.
        """
        if profile_arch not in list(CHROME_AFDO_VERIFIER_BOARDS.values()):
            raise ValueError(
                f"Invalid architecture {profile_arch} to use in AFDO "
                "profile_arch"
            )

        chrome_info = self._GetEbuildInfo(constants.CHROME_PN)
        version = chrome_info.CPV.version
        if version.endswith("_rc"):
            version = version[:-3]
        profile_path = (
            f"chromium/src/+/refs/tags/{version}/chromeos/profiles/"
            f"{profile_arch}.afdo.newest.txt?format=text"
        )

        contents = gob_util.FetchUrl(constants.EXTERNAL_GOB_HOST, profile_path)
        if not contents:
            raise RuntimeError(
                "Could not fetch https://"
                f"{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, encoding="utf-8") as f:
            for line in f:
                match = pattern.search(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 _FindLatestAFDOArtifact(
        self,
        gs_urls: Iterable[str],
        rank_func: Callable[[str], Any],
        arch: str = "",
    ) -> str:
        """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.
            arch: Profile architecture, default is self.arch which is passed
                from recipe.

        Returns:
            The path of the latest eligible AFDO artifact.

        Raises:
            NoProfilesInGsBucketError: If no profiles in GS bucket.
            RuntimeError: If no valid latest profiles.
            ValueError: if regex is not valid.
        """
        if not arch:
            arch = self.arch

        def _FilesOnBranch(
            all_files: Iterable[gs.GSListResult],
            branch: str,
        ):
            """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 of files from GS.
                branch: branch number.

            Returns:
                Files matching the branch.
            """
            cwp_afdo_pattern = re.compile(rf"R{branch}")
            # Search by the arch and branch number.
            bench_afdo_pattern = re.compile(rf"chromeos-chrome-{arch}-{branch}")
            # Search for the benchmark branch version and ignore the cwp
            # version. When main branch switches from 100 to 101 and we are
            # checking 100 branch we have to ignore
            # "-field-100-*-benchmark-101-" profiles which are going to come
            # from main.
            results = []
            for x in all_files:
                x_name = os.path.basename(x.url)
                # Filter in CWP and benchmark AFDO.
                if cwp_afdo_pattern.match(x_name) or bench_afdo_pattern.match(
                    x_name
                ):
                    results.append(x)

            return results

        # 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 NoProfilesInGsBucketError(
                "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(
                f"No valid latest artifact was found in {','.join(gs_urls)}"
                f" (example of invalid artifact: {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 (supports wildcards).
            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)
            found_paths = self.gs_context.LS(path)
            if found_paths:
                if len(found_paths) > 1:
                    raise PrepareForBuildHandlerError(
                        f"Found {found_paths} artifacts at {url}. Expected ONE "
                        "file."
                    )
                return found_paths[0]
        return None

    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, encoding="utf-8") as old, open(
            new_name, "w", encoding="utf-8"
        ) 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."
                )

        CPV = info.CPV
        if uprev:
            assert CPV.version != "9999"
            new_CPV = (
                f"{CPV.category}/{CPV.package}-{CPV.version}"
                f"-r{CPV.revision + 1}"
            )
            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,
                self.chroot.chroot_path(ebuild_file),
                "manifest",
                "--force",
            ]
            self.chroot.run(cmd)

        return CPV

    @staticmethod
    def _ValidBenchmarkProfileVersion(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
            of the benchmark profile is valid and it's not merged.
            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 _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 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,
            extbinary=True,
        )

        return redacted_path

    def _MergeAFDOProfiles(
        self, profile_list, output_profile, use_extbinary=False
    ) -> None:
        """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_extbinary: whether to use the new extensible 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_extbinary:
            merge_command.append("--extbinary")
        self.chroot.run(merge_command, print_cmd=True)

    def _ProcessAFDOProfile(
        self,
        input_path,
        output_path,
        redact=False,
        remove=False,
        reduce_functions=None,
        extbinary=False,
    ) -> None:
        """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.
            extbinary: Whether to convert the final profile into extbinary
                type.

        Raises:
            BundleArtifactsHandlerError: If the output profile is empty.
        """
        profdata_command_base = ["llvm-profdata", "merge", "-sample"]
        # Convert the extbinary 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),
        ]
        self.chroot.run(cmd_to_text, 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:
                self.chroot.run(
                    ["redact_textual_afdo_profile"],
                    input=f,
                    stdout=redacted_temp,
                    print_cmd=True,
                )
            current_input_file = redacted_temp

        if remove:
            # Call the remove indirect call script
            removed_temp = input_path + ".removed.temp"
            self.chroot.run(
                [
                    "remove_indirect_calls",
                    "--input=" + self.chroot.chroot_path(current_input_file),
                    "--output=" + self.chroot.chroot_path(removed_temp),
                ],
                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"
            self.chroot.run(
                [
                    "remove_cold_functions",
                    "--input=" + self.chroot.chroot_path(current_input_file),
                    "--output=" + self.chroot.chroot_path(reduced_tmp),
                    "--number=" + str(reduce_functions),
                ],
                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 extbinary:
            # Using `extbinary` profiles saves us hundreds of MB of RAM per
            # compilation, since it allows profiles to be lazily loaded.
            cmd_to_binary.append("--extbinary")
        self.chroot.run(
            cmd_to_binary,
            print_cmd=True,
        )

        profile_size = os.path.getsize(output_path)
        logging.info(
            "_ProcessAFDOProfile produced AFDO profile %s, size %.1fMB",
            output_path,
            profile_size / (1024 * 1024),
        )
        # Verify the profile size.
        # Empty profiles in a binary format can have a non-zero size
        # because of the header but they won't exceed the page size.
        # Normal profiles are usually >1MB.
        if profile_size < 4096:
            raise BundleArtifactsHandlerError(
                "_ProcessAFDOProfile produced empty AFDO profile, "
                f"{profile_size}"
            )

    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]
        try:
            benchmark_listing = self.gs_context.List(
                os.path.join(
                    benchmark_url,
                    f"chromeos-chrome-{self.arch}-*" + profile_suffix,
                ),
                details=True,
            )
        except (gs.GSCommandError, gs.GSNoSuchKey):
            # This can happen in a new GS bucket where there are no profiles
            # yet.
            logging.warning(
                "Did not find valid benchmark profiles. Skip profile merge.",
            )
            return None

        unmerged_version = _ParseBenchmarkProfileName(unmerged_name)

        def _GetOrderedMergeableProfiles(
            benchmark_listing: Iterable[gs.GSListResult],
        ) -> Iterable[gs.GSListResult]:
            """Get list of mergeable profiles ordered by increasing version."""
            # Exclude merged profiles, because merging merged profiles into
            # merged profiles is likely bad. _ValidBenchmarkProfileVersion takes
            # care of it.
            profile_versions = [
                (self._ValidBenchmarkProfileVersion(x.url), x)
                for x in benchmark_listing
            ]
            # Filter in only necessary profiles.
            candidates = sorted(
                (version, x)
                for version, x in profile_versions
                if version and unmerged_version >= version
            )
            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.
        reduce_functions = 70000
        redact = False
        remove = True
        if self.arch == "arm":
            # Redaction has significant effect on performance gain (+15% on
            # speedometer2) but also has a drastic impact on the binary size
            # (+16MB).
            # With the native arm profile we can trim the binary size with
            # sample-profile-accurate. On trogdor it shaves another 20MB with a
            # slight performance impact, drop from 12 to 11 %.
            redact = True
        self._ProcessAFDOProfile(
            raw_merged_output_path,
            profile_to_upload_path,
            redact=redact,
            remove=remove,
            reduce_functions=reduce_functions,
            extbinary=False,
        )

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

    def _CleanupArtifactDirectory(self, src_dir) -> None:
        """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,
    ) -> None:
        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 _PrepareChromeClangWarningsFile(self):
        # We 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)

            # We don't need a strict version from ebuild because it can change
            # in the timeframe between afdo-generate and afdo-process (right, it
            # happens!). Another edge case is revbump of chrome with patches in
            # 9999.
            bin_name = (
                self._GetBenchmarkAFDOName(
                    CHROME_DEBUG_BINARY_NAME, wildcard_version=True
                )
                + BZ2_COMPRESSION_SUFFIX
            )
            gs_loc = self.input_artifacts.get("ChromeDebugBinary", [])
            # url contains a concrete chrome version.
            bin_url = self._FindArtifact(bin_name, gs_loc)
            if not bin_url:
                raise PrepareForBuildHandlerError(
                    "Could not find an artifact matching the pattern "
                    f'"{bin_name}" in {gs_loc}.'
                )
            # Extract the name with a concrete version of chrome.
            bin_name = os.path.basename(bin_url)
            bin_compressed = self._AfdoTmpPath(bin_name)
            self.chroot.run(
                [
                    "gsutil",
                    "-o",
                    "Boto:num_retries=10",
                    "cp",
                    "-v",
                    "--",
                    bin_url,
                    bin_compressed,
                ],
                print_cmd=True,
            )
            self.chroot.run(
                ["bzip2", "-d", bin_compressed],
                print_cmd=True,
            )

            perf_name = (
                self._GetBenchmarkAFDOName(template=CHROME_PERF_AFDO_FILE)
                + BZ2_COMPRESSION_SUFFIX
            )
            perf_compressed = self._AfdoTmpPath(perf_name)
            gs_loc = self.input_artifacts.get(
                "UnverifiedChromeBenchmarkPerfFile", []
            )
            perf_url = self._FindArtifact(perf_name, gs_loc)
            if not perf_url:
                raise PrepareForBuildHandlerError(
                    f'Could not find "{perf_name}" in {gs_loc}.'
                )
            self.gs_context.Copy(
                perf_url, self.chroot.full_path(perf_compressed)
            )
            self.chroot.run(
                ["bzip2", "-d", perf_compressed],
                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) -> None:
        """Unused: see _PrepareVerifiedReleaseAfdoFile."""
        raise PrepareForBuildHandlerError(
            "Unexpected artifact type %s." % self.artifact_name
        )

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

    def _PrepareUnverifiedKernelCwpAfdoFile(self) -> None:
        """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."
            )

        verified_profile_url = KERNEL_PROFILE_VETTED_URL.format(arch=self.arch)
        profile_url = KERNEL_PROFILE_URL.format(arch=self.arch)
        profile_var_name = "AFDO_PROFILE_VERSION"
        if self.arch == "arm":
            profile_var_name = "ARM_AFDO_PROFILE_VERSION"

        cwp_locs = list(
            self.input_artifacts.get(
                "UnverifiedKernelCwpAfdoFile",
                [os.path.join(profile_url, kernel_version)],
            )
        )
        afdo_path = self._FindLatestAFDOArtifact(
            cwp_locs, _RankValidCWPProfiles
        )

        published_path = os.path.join(
            self.input_artifacts.get(
                "VerifiedKernelCwpAfdoFile",
                [os.path.join(verified_profile_url, 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:
            _WarnDetectiveAboutKernelProfileExpiration(
                kernel_version, afdo_path
            )

        # 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"
                ),
                {profile_var_name: afdo_name, "AFDO_LOCATION": afdo_dir},
                uprev=True,
            )
        return ret

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

    def _PrepareVerifiedChromeCwpAfdoFile(self) -> None:
        """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
        if not self.profile:
            raise PrepareForBuildHandlerError(
                "Profile name is not set. "
                "Is 'chrome_cwp_profile' missing in profile_info?"
            )
        bench_locs = self.input_artifacts.get(
            "UnverifiedChromeBenchmarkAfdoFile", [BENCHMARK_AFDO_GS_URL]
        )
        cwp_locs = self.input_artifacts.get(
            "UnverifiedChromeCwpAfdoFile", [CWP_AFDO_GS_URL]
        )

        # AFDO Experiment can tweak both the source of benchmark and CWP
        # profiles.
        # -<arch> suffix forces use of the specified architecture for
        # the benchmark profile. For example exp-amd64 is going to use
        # benchmark profiles from amd64.
        bench_arch = self.arch
        if self.profile.startswith("exp-"):
            bench_arch = self.profile.replace("exp-", "", 1)

        # This will raise a NoProfilesInGsBucketError if no artifact is found.
        bench = self._FindLatestAFDOArtifact(
            bench_locs, self._ValidBenchmarkProfileVersion, bench_arch
        )
        # CWP source in the AFDO Experiment is configured directly from recipe
        # there is no dependency on the architecture here.
        cwp = self._FindLatestAFDOArtifact(cwp_locs, _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_PROFILE_VETTED_URL]
        )[0]

        profile = self.profile
        if self.arch == "arm" and self.profile == "arm":
            # arm/arm profile is generated on arm64 and used on all arm
            # production devices. Profile rollers track the -arm-none- verified
            # profiles.
            # All other arm profile variants are intended only for testing or
            # experiments. Merged profiles with variants will be stored in gs
            # bucket but ignored by the production pipeline.
            # For example arm32 profiles are generated on arm arch (arm64) and
            # verified on arm32 target. This profile is not used on production.
            profile = "none"
        # Strip suffix from experimental profile.
        if profile.startswith("exp"):
            profile = "exp"
        merged_name = MERGED_AFDO_NAME.format(
            arch=self.arch,
            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.
        return PrepareForBuildReturn.NEEDED

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

    def _PrepareCompilerRusageLogs(self):
        # We always build this artifact.
        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,
    ) -> None:
        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 _CheckArguments(self, chrome_binary: Path) -> None:
        """Make sure the arguments received are correct."""
        if not os.path.isdir(self.output_dir):
            raise BundleArtifactsHandlerError(
                f"Non-existent directory '{self.output_dir}' specified for "
                "--out-dir"
            )

        chrome_binary_path_outside = self.chroot.full_path(
            self.sysroot_path, chrome_binary
        )
        if not os.path.exists(chrome_binary_path_outside):
            raise BundleArtifactsHandlerError(
                f"'{chrome_binary_path_outside}' chrome binary does not exist"
            )

    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),
            ]
            self.chroot.run(cmd, cwd=self.chroot.path)
            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 _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", encoding="utf-8") as f:
            self.chroot.run(
                ["bzip2", "-c", debug_bin_inside],
                stdout=f,
                print_cmd=True,
            )
        return [bin_path]

    @staticmethod
    def _LocateChromeDebugInfo(afdo_tmp_path: Path) -> Path:
        """Locates debuginfo for a Chrome binary in the given path.

        Returns:
            The path to debuginfo.

        Raises:
            BundleArtifactsHandlerError: if the number of files that seem to be
            Chrome debuginfo is not exactly one.
        """
        debug_glob = "chromeos-chrome*.debug"
        matches = list(afdo_tmp_path.glob(debug_glob))
        if len(matches) == 1:
            return matches[0]

        if matches:
            msg = f"Too many chrome debug files found; results: {matches}"
        else:
            msg = f"No files found matching {afdo_tmp_path / debug_glob}"
        raise BundleArtifactsHandlerError(msg)

    def _BundleUnverifiedChromeBenchmarkAfdoFile(self):
        """Bundle a benchmark Chrome AFDO profile.

        Raises:
            BundleArtifactsHandlerError: If the output profile is empty.
        """
        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)
        benchmark_afdo_name = self._LocateChromeDebugInfo(
            afdo_tmp_path=Path(self.chroot.full_path(self._AfdoTmpPath())),
        ).name
        benchmark_chroot_path = self.chroot.full_path(bin_path_in)
        logging.info(
            "Linking %s => %s", benchmark_afdo_name, benchmark_chroot_path
        )
        osutils.SafeSymlink(benchmark_afdo_name, benchmark_chroot_path)
        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.
        self.chroot.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",
            ],
            print_cmd=True,
        )
        profile_size = os.path.getsize(self.chroot.full_path(afdo_path_inside))
        # Check if the profile is empty.
        # Empty profiles in a binary format can have a non-zero size
        # because of the header but they won't exceed the page size.
        # Normal profiles are usually >1MB.
        if profile_size < 4096:
            raise BundleArtifactsHandlerError(
                f"AFDO profile size has invalid size, {profile_size}"
            )
        logging.info(
            "Generated %s AFDO profile %s, size %.1fMB",
            self.arch,
            afdo_name,
            profile_size / (1024 * 1024),
        )

        # Compress and deliver the profile.
        afdo_path = os.path.join(
            self.output_dir, afdo_name + BZ2_COMPRESSION_SUFFIX
        )
        with open(afdo_path, "w", encoding="utf-8") as f:
            self.chroot.run(
                ["bzip2", "-c", afdo_path_inside],
                stdout=f,
                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:
            self.chroot.run(
                ["bzip2", "-c", merged_profile_inside],
                stdout=f,
                print_cmd=True,
            )
        files.append(merged_profile_compressed)
        return files

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

    def _BundleUnverifiedKernelCwpAfdoFile(self) -> None:
        """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.")

        profile_var_name = "AFDO_PROFILE_VERSION"
        if self.arch == "arm":
            profile_var_name = "ARM_AFDO_PROFILE_VERSION"

        kernel_version = kernel_version.replace(".", "_")
        profile_name = self._GetArtifactVersionInEbuild(
            f"chromeos-kernel-{kernel_version}", profile_var_name
        )
        if not profile_name:
            raise BundleArtifactsHandlerError(
                "Could not find AFDO_PROFILE_VERSION in "
                f"chromeos-kernel-{kernel_version}."
            )
        profile_name += 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.afdo.xz
        profile_path = self.chroot.full_path(
            self.sysroot_path,
            "usr",
            "lib",
            "debug",
            "boot",
            f"chromeos-kernel-{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) -> None:
        """Unused: this artifact comes from CWP."""
        raise BundleArtifactsHandlerError(
            "Unexpected artifact type %s." % self.artifact_name
        )

    def _BundleVerifiedChromeCwpAfdoFile(self) -> None:
        """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"
            )
        )

        logging.info("Verifying that Chrome was successfully installed...")
        # This hands back a non-zero exit code if it couldn't find any matches.
        self.chroot.run(
            [
                f"equery-{self.build_target}",
                "l",
                "chromeos-base/chromeos-chrome",
            ],
            check=True,
        )
        logging.info("Chrome build was successful.")

        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 _FindAllCrOSArtifactDirs(
        self, include_incomplete_packages: bool
    ) -> List[str]:
        """Finds all cros-artifacts directories in the chroot."""
        portage_roots = ["/"]
        portage_roots.extend(
            f"/build/{x.name}"
            for x in Path(self.chroot.full_path("/build")).glob("*/")
        )

        subpaths_to_search = [_PACKAGE_ARTIFACTS_PATH]
        if include_incomplete_packages:
            subpaths_to_search.append("var/tmp/portage")

        artifact_dirs = []
        for root in portage_roots:
            for subpath in subpaths_to_search:
                full_dir = Path(
                    self.chroot.full_path(os.path.join(root, subpath))
                )
                artifact_dirs.extend(
                    str(x) for x in full_dir.glob("*/*/cros-artifacts/")
                )

        return artifact_dirs

    def _CollectCrOSArtifactFiles(
        self,
        artifact_subdir: str,
        dest_dir: str,
        include_file: Callable[[str], bool],
        include_incomplete_packages: bool,
    ):
        """Collects files from all cros-artifacts dirs in a chroot.

        Args:
            artifact_subdir: the subdirectory of artifact directories to
                inspect.
            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.
            include_incomplete_packages: True if cros-artifacts directories
                should be included for packages that weren't successfully
                built.

        Returns:
            A list of all files that were copied, relative to the chroot's /.
        """
        artifact_dirs = self._FindAllCrOSArtifactDirs(
            include_incomplete_packages
        )

        output = []
        for artifact_dir in artifact_dirs:
            directory = os.path.join(artifact_dir, artifact_subdir)
            if not os.path.isdir(directory):
                logging.info(
                    "toolchain-logs: artifact subdir %s does not exist; skip",
                    directory,
                )
                continue

            chroot_dir_path = self.chroot.chroot_path(directory)
            assert chroot_dir_path.startswith("/"), chroot_dir_path

            logging.info("toolchain-logs: scanning %s", directory)
            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

                # Chop the leading '/' from the chroot path.
                dest_path = os.path.join(
                    dest_dir, chroot_dir_path[1:], 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 _CreateCrOSArtifactBundle(
        self,
        src_subdir: str,
        tarball: str,
        destination: str,
        extension: Optional[str] = None,
        include_incomplete_packages: bool = False,
    ) -> str:
        """Bundle the files from src_dir into a tar.xz file.

        Args:
            src_subdir: 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.
            include_incomplete_packages: if True, this will also bundle files
                from cros-artifacts dirs that weren't emerged (e.g., due to
                build failures)

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

        def FilterFile(file_path: str) -> bool:
            return extension is None or file_path.endswith(extension)

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

        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._CreateCrOSArtifactBundle(
                        "toolchain/fatal_clang_warnings",
                        "fatal_clang_warnings",
                        tempdir,
                        ".json",
                        # Collecting warning logs is generally only done with
                        # experimental toolchains (e.g., llvm-next), so a green
                        # ToT is not expected.
                        include_incomplete_packages=True,
                    )
                ]
            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._CreateCrOSArtifactBundle(
                        "toolchain/clang_crash_diagnoses",
                        "clang_crash_diagnoses",
                        tempdir,
                        # If the compiler crashed, the package almost
                        # definitely failed to build.
                        include_incomplete_packages=True,
                    )
                ]
            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._CreateCrOSArtifactBundle(
                        "toolchain/clang_rusage_logs",
                        "clang_rusage_logs",
                        tempdir,
                        ".json",
                        include_incomplete_packages=False,
                    )
                ]
            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.
        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:
    """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) -> None:
        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 = (
            "afdo_metadata: Publish new kernel profiles for "
            f"{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()
