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

"""Script that deploys a Chrome build to a device.

The script supports deploying Chrome from these sources:

1. A local build output directory, such as chromium/src/out/[Debug|Release].
2. A Chrome tarball uploaded by a trybot/official-builder to GoogleStorage.
3. A Chrome tarball existing locally.

The script copies the necessary contents of the source location (tarball or
build directory) and rsyncs the contents of the staging directory onto your
device's rootfs.
"""

import argparse
import collections
import contextlib
import functools
import glob
import logging
import multiprocessing
import os
import re
import shlex
import shutil
import time

from chromite.third_party.gn_helpers import gn_helpers

from chromite.cli.cros import cros_chrome_sdk
from chromite.lib import chrome_util
from chromite.lib import commandline
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import failures_lib
from chromite.lib import gs
from chromite.lib import osutils
from chromite.lib import parallel
from chromite.lib import remote_access as remote
from chromite.lib import retry_util
from chromite.lib import timeout_util


KERNEL_A_PARTITION = 2
KERNEL_B_PARTITION = 4

KILL_PROC_MAX_WAIT = 10
POST_KILL_WAIT = 2
POST_UNLOCK_WAIT = 3

MOUNT_RW_COMMAND = ["mount", "-o", "remount,rw", "/"]
LAST_LOGIN_COMMAND = ["bootstat_get_last", "login-prompt-visible"]
UNLOCK_PASSWORD_COMMAND = "python -m uinput.cros_type_keys $'%s\\n'"

_ANDROID_DIR = "/system/chrome"
_ANDROID_DIR_EXTRACT_PATH = "system/chrome/*"

_CHROME_DIR = "/opt/google/chrome"
_CHROME_DIR_MOUNT = "/usr/local/opt/google/chrome"
_CHROME_DIR_STAGING_TARBALL_ZSTD = "chrome.tar.zst"
_CHROME_TEST_BIN_DIR = "/usr/local/libexec/chrome-binary-tests"

_UMOUNT_DIR_IF_MOUNTPOINT_CMD = (
    "if mountpoint -q %(dir)s; then umount %(dir)s; fi"
)
_FIND_TEST_BIN_CMD = [
    "find",
    _CHROME_TEST_BIN_DIR,
    "-maxdepth",
    "1",
    "-executable",
    "-type",
    "f",
]

# This constants are related to an experiment of running compressed ash chrome
# to save rootfs space. See b/247397013
COMPRESSED_ASH_SERVICE = "mount-ash-chrome"
COMPRESSED_ASH_FILE = "chrome.squashfs"
RAW_ASH_FILE = "chrome"
COMPRESSED_ASH_PATH = os.path.join(_CHROME_DIR, COMPRESSED_ASH_FILE)
RAW_ASH_PATH = os.path.join(_CHROME_DIR, RAW_ASH_FILE)
COMPRESSED_ASH_OVERLAY_SUFFIX = "-compressed-ash"

LACROS_DIR = "/usr/local/lacros-chrome"
_CONF_FILE = "/etc/chrome_dev.conf"
MODIFIED_CONF_FILE = f"modified {_CONF_FILE}"

# This command checks if
# "--enable-features=LacrosOnly,LacrosPrimary,LacrosSupport" is present in
# /etc/chrome_dev.conf. If it is not, then it is added.
# TODO(https://crbug.com/1112493): Automated scripts are currently not allowed
# to modify chrome_dev.conf. Either revisit this policy or find another
# mechanism to pass configuration to ash-chrome.
ENABLE_LACROS_VIA_CONF_COMMAND = f"""
    if ! grep -q "^--enable-features=LacrosOnly,LacrosPrimary,LacrosSupport$" {_CONF_FILE}; then
    echo "--enable-features=LacrosOnly,LacrosPrimary,LacrosSupport" >> {_CONF_FILE};
    echo {MODIFIED_CONF_FILE};
    fi
"""

# This command checks if "--lacros-chrome-path=" is present with the right value
# in /etc/chrome_dev.conf. If it is not, then all previous instances are removed
# and the new one is added.
# TODO(https://crbug.com/1112493): Automated scripts are currently not allowed
# to modify chrome_dev.conf. Either revisit this policy or find another
# mechanism to pass configuration to ash-chrome.
_SET_LACROS_PATH_VIA_CONF_COMMAND = """
    if ! grep -q "^--lacros-chrome-path=%(lacros_path)s$" %(conf_file)s; then
    sed 's/--lacros-chrome-path/#--lacros-chrome-path/' %(conf_file)s;
    echo "--lacros-chrome-path=%(lacros_path)s" >> %(conf_file)s;
    echo %(modified_conf_file)s;
    fi
"""


def _UrlBaseName(url):
    """Return the last component of the URL."""
    return url.rstrip("/").rpartition("/")[-1]


class DeployFailure(failures_lib.StepFailure):
    """Raised whenever the deploy fails."""


DeviceInfo = collections.namedtuple(
    "DeviceInfo", ["target_dir_size", "target_fs_free"]
)


