# Copyright 2018 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Sysroot service."""

import contextlib
import getpass
import glob
import logging
import multiprocessing
import os
from pathlib import Path
import re
import shutil
import tempfile
from typing import (
    Dict,
    Generator,
    Iterator,
    List,
    NamedTuple,
    Optional,
    TYPE_CHECKING,
    Union,
)
import urllib

from chromite.lib import cache
from chromite.lib import chromite_config
from chromite.lib import constants
from chromite.lib import cpupower_helper
from chromite.lib import cros_build_lib
from chromite.lib import goma_lib
from chromite.lib import metrics_lib
from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib import remoteexec_util
from chromite.lib import sysroot_lib
from chromite.lib import workon_helper


if TYPE_CHECKING:
    from chromite.lib import binpkg
    from chromite.lib import build_target_lib
    from chromite.lib import chroot_lib

# TODO(xcl): Revisit/remove this after the Lacros launch if no longer needed
_CHROME_PACKAGES = ("chromeos-base/chromeos-chrome", "chromeos-base/chrome-icu")

# A list of critical system packages that should never be incidentally
# reinstalled as a side effect of build_packages. All packages in this list
# are special cased to prefer matching installed versions, overriding the
# typical logic of upgrading to the newest available version.
#
# This list can't include any package that gets installed to a board!
# Packages such as LLVM or binutils must not be in this list as the normal
# rebuild logic must still apply to them for board targets.
#
# TODO(crbug/1050752): Remove this list once we figure out how to exclude
# toolchain packages from being upgraded transitively via BDEPEND relations.
_CRITICAL_SDK_PACKAGES = (
    "dev-embedded/hps-sdk",
    "dev-lang/rust",
    "dev-lang/go",
    "sys-libs/glibc",
    "sys-devel/gcc",
)

_PACKAGE_LIST = List[Optional[str]]

# The default to use for --backtrack everywhere. Must be manually changed in
# update_chroot.
BACKTRACK_DEFAULT = 10

SYSROOT_ARCHIVE_FILE = "sysroot.tar.zst"


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


class NoFilesError(Error):
    """When there are no files to archive."""


class InvalidArgumentsError(Error):
    """Invalid arguments."""


class NotInChrootError(Error):
    """When SetupBoard is run outside of the chroot."""


class UpdateChrootError(Error):
    """Error occurred when running update chroot."""


class SetupBoardRunConfig(object):
    """Value object for full setup board run configurations."""

    def __init__(
        self,
        set_default: bool = False,
        force: bool = False,
        usepkg: bool = True,
        jobs: Optional[int] = None,
        regen_configs: bool = False,
        quiet: bool = False,
        update_toolchain: bool = True,
        upgrade_chroot: bool = True,
        init_board_pkgs: bool = True,
        local_build: bool = False,
        toolchain_changed: bool = False,
        package_indexes: Optional[List["binpkg.PackageIndexInfo"]] = None,
        expanded_binhost_inheritance: bool = False,
        backtrack: int = BACKTRACK_DEFAULT,
    ):
        """Initialize method.

        Args:
            set_default: Whether to set the passed board as the default.
            force: Force a new sysroot creation when it already exists.
            usepkg: Whether to use binary packages to bootstrap.
            jobs: Max number of simultaneous packages to build.
            regen_configs: Whether to only regen the configs.
            quiet: Whether to print notification when sysroot exists.
            update_toolchain: Update the toolchain?
            upgrade_chroot: Upgrade the chroot before building?
            init_board_pkgs: Emerging packages to sysroot?
            local_build: Bootstrap only from local packages?
            toolchain_changed: Has a toolchain change occurred? Implies 'force'.
            package_indexes: List of information about available prebuilts,
                youngest first, or None.
            expanded_binhost_inheritance: Allow expanded binhost inheritance.
            backtrack: emerge --backtrack value.
        """
        self.set_default = set_default
        self.force = force or toolchain_changed
        self.usepkg = usepkg
        self.jobs = jobs
        self.regen_configs = regen_configs
        self.quiet = quiet
        self.update_toolchain = update_toolchain
        self.update_chroot = upgrade_chroot
        self.init_board_pkgs = init_board_pkgs
        self.local_build = local_build
        self.package_indexes = package_indexes or []
        self.expanded_binhost_inheritance = expanded_binhost_inheritance
        self.backtrack = backtrack

    def GetUpdateChrootArgs(self) -> List[str]:
        """Create a list containing the relevant update_chroot arguments.

        Returns:
            The list of arguments
        """
        args = [f"--backtrack={self.backtrack}"]
        if self.usepkg:
            args += ["--usepkg"]
        else:
            args += ["--nousepkg"]

        if self.jobs:
            args += ["--jobs", str(self.jobs)]

        if not self.update_toolchain:
            args += ["--skip_toolchain_update"]

        return args


class BuildPackagesRunConfig(object):
    """Value object to hold build packages run configs."""

    def __init__(
        self,
        usepkg: bool = True,
        install_debug_symbols: bool = False,
        packages: Optional[List[str]] = None,
        use_flags: Optional[List[str]] = None,
        use_goma: bool = False,
        use_remoteexec: bool = False,
        incremental_build: bool = True,
        package_indexes: Optional[List["binpkg.PackageIndexInfo"]] = None,
        dryrun: bool = False,
        usepkgonly: bool = False,
        workon: bool = True,
        install_auto_test: bool = True,
        autosetgov: bool = False,
        autosetgov_sticky: bool = False,
        use_any_chrome: bool = True,
        internal_chrome: bool = False,
        clean_build: bool = False,
        eclean: bool = True,
        rebuild_dep: bool = True,
        jobs: Optional[int] = None,
        local_pkg: bool = False,
        dev_image: bool = True,
        factory_image: bool = True,
        test_image: bool = True,
        debug_version: bool = True,
        backtrack: int = BACKTRACK_DEFAULT,
    ):
        """Init method.

        Args:
            usepkg: Whether to use binpkgs or build from source. False currently
                triggers a local build, which will enable local reuse.
            install_debug_symbols: Whether to include the debug symbols for all
                packages.
            packages: The list of packages to install, by default install all
                packages for the target.
            use_flags: A list of use flags to set.
            use_goma: Whether to enable goma.
            use_remoteexec: Whether to use RBE for remoteexec.
            incremental_build: Whether to treat the build as an incremental
                build or a fresh build. Always treating it as an incremental
                build is safe, but certain operations can be faster when we know
                we are doing a fresh build.
            package_indexes: List of information about available prebuilts,
                youngest first, or None.
            dryrun: Whether to do a dryrun and not actually build any packages.
            usepkgonly: Only use binary packages to bootstrap; abort if any are
                missing.
            workon: Force-build workon packages.
            install_auto_test: Build autotest client code.
            autosetgov: Automatically set cpu governor to 'performance'.
            autosetgov_sticky: Remember --autosetgov setting for future runs.
            use_any_chrome: Use any Chrome prebuilt available, even if the
                prebuilt doesn't match exactly.
            internal_chrome: Build the internal version of chrome.
            clean_build: Perform a clean build; delete sysroot if it exists
                before building.
            eclean: Run eclean to delete old binpkgs.
            rebuild_dep: Rebuild dependencies.
            jobs: How many packages to build in parallel at maximum.
            local_pkg: Bootstrap from local packages instead of remote packages.
            dev_image: Build useful developer friendly utilities.
            factory_image: Build factory installer.
            test_image: Build packages required for testing.
            debug_version: Build debug versions of Chromium-OS-specific
                packages.
            backtrack: emerge --backtrack value.
        """
        self.usepkg = usepkg
        self.install_debug_symbols = install_debug_symbols
        self.packages = packages
        self.use_flags = use_flags
        self.use_goma = use_goma
        self.use_remoteexec = use_remoteexec
        self.is_incremental = incremental_build
        self.package_indexes = package_indexes or []
        self.dryrun = dryrun
        self.usepkgonly = usepkgonly
        self.workon = workon
        self.install_auto_test = install_auto_test
        self.autosetgov = autosetgov
        self.autosetgov_sticky = autosetgov_sticky
        self.use_any_chrome = use_any_chrome
        self.internal_chrome = internal_chrome
        self.clean_build = clean_build
        self.eclean = eclean
        self.rebuild_dep = rebuild_dep
        self.jobs = jobs
        self.local_pkg = local_pkg
        self.dev_image = dev_image
        self.factory_image = factory_image
        self.test_image = test_image
        self.debug_version = debug_version
        self.backtrack = backtrack

    def GetUseFlags(self) -> Optional[str]:
        """Get the use flags as a single string."""
        use_flags = os.environ.get("USE", "").split()

        if self.use_flags:
            use_flags.extend(self.use_flags)

        if self.internal_chrome:
            use_flags.append("chrome_internal")

        if not self.debug_version:
            use_flags.append("-cros-debug")

        return " ".join(use_flags) if use_flags else None

    def GetExtraEnv(self) -> Dict[str, str]:
        """Get the extra env for this config."""
        env = {}

        use_flags = self.GetUseFlags()
        if use_flags:
            env["USE"] = use_flags

        if self.use_goma:
            env["USE_GOMA"] = "true"

        if self.use_remoteexec:
            env["USE_REMOTEEXEC"] = "true"

        if self.package_indexes:
            env["PORTAGE_BINHOST"] = " ".join(
                x.location for x in reversed(self.package_indexes)
            )

        return env

    def GetPackages(self) -> List[str]:
        """Get the set of packages to build for this config."""
        if self.packages:
            return self.packages

        packages = ["virtual/target-os"]

        if self.dev_image:
            packages.append("virtual/target-os-dev")

        if self.factory_image:
            packages.extend(
                ["virtual/target-os-factory", "virtual/target-os-factory-shim"]
            )

        if self.test_image:
            packages.append("virtual/target-os-test")

        if self.install_auto_test:
            packages.append("chromeos-base/autotest-all")

        return packages

    @metrics_lib.timed("service.sysroot.GetForceLocalBuildPackages")
    def GetForceLocalBuildPackages(
        self, sysroot: sysroot_lib.Sysroot
    ) -> _PACKAGE_LIST:
        """Get the set of force local build packages for this config.

        This includes:
            1. Getting packages for a test image.
            2. Getting packages and reverse dependencies for cros workon
                packages.
            3. Getting packages and reverse dependencies for base install
                packages.

        Args:
            sysroot: The sysroot to get packages for.

        Returns:
            A list of packages to build from source.

        Raises:
            cros_build_lib.RunCommandError
        """
        sysroot_path = Path(sysroot.path)
        force_local_build_packages = set()
        packages = self.GetPackages()
        metrics_prefix = "service.sysroot.GetForceLocalBuildPackages"

        if "virtual/target-os-test" in packages:
            # chromeos-ssh-testkeys may generate ssh keys if the right USE flag
            # is set. We force rebuilding this package from source every time,
            # so that consecutive builds don't share ssh keys.
            force_local_build_packages.add(
                "chromeos-base/chromeos-ssh-testkeys"
            )

        cros_workon_packages = None
        if self.workon:
            cros_workon_packages = _GetCrosWorkonPackages(sysroot_path)

            # Any package that directly depends on an active cros_workon package
            # also needs to be rebuilt in order to be correctly built against
            # the current set of changes a user may have made to the cros_workon
            # package.
            if cros_workon_packages:
                force_local_build_packages.update(cros_workon_packages)

                with metrics_lib.timer(
                    f"{metrics_prefix}.CrosWorkonReverseDependencies"
                ):
                    reverse_dependencies = [
                        x.atom
                        for x in portage_util.GetReverseDependencies(
                            cros_workon_packages, sysroot_path
                        )
                    ]
                logging.info(
                    "The following packages depend directly on an active "
                    "cros_workon package and will be rebuilt: %s",
                    " ".join(reverse_dependencies),
                )
                force_local_build_packages.update(reverse_dependencies)

        # Determine base install packages and reverse dependencies if
        # incremental build (--withdevdeps) and clean build (--cleanbuild) is
        # not specified or the sysroot path exists.
        if self.is_incremental and (
            not self.clean_build or sysroot_path.exists()
        ):
            logging.info("Starting reverse dependency calculations...")

            # Temporarily modify the emerge flags so we can calculate the
            # revdeps on the modified packages.
            sim_emerge_flags = self.GetEmergeFlags()
            sim_emerge_flags.extend(
                [
                    "--pretend",
                    "--columns",
                    f'--reinstall-atoms={" ".join(packages)}',
                    f'--usepkg-exclude={" ".join(packages)}',
                ]
            )

            # cros-workon packages are always going to be force reinstalled, so
            # we add the forced reinstall behavior to the modified package
            # calculation. This is necessary to include when a user has already
            # installed a 9999 ebuild and is now reinstalling that package with
            # additional local changes, because otherwise the modified package
            # calculation would not see that a 'new' package is being installed.
            if cros_workon_packages:
                sim_emerge_flags.extend(
                    [
                        f'--reinstall-atoms={" ".join(cros_workon_packages)}',
                        f'--usepkg-exclude={" ".join(cros_workon_packages)}',
                    ]
                )

            revdeps_packages = _GetBaseInstallPackages(
                sysroot_path, sim_emerge_flags, packages
            )
            if revdeps_packages:
                force_local_build_packages.update(revdeps_packages)
                logging.info(
                    "Calculating reverse dependencies on packages: %s",
                    " ".join(revdeps_packages),
                )
                with metrics_lib.timer(f"{metrics_prefix}.ReverseDependencies"):
                    r_revdeps_packages = portage_util.GetReverseDependencies(
                        revdeps_packages, sysroot_path, indirect=True
                    )

                exclude_patterns = ["virtual/"]
                exclude_patterns.extend(_CHROME_PACKAGES)
                reverse_dependencies = [
                    x.atom
                    for x in r_revdeps_packages
                    if not any(p in x.atom for p in exclude_patterns)
                ]
                logging.info(
                    "Final reverse dependencies that will be rebuilt: %s",
                    " ".join(reverse_dependencies),
                )
                force_local_build_packages.update(reverse_dependencies)

        return list(force_local_build_packages)

    def GetEmergeFlags(self) -> List[str]:
        """Get the emerge flags for this config."""
        flags = [
            "-uDNv",
            f"--backtrack={self.backtrack}",
            "--newrepo",
            "--with-test-deps",
            "y",
        ]

        if self.use_any_chrome:
            for pkg in _CHROME_PACKAGES:
                flags.append(f"--force-remote-binary={pkg}")

        extra_board_flags = os.environ.get("EXTRA_BOARD_FLAGS", "").split()
        if extra_board_flags:
            flags.extend(extra_board_flags)

        if self.dryrun:
            flags.append("--pretend")

        if self.usepkg or self.local_pkg or self.usepkgonly:
            # Use binary packages. Include all build-time dependencies, so as to
            # avoid unnecessary differences between source and binary builds.
            flags.extend(["--getbinpkg", "--with-bdeps", "y"])
            if self.usepkgonly:
                flags.append("--usepkgonly")
            else:
                flags.append("--usepkg")

        if self.jobs:
            flags.append(f"--jobs={self.jobs}")

        if self.rebuild_dep:
            flags.append("--rebuild-if-new-rev")

        return flags