class DeployChrome:
    """Wraps the core deployment functionality."""

    def __init__(self, options, tempdir, staging_dir) -> None:
        """Initialize the class.

        Args:
            options: options object.
            tempdir: Scratch space for the class.  Caller has responsibility to
                clean it up.
            staging_dir: Directory to stage the files to.
        """
        self.tempdir = tempdir
        self.options = options
        self.staging_dir = staging_dir
        if not self.options.staging_only:
            hostname = options.device.hostname
            port = options.device.port
            self.device = remote.ChromiumOSDevice(
                hostname,
                port=port,
                ping=options.ping,
                private_key=options.private_key,
                include_dev_paths=False,
            )
            if self._ShouldUseCompressedAsh():
                self.options.compressed_ash = True

        self._root_dir_is_still_readonly = multiprocessing.Event()

        self._deployment_name = "lacros" if options.lacros else "chrome"
        self.copy_paths = chrome_util.GetCopyPaths(self._deployment_name)

        self.chrome_dir = LACROS_DIR if self.options.lacros else _CHROME_DIR

        # Whether UI was stopped during setup.
        self._stopped_ui = False

    def _ShouldUseCompressedAsh(self):
        """Detects if the DUT uses compressed-ash setup."""
        if self.options.lacros:
            return False

        return self.device.IfFileExists(COMPRESSED_ASH_PATH)

    def _GetRemoteMountFree(self, remote_dir):
        result = self.device.run(["df", "-k", remote_dir])
        line = result.stdout.splitlines()[1]
        value = line.split()[3]
        multipliers = {
            "G": 1024 * 1024 * 1024,
            "M": 1024 * 1024,
            "K": 1024,
        }
        return int(value.rstrip("GMK")) * multipliers.get(value[-1], 1)

    def _GetRemoteDirSize(self, remote_dir):
        result = self.device.run(
            ["du", "-ks", remote_dir], capture_output=True, encoding="utf-8"
        )
        return int(result.stdout.split()[0])

    def _GetStagingDirSize(self):
        result = cros_build_lib.dbg_run(
            ["du", "-ks", self.staging_dir],
            capture_output=True,
            encoding="utf-8",
        )
        return int(result.stdout.split()[0])

    def _ChromeFileInUse(self):
        result = self.device.run(
            ["lsof", f"{self.options.target_dir}/chrome"],
            check=False,
            capture_output=True,
        )
        return result.returncode == 0

    def _DisableRootfsVerification(self):
        if not self.options.force:
            logging.error(
                "Detected that the device has rootfs verification enabled."
            )
            logging.info(
                "This script can automatically remove the rootfs "
                "verification, which requires it to reboot the device."
            )
            logging.info("Make sure the device is in developer mode!")
            logging.info("Skip this prompt by specifying --force.")
            if not cros_build_lib.BooleanPrompt(
                "Remove rootfs verification?", False
            ):
                return False

        logging.info(
            "Removing rootfs verification from %s", self.options.device
        )
        # Running in VMs cause make_dev_ssd's firmware confidence checks to
        # fail. Use --force to bypass the checks.
        # TODO(b/269266992): Switch back to a list.
        cmd = (
            "/usr/share/vboot/bin/make_dev_ssd.sh "
            f"--partitions '{KERNEL_A_PARTITION} {KERNEL_B_PARTITION}' "
            "--remove_rootfs_verification "
            "--force"
        )
        self.device.run(cmd, shell=True, check=False)

        self.device.Reboot()

        # Make sure the rootfs is writable now.
        self._MountRootfsAsWritable(run_diagnostics=True)

        # Now that the machine has been rebooted, we need to kill Chrome again.
        self._KillAshChromeIfNeeded()

        return self.device.IsDirWritable("/")

    def _CheckUiJobStarted(self):
        # status output is in the format:
        # <job_name> <status> ['process' <pid>].
        # <status> is in the format <goal>/<state>.
        try:
            result = self.device.run(
                ["status", "ui"], capture_output=True, encoding="utf-8"
            )
        except cros_build_lib.RunCommandError as e:
            if "Unknown job" in e.stderr:
                return False
            else:
                raise e

        return result.stdout.split()[1].split("/")[0] == "start"

    def _KillLacrosChrome(self) -> None:
        """This method kills lacros-chrome on the device, if it's running."""
        # Mark the lacros chrome binary as not executable, so if keep-alive is
        # enabled ash chrome can't restart lacros chrome. This prevents rsync
        # from failing if the file is still in use (being executed by ash
        # chrome). Note that this will cause ash chrome to continuously attempt
        # to start lacros and fail, although it doesn't seem to cause issues.
        if self.options.skip_restart_ui:
            self.device.chmod(
                f"{self.options.target_dir}/chrome",
                "-x",
                check=False,
            )
        self.device.run(
            ["pkill", "-f", f"{self.options.target_dir}/chrome"],
            check=False,
        )

    def _ResetLacrosChrome(self) -> None:
        """Reset Lacros to fresh state by deleting user data dir."""
        self.device.run(["rm", "-rf", "/home/chronos/user/lacros"], check=False)

    def _KillAshChromeIfNeeded(self) -> None:
        """This method kills ash-chrome on the device, if it's running.

        This method calls 'stop ui', and then also manually pkills both
        ash-chrome and the session manager.
        """
        if self._CheckUiJobStarted():
            logging.info("Shutting down Chrome...")
            self.device.run(["stop", "ui"])

        # Developers sometimes run session_manager manually, in which case we'll
        # need to help shut the chrome processes down.
        try:
            with timeout_util.Timeout(self.options.process_timeout):
                while self._ChromeFileInUse():
                    logging.warning(
                        "The chrome binary on the device is in use."
                    )
                    logging.warning(
                        "Killing chrome and session_manager processes...\n"
                    )

                    self.device.run(
                        "pkill 'chrome|session_manager'", check=False
                    )
                    # Wait for processes to actually terminate
                    time.sleep(POST_KILL_WAIT)
                    logging.info("Rechecking the chrome binary...")
                if self.options.compressed_ash:
                    result = self.device.run(
                        ["umount", RAW_ASH_PATH],
                        check=False,
                        capture_output=True,
                    )
                    if result.returncode and not (
                        result.returncode == 32
                        and "not mounted" in result.stderr
                    ):
                        raise DeployFailure(
                            "Could not unmount compressed ash. "
                            f"Error Code: {result.returncode}, "
                            f"Error Message: {result.stderr}"
                        )
        except timeout_util.TimeoutError:
            msg = (
                "Could not kill processes after %s seconds.  Please exit any "
                "running chrome processes and try again."
                % self.options.process_timeout
            )
            raise DeployFailure(msg)

    def _MountRootfsAsWritable(
        self, check=False, run_diagnostics=False
    ) -> None:
        """Mounts the rootfs as writable.

        If the command fails and the root dir is not writable then this function
        sets self._root_dir_is_still_readonly.

        Args:
            check: See remote.RemoteAccess.RemoteSh for details.
            run_diagnostics: Run additional diagnostics if mounting fails.
        """
        # TODO: Should migrate to use the remount functions in remote_access.
        result = self.device.run(
            MOUNT_RW_COMMAND,
            capture_output=True,
            check=check,
            encoding="utf-8",
        )

        if not self.device.IsDirWritable("/"):
            if result and result.returncode:
                logging.warning(
                    "Mounting root as writable failed: %s", result.stderr
                )

            if run_diagnostics:
                # Dump debug info to help diagnose b/293204438.
                findmnt_result = self.device.run(
                    ["findmnt"], capture_output=True
                )
                logging.info("findmnt: %s", findmnt_result.stdout)
                dmesg_result = self.device.run(["dmesg"], capture_output=True)
                logging.info("dmesg: %s", dmesg_result.stdout)

            self._root_dir_is_still_readonly.set()
        else:
            self._root_dir_is_still_readonly.clear()

    def _EnsureTargetDir(self) -> None:
        """Ensures that the target directory exists on the remote device."""
        target_dir = self.options.target_dir
        # Any valid /opt directory should already exist so avoid the remote
        # call.
        if os.path.commonprefix([target_dir, "/opt"]) == "/opt":
            return
        self.device.mkdir(target_dir, mode=0o775)

    def _GetDeviceInfo(self):
        """Get the disk space used and available for the target directory."""
        steps = [
            functools.partial(self._GetRemoteDirSize, self.options.target_dir),
            functools.partial(
                self._GetRemoteMountFree, self.options.target_dir
            ),
        ]
        return_values = parallel.RunParallelSteps(steps, return_values=True)
        return DeviceInfo(*return_values)

    def _CheckDeviceFreeSpace(self, device_info) -> None:
        """See if target device has enough space for Chrome.

        Args:
            device_info: A DeviceInfo named tuple.
        """
        effective_free = (
            device_info.target_dir_size + device_info.target_fs_free
        )
        staging_size = self._GetStagingDirSize()
        if effective_free < staging_size:
            raise DeployFailure(
                "Not enough free space on the device.  Required: %s MiB, "
                "actual: %s MiB."
                % (staging_size // 1024, effective_free // 1024)
            )
        if device_info.target_fs_free < (100 * 1024):
            logging.warning(
                "The device has less than 100MB free.  deploy_chrome may "
                "hang during the transfer."
            )

    def _ShouldUseCompression(self):
        """Checks if compression should be used for rsync."""
        if self.options.compress == "always":
            return True
        elif self.options.compress == "never":
            return False
        elif self.options.compress == "auto":
            return not self.device.HasGigabitEthernet()

    def _Deploy(self) -> None:
        logging.info(
            "Copying %s to %s on device...",
            self._deployment_name,
            self.options.target_dir,
        )
        # CopyToDevice will fall back to scp if rsync is corrupted on stateful.
        # This does not work for deploy.
        if not self.device.HasRsync():
            # This assumes that rsync is part of the bootstrap package. In the
            # future, this might change and we'll have to install it separately.
            if not cros_build_lib.BooleanPrompt(
                "Run dev_install on the device to install rsync?", True
            ):
                raise DeployFailure("rsync is not found on the device.")
            self.device.BootstrapDevTools()
            if not self.device.HasRsync():
                raise DeployFailure("Failed to install rsync")

        try:
            staging_dir = os.path.abspath(self.staging_dir)
            staging_chrome = os.path.join(staging_dir, "chrome")

            if (
                self.options.lacros
                and self.options.skip_restart_ui
                and os.path.exists(staging_chrome)
            ):
                # Make the chrome binary not executable before deploying to
                # prevent ash chrome from starting chrome before the rsync has
                # finished.
                os.chmod(staging_chrome, 0o644)

            self.device.CopyToDevice(
                f"{staging_dir}/",
                self.options.target_dir,
                mode="rsync",
                inplace=True,
                compress=self._ShouldUseCompression(),
                debug_level=logging.INFO,
                verbose=self.options.verbose,
            )
        finally:
            if self.options.lacros and self.options.skip_restart_ui:
                self.device.chmod(
                    f"{self.options.target_dir}/chrome",
                    "+x",
                    check=False,
                )

        # Set the security context on the default Chrome dir if that's where
        # it's getting deployed, and only on SELinux supported devices.
        if (
            not self.options.lacros
            and self.device.IsSELinuxAvailable()
            and (
                _CHROME_DIR in (self.options.target_dir, self.options.mount_dir)
            )
        ):
            self.device.run(["restorecon", "-R", _CHROME_DIR])

        for p in self.copy_paths:
            if p.mode:
                # Set mode if necessary.
                sub_path = p.src if not p.dest else p.dest
                self.device.chmod(
                    f"{self.options.target_dir}/{sub_path}",
                    p.mode,
                )

        if self.options.lacros:
            self.device.run(
                ["chown", "-R", "chronos:chronos", self.options.target_dir]
            )

        if self.options.compressed_ash:
            self.device.run(["start", COMPRESSED_ASH_SERVICE])

        # Send SIGHUP to dbus-daemon to tell it to reload its configs. This
        # won't pick up major changes (bus type, logging, etc.), but all we care
        # about is getting the latest policy from /opt/google/chrome/dbus so
        # that Chrome will be authorized to take ownership of its service names.
        self.device.run(["killall", "-HUP", "dbus-daemon"], check=False)

        if self.options.startui and self._stopped_ui:
            last_login = self._GetLastLogin()
            logging.info("Starting UI...")
            self.device.run(["start", "ui"])

            if self.options.unlock_password:
                logging.info("Unlocking...")

                @retry_util.WithRetry(max_retry=5, sleep=1)
                def WaitForUnlockScreen() -> None:
                    if self._GetLastLogin() == last_login:
                        raise DeployFailure("Unlock screen not shown")

                WaitForUnlockScreen()
                time.sleep(POST_UNLOCK_WAIT)
                self.device.run(
                    UNLOCK_PASSWORD_COMMAND % self.options.unlock_password,
                    shell=True,
                )

    def _GetLastLogin(self):
        """Returns last login time"""
        return self.device.run(LAST_LOGIN_COMMAND).stdout.strip()

    def _DeployTestBinaries(self) -> None:
        """Deploys any local test binary to _CHROME_TEST_BIN_DIR on the device.

        There could be several binaries located in the local build dir, so
        compare what's already present on the device in _CHROME_TEST_BIN_DIR ,
        and copy over any that we also built ourselves.
        """
        r = self.device.run(_FIND_TEST_BIN_CMD, check=False)
        if r.returncode != 0:
            raise DeployFailure(
                "Unable to ls contents of %s" % _CHROME_TEST_BIN_DIR
            )
        binaries_to_copy = []
        for f in r.stdout.splitlines():
            binaries_to_copy.append(
                chrome_util.Path(os.path.basename(f), exe=True, optional=True)
            )

        staging_dir = os.path.join(
            self.tempdir, os.path.basename(_CHROME_TEST_BIN_DIR)
        )
        _PrepareStagingDir(
            self.options, self.tempdir, staging_dir, copy_paths=binaries_to_copy
        )
        # Deploying can occasionally run into issues with rsync getting a broken
        # pipe, so retry several times. See crbug.com/1141618 for more
        # information.
        retry_util.RetryException(
            None,
            3,
            self.device.CopyToDevice,
            staging_dir,
            os.path.dirname(_CHROME_TEST_BIN_DIR),
            mode="rsync",
        )

    def _CheckBoard(self) -> None:
        """Check that the Chrome build is targeted for the device board."""
        if self.options.board == self.device.board:
            return
        logging.warning(
            "Device board is %s whereas target board is %s.",
            self.device.board,
            self.options.board,
        )
        if self.options.force:
            return
        if not cros_build_lib.BooleanPrompt(
            "Continue despite board mismatch?", False
        ):
            raise DeployFailure("Aborted.")

    def _CheckDeployType(self) -> None:
        if self.options.build_dir:

            def BinaryExists(filename):
                """Checks if |filename| is present in the build directory."""
                return os.path.exists(
                    os.path.join(self.options.build_dir, filename)
                )

            # In the future, lacros-chrome and ash-chrome will likely be named
            # something other than 'chrome' to avoid confusion.
            # Handle non-Chrome deployments.
            if not BinaryExists("chrome"):
                if BinaryExists("app_shell"):
                    self.copy_paths = chrome_util.GetCopyPaths("app_shell")

    def _PrepareStagingDir(self) -> None:
        _PrepareStagingDir(
            self.options,
            self.tempdir,
            self.staging_dir,
            self.copy_paths,
            self.chrome_dir,
        )

    def _MountTarget(self) -> None:
        logging.info("Mounting Chrome...")

        # Create directory if does not exist.
        self.device.mkdir(self.options.mount_dir, mode=0o775)
        try:
            # Umount the existing mount on mount_dir if present first.
            self.device.run(
                _UMOUNT_DIR_IF_MOUNTPOINT_CMD % {"dir": self.options.mount_dir},
                shell=True,
            )
        except cros_build_lib.RunCommandError as e:
            logging.error("Failed to umount %s", self.options.mount_dir)
            # If there is a failure, check if some process is using the
            # mount_dir.
            result = self.device.run(
                ["lsof", self.options.mount_dir],
                check=False,
                capture_output=True,
                encoding="utf-8",
            )
            logging.error("lsof %s -->", self.options.mount_dir)
            logging.error(result.stdout)
            raise e

        self.device.run(
            [
                "mount",
                "--rbind",
                self.options.target_dir,
                self.options.mount_dir,
            ]
        )

        # Chrome needs partition to have exec and suid flags set
        self.device.run(
            ["mount", "-o", "remount,exec,suid", self.options.mount_dir]
        )

    def Cleanup(self) -> None:
        """Clean up RemoteDevice."""
        if not self.options.staging_only:
            self.device.Cleanup()

    def Perform(self):
        self._CheckDeployType()

        # If requested, just do the staging step.
        if self.options.staging_only:
            self._PrepareStagingDir()
            return 0

        # Check that the build matches the device. Lacros-chrome skips this
        # check as it's currently board independent. This means that it's
        # possible to deploy a build of lacros-chrome with a mismatched
        # architecture. We don't try to prevent this developer foot-gun.
        if not self.options.lacros:
            self._CheckBoard()

        # Ensure that the target directory exists before running parallel steps.
        self._EnsureTargetDir()

        logging.info("Preparing device")
        steps = [
            self._GetDeviceInfo,
            self._MountRootfsAsWritable,
            self._PrepareStagingDir,
        ]

        restart_ui = not self.options.skip_restart_ui
        if self.options.lacros:
            steps.append(self._KillLacrosChrome)
            if self.options.reset_lacros:
                steps.append(self._ResetLacrosChrome)
            config_modified = False
            if self.options.modify_config_file:
                config_modified = self._ModifyConfigFileIfNeededForLacros()
            if config_modified and not restart_ui:
                logging.warning(
                    "Config file modified but skipping restart_ui "
                    "due to option --skip-restart-ui. Config file "
                    "update is not reflected."
                )

        if restart_ui:
            steps.append(self._KillAshChromeIfNeeded)
            self._stopped_ui = True

        ret = parallel.RunParallelSteps(
            steps, halt_on_error=True, return_values=True
        )
        self._CheckDeviceFreeSpace(ret[0])

        # If the root dir is not writable, try disabling rootfs verification.
        # (We always do this by default so that developers can write to
        # /etc/chrome_dev.conf and other directories in the rootfs).
        if self._root_dir_is_still_readonly.is_set():
            if self.options.noremove_rootfs_verification:
                logging.warning("Skipping disable rootfs verification.")
            elif not self._DisableRootfsVerification():
                # A writable rootfs might not be needed if
                # 1) Deploy chrome to stateful partition with mount option.
                # 2) Deploy lacros without modifying /etc/chrome_dev.conf.
                if self.options.mount:
                    logging.warning(
                        "Failed to disable rootfs verification. "
                        "Continue as --mount is set."
                    )
                elif (
                    self.options.lacros and not self.options.modify_config_file
                ):
                    logging.warning(
                        "Failed to disable rootfs verification. "
                        "Continue as --lacros is set and "
                        "--skip-modifying-config-file is unset."
                    )
                else:
                    raise DeployFailure(
                        "Failed to disable rootfs verification."
                    )

            # If the target dir is still not writable (i.e. the user opted out
            # or the command failed), abort.
            if not self.device.IsDirWritable(self.options.target_dir):
                if self.options.startui and self._stopped_ui:
                    logging.info("Restarting Chrome...")
                    self.device.run(["start", "ui"])
                raise DeployFailure(
                    "Target location is not writable. Aborting."
                )

        if self.options.mount_dir is not None:
            self._MountTarget()

        # Actually deploy Chrome to the device.
        self._Deploy()
        if self.options.deploy_test_binaries:
            self._DeployTestBinaries()

    def _ModifyConfigFileIfNeededForLacros(self):
        """Modifies the /etc/chrome_dev.conf file for lacros-chrome.

        Returns:
            True if the file is modified, and the return value is usually used
            to determine whether restarting ash-chrome is needed.
        """
        assert (
            self.options.lacros
        ), "Only deploying lacros-chrome needs to modify the config file."
        # Update /etc/chrome_dev.conf to include appropriate flags.
        modified = False
        if self.options.enable_lacros_support:
            result = self.device.run(ENABLE_LACROS_VIA_CONF_COMMAND, shell=True)
            if result.stdout.strip() == MODIFIED_CONF_FILE:
                modified = True
        result = self.device.run(
            _SET_LACROS_PATH_VIA_CONF_COMMAND
            % {
                "conf_file": _CONF_FILE,
                "lacros_path": self.options.target_dir,
                "modified_conf_file": MODIFIED_CONF_FILE,
            },
            shell=True,
        )
        if result.stdout.strip() == MODIFIED_CONF_FILE:
            modified = True

        return modified


def ValidateStagingFlags(value):
    """Convert formatted string to dictionary."""
    return chrome_util.ProcessShellFlags(value)


def ValidateGnArgs(value):
    """Convert GN_ARGS-formatted string to dictionary."""
    return gn_helpers.FromGNArgs(value)


def _CreateParser():
    """Create our custom parser."""
    parser = commandline.ArgumentParser(description=__doc__, caching=True)

    # TODO(rcui): Have this use the UI-V2 format of having source and target
    # device be specified as positional arguments.
    parser.add_argument(
        "--force",
        action="store_true",
        default=False,
        help="Skip all prompts (such as the prompt for disabling "
        "of rootfs verification).  This may result in the "
        "target machine being rebooted.",
    )
    sdk_board_env = os.environ.get(cros_chrome_sdk.SDKFetcher.SDK_BOARD_ENV)
    parser.add_argument(
        "--board",
        default=sdk_board_env,
        help="The board the Chrome build is targeted for.  When "
        "in a 'cros chrome-sdk' shell, defaults to the SDK "
        "board.",
    )
    parser.add_argument(
        "--build-dir",
        type="str_path",
        help="The directory with Chrome build artifacts to "
        "deploy from. Typically of format "
        "<chrome_root>/out/Debug. When this option is used, "
        "the GN_ARGS environment variable must be set.",
    )
    parser.add_argument(
        "--target-dir",
        type="str_path",
        default=None,
        help="Target directory on device to deploy Chrome into.",
    )
    parser.add_argument(
        "-g",
        "--gs-path",
        type="gs_path",
        help="GS path that contains the chrome to deploy.",
    )
    parser.add_argument(
        "--private-key",
        type="str_path",
        default=None,
        help="An ssh private key to use when deploying to " "a CrOS device.",
    )
    parser.add_argument(
        "--nostartui",
        action="store_false",
        dest="startui",
        default=True,
        help="Don't restart the ui daemon after deployment.",
    )
    parser.add_argument(
        "--unlock-password",
        default=None,
        help="Password to use to unlock after deployment and restart.",
    )
    parser.add_argument(
        "--nostrip",
        action="store_false",
        dest="dostrip",
        default=True,
        help="Don't strip binaries during deployment.  Warning: "
        "the resulting binaries will be very large!",
    )
    parser.add_argument(
        "-d",
        "--device",
        type=commandline.DeviceParser(commandline.DeviceScheme.SSH),
        help="Device hostname or IP in the format hostname[:port].",
    )
    parser.add_argument(
        "--mount-dir",
        type="str_path",
        default=None,
        help="Deploy Chrome in target directory and bind it "
        "to the directory specified by this flag. "
        "Any existing mount on this directory will be "
        "umounted first.",
    )
    parser.add_argument(
        "--mount",
        action="store_true",
        default=False,
        help="Deploy Chrome to default target directory and bind "
        "it to the default mount directory. "
        "Any existing mount on this directory will be "
        "umounted first.",
    )
    parser.add_argument(
        "--noremove-rootfs-verification",
        action="store_true",
        default=False,
        help="Never remove rootfs verification.",
    )
    parser.add_argument(
        "--deploy-test-binaries",
        action="store_true",
        default=False,
        help="Also deploy any test binaries to %s. Useful for "
        "running any Tast tests that execute these "
        "binaries." % _CHROME_TEST_BIN_DIR,
    )
    parser.add_argument(
        "--use-external-config",
        action="store_true",
        help="When identifying the configuration for a board, "
        "force usage of the external configuration if both "
        "internal and external are available. This only "
        "has an effect when stripping Chrome, i.e. when "
        "--nostrip is not passed in.",
    )

    group = parser.add_argument_group("Lacros Options")
    group.add_argument(
        "--lacros",
        action="store_true",
        default=False,
        help="Deploys lacros-chrome rather than ash-chrome.",
    )
    group.add_argument(
        "--reset-lacros",
        action="store_true",
        default=False,
        help="Reset Lacros by deleting Lacros user data dir if it exists.",
    )
    group.add_argument(
        "--skip-restart-ui",
        action="store_true",
        default=False,
        help="Skip restarting ash-chrome on deploying lacros-chrome. Note "
        "that this flag may cause ETXTBSY error on rsync, and also won't "
        "reflect the /etc/chrome_dev.conf file updates as it won't restart.",
    )
    group.add_argument(
        "--skip-enabling-lacros-support",
        action="store_false",
        dest="enable_lacros_support",
        help="By default, deploying lacros-chrome modifies the "
        "/etc/chrome_dev.conf file to (1) enable the LacrosSupport feature "
        "and (2) set the Lacros path, which can interfere with automated "
        "testing. With this flag, part (1) will be skipped. See the "
        "--skip-modifying-config-file flag for skipping both parts.",
    )
    group.add_argument(
        "--skip-modifying-config-file",
        action="store_false",
        dest="modify_config_file",
        help="When deploying lacros-chrome, do not modify the "
        "/etc/chrome_dev.conf file. See also the "
        "--skip-enabling-lacros-support flag.",
    )

    group = parser.add_argument_group("Advanced Options")
    group.add_argument(
        "-l",
        "--local-pkg-path",
        type="str_path",
        help="Path to local chrome prebuilt package to deploy.",
    )
    group.add_argument(
        "--sloppy",
        action="store_true",
        default=False,
        help="Ignore when mandatory artifacts are missing.",
    )
    group.add_argument(
        "--staging-flags",
        default=None,
        type=ValidateStagingFlags,
        help=(
            "Extra flags to control staging.  Valid flags are - "
            "%s" % ", ".join(chrome_util.STAGING_FLAGS)
        ),
    )
    # TODO(stevenjb): Remove --strict entirely once removed from the ebuild.
    group.add_argument(
        "--strict",
        action="store_true",
        default=False,
        help='Deprecated. Default behavior is "strict". Use '
        "--sloppy to omit warnings for missing optional "
        "files.",
    )
    group.add_argument(
        "--strip-flags",
        default=None,
        help="Flags to call the 'strip' binutil tool with.  "
        "Overrides the default arguments.",
    )
    group.add_argument(
        "--ping",
        action="store_true",
        default=False,
        help="Ping the device before connection attempt.",
    )
    group.add_argument(
        "--process-timeout",
        type=int,
        default=KILL_PROC_MAX_WAIT,
        help="Timeout for process shutdown.",
    )

    group = parser.add_argument_group(
        "Metadata Overrides (Advanced)",
        description="Provide all of these overrides in order to remove "
        "dependencies on metadata.json existence.",
    )
    group.add_argument(
        "--target-tc",
        action="store",
        default=None,
        help="Override target toolchain name, e.g. " "x86_64-cros-linux-gnu",
    )
    group.add_argument(
        "--toolchain-url",
        action="store",
        default=None,
        help="Override toolchain url format pattern, e.g. "
        "2014/04/%%(target)s-2014.04.23.220740.tar.xz",
    )

    # DEPRECATED: --gyp-defines is ignored, but retained for backwards
    # compatibility. TODO(stevenjb): Remove once eliminated from the ebuild.
    parser.add_argument(
        "--gyp-defines",
        default=None,
        type=ValidateStagingFlags,
        help=argparse.SUPPRESS,
    )

    # GN_ARGS (args.gn) used to build Chrome. Influences which files are staged
    # when --build-dir is set. Defaults to reading from the GN_ARGS env
    # variable. CURRENTLY IGNORED, ADDED FOR FORWARD COMPATIBILITY.
    parser.add_argument(
        "--gn-args", default=None, type=ValidateGnArgs, help=argparse.SUPPRESS
    )

    # Path of an empty directory to stage chrome artifacts to.  Defaults to a
    # temporary directory that is removed when the script finishes. If the path
    # is specified, then it will not be removed.
    parser.add_argument(
        "--staging-dir", type="str_path", default=None, help=argparse.SUPPRESS
    )
    # Only prepare the staging directory, and skip deploying to the device.
    parser.add_argument(
        "--staging-only",
        action="store_true",
        default=False,
        help=argparse.SUPPRESS,
    )
    # Uploads the compressed staging directory to the given gs:// path URI.
    parser.add_argument(
        "--staging-upload",
        type="gs_path",
        help="GS path to upload the compressed staging files to.",
    )
    # Used alongside --staging-upload to upload with public-read ACL.
    parser.add_argument(
        "--public-read",
        action="store_true",
        default=False,
        help="GS path to upload the compressed staging files to.",
    )
    # Path to a binutil 'strip' tool to strip binaries with.  The passed-in path
    # is used as-is, and not normalized.  Used by the Chrome ebuild to skip
    # fetching the SDK toolchain.
    parser.add_argument("--strip-bin", default=None, help=argparse.SUPPRESS)
    parser.add_argument(
        "--compress",
        action="store",
        default="auto",
        choices=("always", "never", "auto"),
        help="Choose the data transfer compression behavior. Default "
        'is set to "auto", that disables compression if '
        "the target device has a gigabit ethernet port.",
    )
    parser.add_argument(
        "--compressed-ash",
        action="store_true",
        default=False,
        help="Use compressed-ash deployment scheme. With the flag, ash-chrome "
        "binary is stored on DUT in squashfs, mounted upon boot.",
    )
    return parser


def _ParseCommandLine(argv):
    """Parse args, and run environment-independent checks."""
    parser = _CreateParser()
    options = parser.parse_args(argv)

    if not any([options.gs_path, options.local_pkg_path, options.build_dir]):
        parser.error(
            "Need to specify either --gs-path, --local-pkg-path, or "
            "--build-dir"
        )
    if options.build_dir and any([options.gs_path, options.local_pkg_path]):
        parser.error(
            "Cannot specify both --build_dir and " "--gs-path/--local-pkg-patch"
        )
    if options.lacros:
        if options.dostrip and not options.board:
            parser.error("Please specify --board.")
        if options.mount_dir or options.mount:
            parser.error("--lacros does not support --mount or --mount-dir")
        if options.deploy_test_binaries:
            parser.error("--lacros does not support --deploy-test-binaries")
        if options.local_pkg_path:
            parser.error("--lacros does not support --local-pkg-path")
        if options.compressed_ash:
            parser.error("--lacros does not support --compressed-ash")
    else:
        if not options.board and options.build_dir:
            match = re.search(r"out_([^/]+)/Release$", options.build_dir)
            if match:
                options.board = match.group(1)
                logging.info("--board is set to %s", options.board)
        if not options.board:
            parser.error("--board is required")
    if options.gs_path and options.local_pkg_path:
        parser.error("Cannot specify both --gs-path and --local-pkg-path")
    if not (options.staging_only or options.device):
        parser.error("Need to specify --device")
    if options.staging_flags and not options.build_dir:
        parser.error("--staging-flags require --build-dir to be set.")

    if options.strict:
        logging.warning("--strict is deprecated.")
    if options.gyp_defines:
        logging.warning("--gyp-defines is deprecated.")

    if options.mount or options.mount_dir:
        if not options.target_dir:
            options.target_dir = _CHROME_DIR_MOUNT
    else:
        if not options.target_dir:
            options.target_dir = LACROS_DIR if options.lacros else _CHROME_DIR

    if options.mount and not options.mount_dir:
        options.mount_dir = _CHROME_DIR

    return options


def _PostParseCheck(options) -> None:
    """Perform some usage validation (after we've parsed the arguments).

    Args:
        options: The options object returned by the cli parser.
    """
    if options.local_pkg_path and not os.path.isfile(options.local_pkg_path):
        cros_build_lib.Die("%s is not a file.", options.local_pkg_path)

    if not options.gn_args:
        gn_env = os.getenv("GN_ARGS")
        if gn_env is not None:
            options.gn_args = gn_helpers.FromGNArgs(gn_env)
            logging.debug("GN_ARGS taken from environment: %s", options.gn_args)

    if not options.staging_flags:
        use_env = os.getenv("USE")
        if use_env is not None:
            options.staging_flags = " ".join(
                set(use_env.split()).intersection(chrome_util.STAGING_FLAGS)
            )
            logging.info(
                "Staging flags taken from USE in environment: %s",
                options.staging_flags,
            )


def _FetchChromePackage(cache_dir, tempdir, gs_path):
    """Get the chrome prebuilt tarball from GS.

    Returns:
        Path to the fetched chrome tarball.
    """
    gs_ctx = gs.GSContext(cache_dir=cache_dir, init_boto=True)
    files = gs_ctx.LS(gs_path)
    files = [
        found
        for found in files
        if _UrlBaseName(found).startswith("%s-" % constants.CHROME_PN)
    ]
    if not files:
        raise Exception("No chrome package found at %s" % gs_path)
    elif len(files) > 1:
        # - Users should provide us with a direct link to either a stripped or
        #   unstripped chrome package.
        # - In the case of being provided with an archive directory, where both
        #   stripped and unstripped chrome available, use the stripped chrome
        #   package.
        # - Stripped chrome pkg is chromeos-chrome-<version>.tar.gz
        # - Unstripped chrome pkg is
        #   chromeos-chrome-<version>-unstripped.tar.gz.
        files = [f for f in files if not "unstripped" in f]
        assert len(files) == 1
        logging.warning("Multiple chrome packages found.  Using %s", files[0])

    filename = _UrlBaseName(files[0])
    logging.info("Fetching %s...", filename)
    gs_ctx.Copy(files[0], tempdir, print_cmd=False)
    chrome_path = os.path.join(tempdir, filename)
    assert os.path.exists(chrome_path)
    return chrome_path


@contextlib.contextmanager
def _StripBinContext(options):
    if not options.dostrip:
        yield None
    elif options.strip_bin:
        yield options.strip_bin
    else:
        sdk = cros_chrome_sdk.SDKFetcher(
            options.cache_dir,
            options.board,
            use_external_config=options.use_external_config,
        )
        components = (sdk.TARGET_TOOLCHAIN_KEY, constants.CHROME_ENV_TAR)
        with sdk.Prepare(
            components=components,
            target_tc=options.target_tc,
            toolchain_url=options.toolchain_url,
        ) as ctx:
            env_path = os.path.join(
                ctx.key_map[constants.CHROME_ENV_TAR].path,
                constants.CHROME_ENV_FILE,
            )
            strip_bin = osutils.SourceEnvironment(env_path, ["STRIP"])["STRIP"]
            strip_bin = os.path.join(
                ctx.key_map[sdk.TARGET_TOOLCHAIN_KEY].path,
                "bin",
                os.path.basename(strip_bin),
            )
            yield strip_bin


def _UploadStagingDir(
    options: commandline.ArgumentNamespace, tempdir: str, staging_dir: str
) -> None:
    """Uploads the compressed staging directory.

    Args:
        options: options object.
        tempdir: Scratch space.
        staging_dir: Directory staging chrome files.
    """
    staging_tarball_path = os.path.join(
        tempdir, _CHROME_DIR_STAGING_TARBALL_ZSTD
    )
    logging.info(
        "Compressing staging dir (%s) to (%s)",
        staging_dir,
        staging_tarball_path,
    )
    cros_build_lib.CreateTarball(
        staging_tarball_path,
        staging_dir,
        compression=cros_build_lib.CompressionType.ZSTD,
        extra_env={"ZSTD_CLEVEL": "9"},
    )
    logging.info(
        "Uploading staging tarball (%s) into %s",
        staging_tarball_path,
        options.staging_upload,
    )
    ctx = gs.GSContext()
    ctx.Copy(
        staging_tarball_path,
        options.staging_upload,
        acl="public-read" if options.public_read else "",
    )


def _PrepareStagingDir(
    options, tempdir, staging_dir, copy_paths=None, chrome_dir=None
) -> None:
    """Place the necessary files in the staging directory.

    The staging directory is the directory used to rsync the build artifacts
    over to the device.  Only the necessary Chrome build artifacts are put into
    the staging directory.
    """
    if chrome_dir is None:
        chrome_dir = LACROS_DIR if options.lacros else _CHROME_DIR
    osutils.SafeMakedirs(staging_dir)
    os.chmod(staging_dir, 0o755)
    if options.build_dir:
        with _StripBinContext(options) as strip_bin:
            strip_flags = (
                None
                if options.strip_flags is None
                else shlex.split(options.strip_flags)
            )
            chrome_util.StageChromeFromBuildDir(
                staging_dir,
                options.build_dir,
                strip_bin,
                sloppy=options.sloppy,
                gn_args=options.gn_args,
                staging_flags=options.staging_flags,
                strip_flags=strip_flags,
                copy_paths=copy_paths,
            )
    else:
        pkg_path = options.local_pkg_path
        if options.gs_path:
            pkg_path = _FetchChromePackage(
                options.cache_dir, tempdir, options.gs_path
            )

        assert pkg_path
        logging.info("Extracting %s...", pkg_path)
        # Extract only the ./opt/google/chrome contents, directly into the
        # staging dir, collapsing the directory hierarchy.
        if pkg_path[-4:] == ".zip":
            cros_build_lib.dbg_run(
                [
                    "unzip",
                    "-X",
                    pkg_path,
                    _ANDROID_DIR_EXTRACT_PATH,
                    "-d",
                    staging_dir,
                ]
            )
            for filename in glob.glob(
                os.path.join(staging_dir, "system/chrome/*")
            ):
                shutil.move(filename, staging_dir)
            osutils.RmDir(
                os.path.join(staging_dir, "system"), ignore_missing=True
            )
        else:
            compression = cros_build_lib.CompressionDetectType(pkg_path)
            compressor = cros_build_lib.FindCompressor(compression)
            if compression == cros_build_lib.CompressionType.ZSTD:
                compressor += " -f"
            cros_build_lib.dbg_run(
                [
                    "tar",
                    "--strip-components",
                    "4",
                    "--extract",
                    "-I",
                    compressor,
                    "--preserve-permissions",
                    "--file",
                    pkg_path,
                    ".%s" % chrome_dir,
                ],
                cwd=staging_dir,
            )

    if options.compressed_ash:
        # Setup SDK here so mksquashfs is still found in no-shell + nostrip
        # configuration.
        # HACH(b/247397013, dlunev): to not setup release builders for SDK while
        # this is in test, cut the known suffix of experimental overlays.
        sdk_orig_board = options.board
        if sdk_orig_board.endswith(COMPRESSED_ASH_OVERLAY_SUFFIX):
            sdk_orig_board = sdk_orig_board[
                : -len(COMPRESSED_ASH_OVERLAY_SUFFIX)
            ]

        sdk = cros_chrome_sdk.SDKFetcher(
            options.cache_dir,
            sdk_orig_board,
            use_external_config=options.use_external_config,
        )
        with sdk.Prepare(
            components=[],
            target_tc=options.target_tc,
            toolchain_url=options.toolchain_url,
        ):
            cros_build_lib.dbg_run(
                [
                    "mksquashfs",
                    RAW_ASH_FILE,
                    COMPRESSED_ASH_FILE,
                    "-all-root",
                    "-no-progress",
                    "-comp",
                    "zstd",
                ],
                cwd=staging_dir,
            )
        os.truncate(os.path.join(staging_dir, RAW_ASH_FILE), 0)

    if options.staging_upload:
        _UploadStagingDir(options, tempdir, staging_dir)


def main(argv) -> None:
    options = _ParseCommandLine(argv)
    _PostParseCheck(options)

    with osutils.TempDir(set_global=True) as tempdir:
        staging_dir = options.staging_dir
        if not staging_dir:
            staging_dir = os.path.join(tempdir, "chrome")

        deploy = DeployChrome(options, tempdir, staging_dir)
        try:
            deploy.Perform()
        except failures_lib.StepFailure as ex:
            raise SystemExit(str(ex).strip())
        deploy.Cleanup()