def SetupBoard(
    target: "build_target_lib.BuildTarget",
    accept_licenses: Optional[str] = None,
    run_configs: Optional[SetupBoardRunConfig] = None,
) -> None:
    """Run the full process to setup a board's sysroot.

    This is the entry point to run the setup_board script.

    Args:
        target: The build target configuration.
        accept_licenses: The additional licenses to accept.
        run_configs: The run configs.

    Raises:
        sysroot_lib.ToolchainInstallError when the toolchain fails to install.
    """
    if not cros_build_lib.IsInsideChroot():
        raise NotInChrootError("SetupBoard must be run from inside the chroot")

    # Make sure we have valid run configs setup.
    run_configs = run_configs or SetupBoardRunConfig()

    sysroot = Create(target, run_configs, accept_licenses)

    if run_configs.regen_configs:
        # We're now done if we're only regenerating the configs.
        return

    InstallToolchain(target, sysroot, run_configs)


def Create(
    target: "build_target_lib.BuildTarget",
    run_configs: SetupBoardRunConfig,
    accept_licenses: Optional[str],
) -> sysroot_lib.Sysroot:
    """Create a sysroot.

    This entry point is the subset of the full setup process that does the
    creation and configuration of a sysroot, including installing portage.

    Args:
        target: The build target being installed in the sysroot being created.
        run_configs: The run configs.
        accept_licenses: The additional licenses to accept.
    """
    cros_build_lib.AssertInsideChroot()

    sysroot = sysroot_lib.Sysroot(target.root)

    if sysroot.Exists() and not run_configs.force and not run_configs.quiet:
        logging.warning(
            "Board output directory already exists: %s\n"
            "Use --force to clobber the board root and start again.",
            sysroot.path,
        )

    # Override regen_configs setting to force full setup run if the sysroot does
    # not exist.
    run_configs.regen_configs = run_configs.regen_configs and sysroot.Exists()

    # Make sure the chroot is fully up to date before we start unless the
    # chroot update is explicitly disabled.
    if run_configs.update_chroot:
        logging.info("Updating chroot.")
        update_chroot = [
            constants.CROSUTILS_DIR / "update_chroot",
            "--toolchain_boards",
            target.name,
        ]
        update_chroot += run_configs.GetUpdateChrootArgs()
        try:
            cros_build_lib.run(update_chroot)
        except cros_build_lib.RunCommandError:
            raise UpdateChrootError(
                "Error occurred while updating the chroot. "
                "See the logs for more information."
            )

    # Delete old sysroot to force a fresh start if requested.
    if sysroot.Exists() and run_configs.force:
        sysroot.Delete(background=True)

    # Step 1: Create folders.
    # Dependencies: None.
    # Create the skeleton.
    logging.info("Creating sysroot directories.")
    _CreateSysrootSkeleton(sysroot)

    # Step 2: Standalone configurations.
    # Dependencies: Folders exist.
    # Install main, board setup, and user make.conf files.
    logging.info("Installing configurations into sysroot.")
    _InstallConfigs(sysroot, target)

    # Step 3: Portage configurations.
    # Dependencies: make.conf.board_setup.
    # Create the command wrappers, choose profile, and make.conf.board.
    # Refresh the workon symlinks to compensate for crbug.com/679831.
    logging.info("Setting up portage in the sysroot.")
    _InstallPortageConfigs(
        sysroot,
        target,
        accept_licenses,
        run_configs.local_build,
        package_indexes=run_configs.package_indexes,
        expanded_binhost_inheritance=run_configs.expanded_binhost_inheritance,
    )

    # Developer Experience Step: Set default board (if requested) to allow
    # running later commands without needing to pass the --board argument.
    if run_configs.set_default:
        cros_build_lib.SetDefaultBoard(target.name)

    return sysroot


def GenerateArchive(
    output_dir: str, build_target_name: str, pkg_list: List[str]
) -> str:
    """Generate a sysroot tarball for informational builders.

    Args:
        output_dir: Directory to contain the created the sysroot.
        build_target_name: The build target for the sysroot being created.
        pkg_list: List of 'category/package' package strings.

    Returns:
        Path to the sysroot tar file.
    """
    cmd = [
        "cros_generate_sysroot",
        "--out-file",
        constants.TARGET_SYSROOT_TAR,
        "--out-dir",
        output_dir,
        "--board",
        build_target_name,
        "--package",
        " ".join(pkg_list),
    ]
    cros_build_lib.run(cmd, cwd=constants.SOURCE_ROOT)
    return os.path.join(output_dir, constants.TARGET_SYSROOT_TAR)


def _create_sysroot(
    chroot: "chroot_lib.Chroot",
    _sysroot_class,
    build_target: "build_target_lib.BuildTarget",
    output_dir: str,
    package_list: List[str],
    output_file: str,
    deps_only: bool = True,
) -> str:
    """Create a sysroot to use.

    Args:
        chroot: The chroot class used for these artifacts.
        sysroot_class: The sysroot class used for these artifacts.
        build_target: The build target used for these artifacts.
        output_dir: The path to write artifacts to.
        package_list: List of packages to use.
        output_file: Name of the archive to output.
        deps_only: Whether to pass --deps-only.

    Returns:
        Path to the sysroot tar file.
    """
    with chroot.tempdir() as tempdir:
        outdir = chroot.chroot_path(tempdir)
        cmd = [
            "cros_generate_sysroot",
            "--out-dir",
            outdir,
            "--board",
            build_target.name,
            "--package",
            " ".join(package_list),
            "--out-file",
            output_file,
        ]
        if deps_only:
            cmd.append("--deps-only")
        cros_build_lib.run(
            cmd,
            cwd=constants.SOURCE_ROOT,
            enter_chroot=True,
            chroot_args=chroot.get_enter_args(),
            extra_env=chroot.env,
        )

        # Move the artifact out of the chroot.
        sysroot_tar_path = os.path.join(tempdir, output_file)
        shutil.copy(sysroot_tar_path, output_dir)
        return os.path.join(output_dir, output_file)


def CreateSimpleChromeSysroot(
    chroot: "chroot_lib.Chroot",
    _sysroot_class,
    build_target: "build_target_lib.BuildTarget",
    output_dir: str,
) -> str:
    """Create a sysroot for SimpleChrome to use.

    Args:
        chroot: The chroot class used for these artifacts.
        sysroot_class: The sysroot class used for these artifacts.
        build_target: The build target used for these artifacts.
        output_dir: The path to write artifacts to.

    Returns:
        Path to the sysroot tar file.
    """
    return _create_sysroot(
        chroot,
        _sysroot_class,
        build_target,
        output_dir,
        [constants.CHROME_CP],
        output_file=constants.CHROME_SYSROOT_TAR,
    )


def CreateFuzzerSysroot(
    chroot: "chroot_lib.Chroot",
    _sysroot_class,
    build_target: "build_target_lib.BuildTarget",
    output_dir: str,
) -> str:
    """Create a sysroot for fuzzer builders.

    Args:
        chroot: The chroot class used for these artifacts.
        sysroot_class: The sysroot class used for these artifacts.
        build_target: The build target used for these artifacts.
        output_dir: The path to write artifacts to.

    Returns:
        Path to the sysroot tar file.
    """
    return _create_sysroot(
        chroot,
        _sysroot_class,
        build_target,
        output_dir,
        ["virtual/target-fuzzers"],
        output_file="sysroot_virtual_target-os.tar.xz",
        deps_only=False,
    )


def CreateChromeEbuildEnv(
    chroot: "chroot_lib.Chroot",
    sysroot_class: sysroot_lib.Sysroot,
    _build_target,
    output_dir: str,
) -> Optional[str]:
    """Generate Chrome ebuild environment.

    Args:
        chroot: The chroot class used for these artifacts.
        sysroot_class: The sysroot where the original environment archive can be
        found.
        output_dir: Where the result should be stored.

    Returns:
        The path to the archive, or None.
    """
    pkg_dir = chroot.full_path(sysroot_class.path, portage_util.VDB_PATH)
    files = glob.glob(os.path.join(pkg_dir, constants.CHROME_CP) + "-*")
    if not files:
        logging.warning("No package found for %s", constants.CHROME_CP)
        return None

    if len(files) > 1:
        logging.warning(
            "Expected one package for %s, found %d",
            constants.CHROME_CP,
            len(files),
        )

    chrome_dir = sorted(files)[-1]
    env_bzip = os.path.join(chrome_dir, "environment.bz2")
    result_path = os.path.join(output_dir, constants.CHROME_ENV_TAR)
    with osutils.TempDir() as tempdir:
        # Convert from bzip2 to tar format.
        bzip2 = cros_build_lib.FindCompressor(
            cros_build_lib.CompressionType.BZIP2
        )
        tempdir_tar_path = os.path.join(tempdir, constants.CHROME_ENV_FILE)
        cros_build_lib.run(
            [bzip2, "-d", env_bzip, "-c"], stdout=tempdir_tar_path
        )

        cros_build_lib.CreateTarball(result_path, tempdir)

    return result_path


def InstallToolchain(
    target: "build_target_lib.BuildTarget",
    sysroot: sysroot_lib.Sysroot,
    run_configs: SetupBoardRunConfig,
) -> None:
    """Update the toolchain to a sysroot.

    This entry point just installs the target's toolchain into the sysroot.
    Everything else must have been done already for this to be successful.

    Args:
        target: The target whose toolchain is being installed.
        sysroot: The sysroot where the toolchain is being installed.
        run_configs: The run configs.
    """
    cros_build_lib.AssertInsideChroot()
    if not sysroot.Exists():
        # Sanity check before we try installing anything.
        raise ValueError("The sysroot must exist, run Create first.")

    # Step 4: Install toolchain and packages.
    # Dependencies: Portage configs and wrappers have been installed.
    if run_configs.init_board_pkgs:
        logging.info("Updating toolchain.")
        # Use the local packages if we're doing a local only build or usepkg is
        # set.
        local_init = run_configs.usepkg or run_configs.local_build
        _InstallToolchain(sysroot, target, local_init=local_init)


@metrics_lib.timed("service.sysroot.BuildPackages")
def BuildPackages(
    target: "build_target_lib.BuildTarget",
    sysroot: sysroot_lib.Sysroot,
    run_configs: BuildPackagesRunConfig,
) -> None:
    """Build and install packages into a sysroot.

    Args:
        target: The target whose packages are being installed.
        sysroot: The sysroot where the packages are being installed.
        run_configs: The run configs.

    Raises:
        sysroot_lib.PackageInstallError when packages fail to install.
    """
    cros_build_lib.AssertInsideChroot()
    cros_build_lib.AssertNonRootUser()
    metrics_prefix = "service.sysroot.BuildPackages"

    if (
        os.path.isfile(chromite_config.AUTO_COP_CONFIG)
        or getpass.getuser() == "chrome-bot"
    ):
        cop_command = [
            "cros",
            "clean-outdated-pkgs",
            f"--board={target.name}",
        ]
        # Set check=False to allow cop to fail.
        cros_build_lib.sudo_run(
            cop_command,
            preserve_env=True,
            check=False,
        )

    extra_env = run_configs.GetExtraEnv()
    extra_env["PKGDIR"] = f"{sysroot.path}/packages"
    with osutils.TempDir() as tempdir, cpupower_helper.ModifyCpuGovernor(
        run_configs.autosetgov, run_configs.autosetgov_sticky
    ):
        extra_env[constants.CROS_METRICS_DIR_ENVVAR] = tempdir

        cros_build_lib.ClearShadowLocks(sysroot.path)

        portage_binhost = portage_util.PortageqEnvvar(
            "PORTAGE_BINHOST", target.name
        )
        logging.info("PORTAGE_BINHOST: %s", portage_binhost)

        # Before running any emerge operations, regenerate the Portage
        # dependency cache in parallel.
        logging.info("Rebuilding Portage cache.")
        with metrics_lib.timer(f"{metrics_prefix}.RegenPortageCache"):
            portage_util.RegenDependencyCache(
                sysroot=sysroot.path, jobs=run_configs.jobs
            )

        # Clean out any stale binpkgs we've accumulated. This is done
        # immediately after regenerating the cache in case ebuilds have been
        # removed (e.g. from a revert).
        if run_configs.eclean:
            _CleanStaleBinpkgs(sysroot.path)

        emerge_cmd = _GetEmergeCommand(sysroot.path)
        emerge_flags = run_configs.GetEmergeFlags()
        rebuild_pkgs = " ".join(run_configs.GetForceLocalBuildPackages(sysroot))
        if rebuild_pkgs:
            emerge_flags.extend(
                [
                    f"--reinstall-atoms={rebuild_pkgs}",
                    f"--usepkg-exclude={rebuild_pkgs}",
                ]
            )

        sdk_pkgs = " ".join(_CRITICAL_SDK_PACKAGES)
        emerge_flags.extend(
            [
                f"--useoldpkg-atoms={sdk_pkgs}",
                f"--rebuild-exclude={sdk_pkgs}",
            ]
        )
        with RemoteExecution(run_configs.use_goma, run_configs.use_remoteexec):
            logging.info("Merging board packages now.")
            try:
                with metrics_lib.timer(f"{metrics_prefix}.emerge"):
                    cros_build_lib.sudo_run(
                        emerge_cmd + emerge_flags + run_configs.GetPackages(),
                        preserve_env=True,
                        extra_env=extra_env,
                    )
                logging.info("Builds complete.")
            except cros_build_lib.RunCommandError as e:
                failed_pkgs = portage_util.ParseDieHookStatusFile(tempdir)
                raise sysroot_lib.PackageInstallError(
                    "Merging board packages failed",
                    e.result,
                    exception=e,
                    packages=failed_pkgs,
                )

        if run_configs.install_debug_symbols:
            logging.info("Fetching the debug symbols.")
            try:
                # TODO(xcl): Convert to directly importing and calling a Python
                #   lib instead of calling a binary.
                cros_build_lib.run(
                    [
                        constants.CHROMITE_BIN_DIR / "cros_install_debug_syms",
                        f"--board={sysroot.build_target_name}",
                        "--all",
                    ]
                )
            except cros_build_lib.RunCommandError as e:
                logging.error("Unable to install debug symbols: %s", e)

        # Remove any broken or outdated binpkgs.
        if run_configs.eclean:
            portage_util.CleanOutdatedBinaryPackages(sysroot.path, deep=True)


def _CleanStaleBinpkgs(sysroot: Union[str, os.PathLike]) -> None:
    """Clean any accumulated stale binpkgs.

    Args:
        sysroot: The sysroot to clean stale binpkgs for.

    Raises:
        cros_build_lib.RunCommandError
    """
    logging.info("Cleaning stale binpkgs.")
    exclude_pkgs = [
        x.package_info.atom
        for x in portage_util.PortageDB().InstalledPackages()
        if x.category.startswith("cross-")
    ]
    with tempfile.NamedTemporaryFile(mode="w") as f:
        f.write("\n".join(exclude_pkgs))
        f.flush()
        portage_util.CleanOutdatedBinaryPackages(
            sysroot, deep=True, exclusion_file=f.name
        )


def _GetCrosWorkonPackages(sysroot: Union[str, os.PathLike]) -> _PACKAGE_LIST:
    """Get cros_workon packages.

    Args:
        sysroot: The sysroot to get cros_workon packages for.

    Raises:
        cros_build_lib.RunCommandError
    """
    # TODO(xcl): Migrate this to calling an imported Python lib
    cmd = ["cros_list_modified_packages", "--sysroot", sysroot]
    result = cros_build_lib.run(
        cmd, print_cmd=False, capture_output=True, encoding="utf-8"
    )
    logging.info(
        "Detected cros_workon modified packages: %s", result.stdout.rstrip()
    )
    packages = result.stdout.split()

    if os.environ.get("CHROME_ORIGIN"):
        packages.extend(_CHROME_PACKAGES)

    return packages


def _GetBaseInstallPackages(
    sysroot: Union[str, os.PathLike], emerge_flags: str, packages: List[str]
) -> List[Optional[str]]:
    """Get packages to determine reverse dependencies for.

    Args:
        sysroot: The sysroot to get packages for.
        emerge_flags: Emerge flags to run the command with.
        packages: The packages to get dependencies for.

    Raises:
        cros_build_lib.RunCommandError
    """
    # Do a pretend `emerge` command to get a list of what would be built.
    # Sample output:
    # [binary N] dev-go/containerd ... to /build/eve/ USE="..."
    # [ebuild r U] chromeos-base/tast-build-deps ... to /build/eve/ USE="..."
    # [binary U] chromeos-base/chromeos-chrome ... to /build/eve/ USE="..."
    cmd = _GetEmergeCommand(sysroot)
    result = cros_build_lib.sudo_run(
        cmd + emerge_flags + packages, capture_output=True, encoding="utf-8"
    )

    # Filter to a heuristic set of packages known to have incorrectly specified
    # dependencies that will be installed to the board sysroot.
    # Sample output is filtered to:
    # [ebuild r U] chromeos-base/tast-build-deps ... to /build/eve/ USE="..."
    include_patterns = ["coreboot-private-files", "tast-build-deps"]

    # Pattern used to rewrite the line from Portage's full output to only
    # $CATEGORY/$PACKAGE.
    pattern = re.compile(r"\[ebuild(.*?)\]\s(.*?)\s")

    # Filter and sort the output and remove any duplicate entries.
    packages = set()
    for line in result.stdout.splitlines():
        if "to /build/" in line and any(x in line for x in include_patterns):
            # Use regex to get substrings that matches a
            # '[ebuild ...] <some characters> ' pattern. The second matching
            # group returns the $CATEGORY/$PACKAGE from a line of the emerge
            # output.
            m = pattern.search(line)
            if m:
                packages.add(m.group(2))
    return sorted(packages)


def _GetEmergeCommand(
    sysroot: Optional[Union[str, os.PathLike]] = None
) -> List[Union[str, os.PathLike]]:
    """Get the emerge command to use with build_packages."""
    # TODO(xcl): Convert to directly importing and calling a Python lib instead
    # of calling a binary.
    cmd = [constants.CHROMITE_BIN_DIR / "parallel_emerge"]
    if sysroot:
        cmd.extend(
            [
                f"--sysroot={sysroot}",
                f"--root={sysroot}",
            ]
        )
    return cmd


def _CreateSysrootSkeleton(sysroot: sysroot_lib.Sysroot) -> None:
    """Create the sysroot skeleton.

    Dependencies: None.
    Creates the sysroot directory structure and installs the portage hooks.

    Args:
        sysroot: The sysroot.
    """
    sysroot.CreateSkeleton()


def _InstallConfigs(
    sysroot: sysroot_lib.Sysroot, target: "build_target_lib.BuildTarget"
) -> None:
    """Install standalone configuration files into the sysroot.

    Dependencies: The sysroot exists (i.e. CreateSysrootSkeleton).
    Installs the main, board setup, and user make.conf files.

    Args:
        sysroot: The sysroot.
        target: The build target being setup in the sysroot.
    """
    sysroot.InstallMakeConf()
    sysroot.InstallMakeConfBoardSetup(target.name)
    sysroot.InstallMakeConfUser()


def _InstallPortageConfigs(
    sysroot: sysroot_lib.Sysroot,
    target: "build_target_lib.BuildTarget",
    accept_licenses: Optional[str],
    local_build: bool,
    package_indexes: List["binpkg.PackageIndexInfo"] = None,
    expanded_binhost_inheritance: bool = False,
) -> None:
    """Install portage wrappers and configurations.

    Dependencies: make.conf.board_setup (InstallConfigs).
    Create the command wrappers, choose profile, and generate make.conf.board.
    Refresh the workon symlinks to compensate for crbug.com/679831.

    Args:
        sysroot: The sysroot.
        target: The build target being installed in the sysroot.
        accept_licenses: Additional accepted licenses as a string.
        local_build: If the build is a local only build.
        package_indexes: List of information about available prebuilts, youngest
            first, or None.
        expanded_binhost_inheritance: Whether to allow expanded binhost
            inheritance.
    """
    sysroot.CreateAllWrappers(friendly_name=target.name)
    _ChooseProfile(target, sysroot)
    _RefreshWorkonSymlinks(target.name, sysroot)
    # Must be done after the profile is chosen or binhosts may be incomplete.
    sysroot.InstallMakeConfBoard(
        accepted_licenses=accept_licenses,
        local_only=local_build,
        package_indexes=package_indexes,
        expanded_binhost_inheritance=expanded_binhost_inheritance,
    )


def _InstallToolchain(
    sysroot: sysroot_lib.Sysroot,
    target: "build_target_lib.BuildTarget",
    local_init: bool = True,
) -> None:
    """Install toolchain and packages.

    Dependencies: Portage configs and wrappers have been installed
        (InstallPortageConfigs).
    Install the toolchain and the implicit dependencies.

    Args:
        sysroot: The sysroot to install to.
        target: The build target whose toolchain is being installed.
        local_init: Whether to use local packages to bootstrap implicit
            dependencies.
    """
    sysroot.UpdateToolchain(target.name, local_init=local_init)


def _RefreshWorkonSymlinks(target: str, sysroot: sysroot_lib.Sysroot) -> None:
    """Force refresh the workon symlinks.

    Create an instance of the WorkonHelper, which will recreate all symlinks
    to masked/unmasked packages currently worked on in case the sysroot was
    recreated (crbug.com/679831).

    This was done with a call to `cros_workon list` in the bash version of
    the script, but all we actually need is for the WorkonHelper to be
    instantiated since it refreshes the symlinks in its __init__.

    Args:
        target: The build target name.
        sysroot: The board's sysroot.
    """
    workon_helper.WorkonHelper(sysroot.path, friendly_name=target)


def _ChooseProfile(
    target: "build_target_lib.BuildTarget", sysroot: sysroot_lib.Sysroot
) -> None:
    """Helper function to execute cros_choose_profile.

    TODO(saklein) Refactor cros_choose_profile to avoid needing the run
    call here, and by extension this method all together.

    Args:
        target: The build target whose profile is being chosen.
        sysroot: The sysroot for which the profile is being chosen.
    """
    choose_profile = [
        "cros_choose_profile",
        "--board",
        target.name,
        "--board-root",
        sysroot.path,
    ]
    if target.profile:
        # Chooses base by default, only override when we have a passed param.
        choose_profile += ["--profile", target.profile]
    try:
        cros_build_lib.run(choose_profile, print_cmd=False)
    except cros_build_lib.RunCommandError as e:
        logging.error(
            "Selecting profile failed, removing incomplete board " "directory!"
        )
        sysroot.Delete()
        raise e


def BundleDebugSymbols(
    chroot: "chroot_lib.Chroot",
    sysroot_class: sysroot_lib.Sysroot,
    _build_target: "build_target_lib.BuildTarget",
    output_dir: str,
) -> Optional[str]:
    """Bundle debug symbols into a tarball for importing into GCE.

    Bundle the debug symbols found in the sysroot into a .tgz. This assumes
    these files are present.

    Args:
        chroot: The chroot class used for these artifacts.
        sysroot_class: The sysroot class used for these artifacts.
        build_target: The build target used for these artifacts.
        output_dir: The path to write artifacts to.

    Returns:
        A string path to the output debug.tgz artifact, or None.
    """
    base_path = chroot.full_path(sysroot_class.path)
    debug_dir = os.path.join(base_path, "usr/lib/debug")

    if not os.path.isdir(debug_dir):
        logging.error("No debug directory found at %s.", debug_dir)
        return None

    # Create tarball from destination_tmp, then copy it...
    tarball_path = os.path.join(output_dir, constants.DEBUG_SYMBOLS_TAR)
    exclude_breakpad_tar_arg = "--exclude=%s" % os.path.join(
        debug_dir, "breakpad"
    )
    result = None
    try:
        result = cros_build_lib.CreateTarball(
            tarball_path,
            debug_dir,
            compression=cros_build_lib.CompressionType.GZIP,
            sudo=True,
            extra_args=[exclude_breakpad_tar_arg],
        )
    except cros_build_lib.TarballError:
        pass
    if not result or result.returncode:
        # We don't abort here, because the tar may still be somewhat intact.
        err = result.return_code if result else "TarballError"
        logging.error(
            "Error (%s) when creating tarball %s from %s",
            err,
            tarball_path,
            debug_dir,
        )
    if os.path.exists(tarball_path):
        return tarball_path
    else:
        return None


def BundleBreakpadSymbols(
    chroot: "chroot_lib.Chroot",
    sysroot_class: sysroot_lib.Sysroot,
    build_target: "build_target_lib.BuildTarget",
    output_dir: str,
) -> Optional[str]:
    """Bundle breakpad debug symbols into a tarball for importing into GCE.

    Call the GenerateBreakpadSymbols function and archive this into a tar.gz.

    Args:
        chroot: The chroot class used for these artifacts.
        sysroot_class: The sysroot class used for these artifacts.
        build_target: The build target used for these artifacts.
        output_dir: The path to write artifacts to.

    Returns:
        A string path to the output debug_breakpad.tar.gz artifact, or None.
    """
    base_path = chroot.full_path(sysroot_class.path)

    result = GenerateBreakpadSymbols(chroot, build_target, debug=True)

    # Verify breakpad symbol generation before gathering the sym files.
    if result.returncode:
        logging.error(
            "Error (%d) when generating breakpad symbols", result.returncode
        )
        return None
    with chroot.tempdir() as symbol_tmpdir, chroot.tempdir() as dest_tmpdir:
        breakpad_dir = os.path.join(base_path, "usr/lib/debug/breakpad")
        # Call list on the atifacts.GatherSymbolFiles generator function to
        # materialize and consume all entries so that all are copied to
        # dest dir and complete list of all symbol files is returned.
        sym_file_list = list(
            GatherSymbolFiles(
                tempdir=symbol_tmpdir, destdir=dest_tmpdir, paths=[breakpad_dir]
            )
        )

        if not sym_file_list:
            logging.warning("No sym files found in %s.", breakpad_dir)
        # Create tarball from destination_tmp, then copy it...
        tarball_path = os.path.join(
            output_dir, constants.BREAKPAD_DEBUG_SYMBOLS_TAR
        )
        result = cros_build_lib.CreateTarball(tarball_path, dest_tmpdir)
        if result.returncode != 0:
            logging.error(
                "Error (%d) when creating tarball %s from %s",
                result.returncode,
                tarball_path,
                dest_tmpdir,
            )
            return None
    return tarball_path


# A SymbolFileTuple is a data object that contains:
#  relative_path (str): Relative path to the file based on initial search path.
#  source_file_name (str): Full path to where the SymbolFile was found.
# For example, if the search path for symbol files is '/some/bot/path/'
# and a symbol file is found at '/some/bot/path/a/b/c/file1.sym',
# then the relative_path would be 'a/b/c/file1.sym' and the source_file_name
# would be '/some/bot/path/a/b/c/file1.sym'.
# The source_file_name is informational for two reasons:
# 1) They are typically copied off a machine (such as a build bot) where
#    that path will disappear, which is why when we find them they get
#    copied to a destination directory.
# 2) For tar files, the source_file_name is not a full path that can be
#    opened, since it is the path the tar file plus the relative path of
#    the file when we untar it.
class SymbolFileTuple(NamedTuple):
    """Contain a relative and full path to a SymbolFile."""

    relative_path: str
    source_file_name: str


def GenerateBreakpadSymbols(
    chroot: "chroot_lib.Chroot",
    build_target: "build_target_lib.BuildTarget",
    debug: bool,
) -> cros_build_lib.CompletedProcess:
    """Generate breakpad (go/breakpad) symbols for debugging.

    This function generates .sym files to /build/<board>/usr/lib/debug/breakpad
    from .debug files found in /build/<board>/usr/lib/debug by calling
    cros_generate_breakpad_symbols.

    Args:
        chroot: The chroot in which the sysroot should be built.
        build_target: The sysroot's build target.
        debug: Include extra debugging output.
    """
    # The firmware directory contains elf symbols that we have trouble parsing
    # and that don't help with breakpad debugging (see crbug.com/213670).
    exclude_dirs = ["firmware"]

    cmd = ["cros_generate_breakpad_symbols"]
    if debug:
        cmd += ["--debug"]

    # Execute for board in parallel with half # of cpus available to avoid
    # starving other parallel processes on the same machine.
    cmd += [
        "--board=%s" % build_target.name,
        "--jobs",
        str(max(1, multiprocessing.cpu_count() // 2)),
    ]
    cmd += ["--exclude-dir=%s" % x for x in exclude_dirs]

    logging.info("Generating breakpad symbols: %s.", cmd)
    result = cros_build_lib.run(
        cmd, enter_chroot=True, chroot_args=chroot.get_enter_args()
    )
    return result


def GatherSymbolFiles(
    tempdir: str, destdir: str, paths: List[str]
) -> Generator[SymbolFileTuple, None, None]:
    """Locate symbol files in |paths|

    This generator function searches all paths for .sym files and copies them to
    destdir. A path to a tarball will result in the tarball being unpacked and
    examined. A path to a directory will result in the directory being searched
    for .sym files. The generator yields SymbolFileTuple objects that contain
    symbol file references which are valid after this exits. Those files may
    exist externally, or be created in the tempdir (when expanding tarballs).
    Typical usage in the BuildAPI will be for the .sym files to exist under a
    directory such as /build/<board>/usr/lib/debug/breakpad so that the path to
    a sym file will always be unique.
    Note: the caller must clean up the tempdir.
    Note: this function is recursive for tar files.

    Args:
        tempdir: Path to use for temporary files.
        destdir: All .sym files are copied to this path. Tarfiles are opened
            inside a tempdir and any .sym files within them are copied to
            destdir from within that temp path.
        paths: A list of input paths to walk. Files are returned based on .sym
            name w/out any checking internal symbol file format. Dirs are
            searched for files that end in ".sym". Urls are not handled.
            Tarballs are unpacked and walked.

    Yields:
        A SymbolFileTuple for every symbol file found in paths.
    """
    logging.info(
        "GatherSymbolFiles tempdir %s destdir %s paths %s",
        tempdir,
        destdir,
        paths,
    )
    for p in paths:
        o = urllib.parse.urlparse(p)
        if o.scheme:
            raise NotImplementedError("URL paths are not expected/handled: ", p)
        elif not os.path.exists(p):
            raise NoFilesError("The path did not exist: ", p)
        elif os.path.isdir(p):
            for root, _, files in os.walk(p):
                for f in files:
                    if f.endswith(".sym"):
                        # If p is '/tmp/foo' and filename is
                        # '/tmp/foo/bar/bar.sym', relative_path = 'bar/bar.sym'
                        filename = os.path.join(root, f)
                        relative_path = filename[len(p) :].lstrip("/")
                        try:
                            shutil.copy(
                                filename, os.path.join(destdir, relative_path)
                            )
                        except IOError:
                            # Handles pre-3.3 Python where we may need to make
                            # the target path's dirname before copying.
                            os.makedirs(
                                os.path.join(
                                    destdir, os.path.dirname(relative_path)
                                )
                            )
                            shutil.copy(
                                filename, os.path.join(destdir, relative_path)
                            )
                        yield SymbolFileTuple(
                            relative_path=relative_path,
                            source_file_name=filename,
                        )

        elif cros_build_lib.IsTarball(p):
            tardir = tempfile.mkdtemp(dir=tempdir)
            cache.Untar(os.path.realpath(p), tardir)
            for sym in GatherSymbolFiles(tardir, destdir, [tardir]):
                # The SymbolFileTuple is generated from [tardir], but we want
                # the source_file_name (which informational) to reflect the tar
                # path plus the relative path after the file is untarred. Thus,
                # something like /botpath/some/path/tmp22dl33sa/dir1/fileB.sym
                # (where the tardir is /botpath/some/path/tmp22dl33sa) has a
                # resulting path /botpath/some/path/symfiles.tar/dir1/fileB.sym
                # When we call GatherSymbolFiles with [tardir] as the argument,
                # the os.path.isdir case above will walk the tar contents,
                # processing only .sym. Non-sym files within the tar file will
                # be ignored (even tar files within tar files, which we don't
                # expect).
                new_source_file_name = sym.source_file_name.replace(tardir, p)
                yield SymbolFileTuple(
                    relative_path=sym.relative_path,
                    source_file_name=new_source_file_name,
                )

        elif os.path.isfile(p):
            # Path p is a file. This code path is only executed when a full file
            # path is one of the elements in the 'paths' argument. When a
            # directory is an element of the 'paths' argument, we walk the tree
            # (above) and process each file. When a tarball is an element of the
            # 'paths' argument, we untar it into a directory and recurse with
            # the temp tardir as the directory, so that tarfile contents are
            # processed (above) in the os.walk of the directory.
            if p.endswith(".sym"):
                shutil.copy(p, destdir)
                yield SymbolFileTuple(
                    relative_path=os.path.basename(p), source_file_name=p
                )
        else:
            raise ValueError("Unexpected input to GatherSymbolFiles: ", p)


@contextlib.contextmanager
def RemoteExecution(use_goma: bool, use_remoteexec: bool) -> Iterator[None]:
    """A context manager to start goma or remoteexec instance.

    The context manager depending on the input argument will decide to start
    either the goma or remote exec instance.

    Args:
        use_goma: If true, start the goma instance.
        use_remoteexec: If true, start the remoteexec instance.

    Yields:
        Iterator.
    """
    goma_dir = Path(os.environ.get("GOMA_DIR", Path.home() / "goma"))
    goma_tmp_dir = os.environ.get("GOMA_TMP_DIR")
    glog_log_dir = os.environ.get("GLOG_log_dir")
    reclient_dir = os.environ.get("RECLIENT_DIR")
    reproxy_cfg_file = os.environ.get("REPROXY_CFG")
    remoteexec_instance = None
    goma_instance = None

    try:
        if use_remoteexec and reclient_dir and reproxy_cfg_file:
            logging.info("Starting RBE reproxy.")
            remoteexec_instance = remoteexec_util.Remoteexec(
                reclient_dir, reproxy_cfg_file
            )
        elif use_goma:
            logging.info("Starting goma compiler_proxy.")
            goma_instance = goma_lib.Goma(
                goma_dir,
                goma_tmp_dir,
                stage_name="BuildPackages",
                log_dir=glog_log_dir,
            )
    except ValueError:
        logging.warning("Remote execution initialization error.")

    try:
        if remoteexec_instance:
            remoteexec_instance.Start()
        elif goma_instance:
            goma_instance.Restart()
        yield
    finally:
        if remoteexec_instance:
            logging.info("Stopping RBE reproxy.")
            remoteexec_instance.Stop()
        elif goma_instance:
            logging.info("Stopping goma compiler_proxy.")
            goma_instance.Stop()


def ArchiveSysroot(
    chroot: "chroot_lib.Chroot",
    sysroot: "sysroot_lib.Sysroot",
    _build_target: "build_target_lib.BuildTarget",
    output_dir: os.PathLike,
) -> Optional[os.PathLike]:
    """Archive the given sysroot.

    Args:
        chroot: The chroot in which the sysroot exists.
        sysroot: Sysroot that needs to be archived.
        output_dir: Directory in which the generated archive will be placed.

    Returns:
        The archive file path or None if the archive directory doesnt exists.
    """
    sysroot_path = Path(chroot.full_path(sysroot.path))
    if not sysroot_path.is_dir():
        return None

    osutils.SafeMakedirs(output_dir)
    archive_path = Path(output_dir) / SYSROOT_ARCHIVE_FILE

    compression_type = cros_build_lib.CompressionExtToType(SYSROOT_ARCHIVE_FILE)
    cros_build_lib.CreateTarball(
        archive_path,
        sysroot_path,
        compression=compression_type,
        chroot=chroot.path,
        sudo=True,
    )

    return archive_path
