#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tool to automatically generate a new Rust uprev CL.

This tool is intended to automatically generate a CL to uprev Rust to a
newer version in ChromeOS, including creating a new Rust version or
removing an old version. It's based on
src/third_party/chromiumos-overlay/dev-lang/rust/UPGRADE.md. When using
the tool, the progress can be saved to a JSON file, so the user can resume
the process after a failing step is fixed. Example usage to create a new
version:

1. (inside chroot) $ ./rust_tools/rust_uprev.py
                     --state_file /tmp/state-file.json
                     create --rust_version 1.45.0
2. Step "compile rust" failed due to the patches can't apply to new version
3. Manually fix the patches
4. Execute the command in step 1 again.
5. Iterate 1-4 for each failed step until the tool passes.

Replace `create --rust_version 1.45.0` with `remove --rust_version 1.43.0`
if you want to remove all 1.43.0 related stuff in the same CL. Remember to
use a different state file if you choose to run different subcommands.

If you want a hammer that can do everything for you, use the subcommand
`roll`. It can create a Rust uprev CL with `create` and `remove` and upload
the CL to chromium code review.

See `--help` for all available options.
"""

import argparse
import json
import logging
import os
import pathlib
from pathlib import Path
import re
import shutil
import subprocess
import sys
from typing import Any, Callable, Dict, List, NamedTuple, Optional, T, Tuple

from llvm_tools import chroot
from llvm_tools import git


EQUERY = "equery"
GSUTIL = "gsutil.py"
MIRROR_PATH = "gs://chromeos-localmirror/distfiles"
RUST_PATH = Path(
    "/mnt/host/source/src/third_party/chromiumos-overlay/dev-lang/rust"
)


def get_command_output(command: List[str], *args, **kwargs) -> str:
    return subprocess.check_output(
        command, encoding="utf-8", *args, **kwargs
    ).strip()


def get_command_output_unchecked(command: List[str], *args, **kwargs) -> str:
    return subprocess.run(
        command,
        check=False,
        stdout=subprocess.PIPE,
        encoding="utf-8",
        *args,
        **kwargs,
    ).stdout.strip()


class RustVersion(NamedTuple):
    """NamedTuple represents a Rust version"""

    major: int
    minor: int
    patch: int

    def __str__(self):
        return f"{self.major}.{self.minor}.{self.patch}"

    @staticmethod
    def parse_from_ebuild(ebuild_name: str) -> "RustVersion":
        input_re = re.compile(
            r"^rust-"
            r"(?P<major>\d+)\."
            r"(?P<minor>\d+)\."
            r"(?P<patch>\d+)"
            r"(:?-r\d+)?"
            r"\.ebuild$"
        )
        m = input_re.match(ebuild_name)
        assert m, f"failed to parse {ebuild_name!r}"
        return RustVersion(
            int(m.group("major")), int(m.group("minor")), int(m.group("patch"))
        )

    @staticmethod
    def parse(x: str) -> "RustVersion":
        input_re = re.compile(
            r"^(?:rust-)?"
            r"(?P<major>\d+)\."
            r"(?P<minor>\d+)\."
            r"(?P<patch>\d+)"
            r"(?:.ebuild)?$"
        )
        m = input_re.match(x)
        assert m, f"failed to parse {x!r}"
        return RustVersion(
            int(m.group("major")), int(m.group("minor")), int(m.group("patch"))
        )


def compute_rustc_src_name(version: RustVersion) -> str:
    return f"rustc-{version}-src.tar.gz"


def compute_rust_bootstrap_prebuilt_name(version: RustVersion) -> str:
    return f"rust-bootstrap-{version}.tbz2"


def find_ebuild_for_package(name: str) -> os.PathLike:
    """Returns the path to the ebuild for the named package."""
    return get_command_output([EQUERY, "w", name])


def find_ebuild_path(
    directory: Path, name: str, version: Optional[RustVersion] = None
) -> Path:
    """Finds an ebuild in a directory.

    Returns the path to the ebuild file. Asserts if there is not
    exactly one match. The match is constrained by name and optionally
    by version, but can match any patch level. E.g. "rust" version
    1.3.4 can match rust-1.3.4.ebuild but also rust-1.3.4-r6.ebuild.
    """
    if version:
        pattern = f"{name}-{version}*.ebuild"
    else:
        pattern = f"{name}-*.ebuild"
    matches = list(Path(directory).glob(pattern))
    assert len(matches) == 1, matches
    return matches[0]


def get_rust_bootstrap_version():
    """Get the version of the current rust-bootstrap package."""
    bootstrap_ebuild = find_ebuild_path(rust_bootstrap_path(), "rust-bootstrap")
    m = re.match(r"^rust-bootstrap-(\d+).(\d+).(\d+)", bootstrap_ebuild.name)
    assert m, bootstrap_ebuild.name
    return RustVersion(int(m.group(1)), int(m.group(2)), int(m.group(3)))


def parse_commandline_args() -> argparse.Namespace:
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    parser.add_argument(
        "--state_file",
        required=True,
        help="A state file to hold previous completed steps. If the file "
        "exists, it needs to be used together with --continue or --restart. "
        "If not exist (do not use --continue in this case), we will create a "
        "file for you.",
    )
    parser.add_argument(
        "--restart",
        action="store_true",
        help="Restart from the first step. Ignore the completed steps in "
        "the state file",
    )
    parser.add_argument(
        "--continue",
        dest="cont",
        action="store_true",
        help="Continue the steps from the state file",
    )

    create_parser_template = argparse.ArgumentParser(add_help=False)
    create_parser_template.add_argument(
        "--template",
        type=RustVersion.parse,
        default=None,
        help="A template to use for creating a Rust uprev from, in the form "
        "a.b.c The ebuild has to exist in the chroot. If not specified, the "
        "tool will use the current Rust version in the chroot as template.",
    )
    create_parser_template.add_argument(
        "--skip_compile",
        action="store_true",
        help="Skip compiling rust to test the tool. Only for testing",
    )

    subparsers = parser.add_subparsers(dest="subparser_name")
    subparser_names = []
    subparser_names.append("create")
    create_parser = subparsers.add_parser(
        "create",
        parents=[create_parser_template],
        help="Create changes uprevs Rust to a new version",
    )
    create_parser.add_argument(
        "--rust_version",
        type=RustVersion.parse,
        required=True,
        help="Rust version to uprev to, in the form a.b.c",
    )

    subparser_names.append("remove")
    remove_parser = subparsers.add_parser(
        "remove",
        help="Clean up old Rust version from chroot",
    )
    remove_parser.add_argument(
        "--rust_version",
        type=RustVersion.parse,
        default=None,
        help="Rust version to remove, in the form a.b.c If not "
        "specified, the tool will remove the oldest version in the chroot",
    )

    subparser_names.append("remove-bootstrap")
    remove_bootstrap_parser = subparsers.add_parser(
        "remove-bootstrap",
        help="Remove an old rust-bootstrap version",
    )
    remove_bootstrap_parser.add_argument(
        "--version",
        type=RustVersion.parse,
        required=True,
        help="rust-bootstrap version to remove",
    )

    subparser_names.append("roll")
    roll_parser = subparsers.add_parser(
        "roll",
        parents=[create_parser_template],
        help="A command can create and upload a Rust uprev CL, including "
        "preparing the repo, creating new Rust uprev, deleting old uprev, "
        "and upload a CL to crrev.",
    )
    roll_parser.add_argument(
        "--uprev",
        type=RustVersion.parse,
        required=True,
        help="Rust version to uprev to, in the form a.b.c",
    )
    roll_parser.add_argument(
        "--remove",
        type=RustVersion.parse,
        default=None,
        help="Rust version to remove, in the form a.b.c If not "
        "specified, the tool will remove the oldest version in the chroot",
    )
    roll_parser.add_argument(
        "--skip_cross_compiler",
        action="store_true",
        help="Skip updating cross-compiler in the chroot",
    )
    roll_parser.add_argument(
        "--no_upload",
        action="store_true",
        help="If specified, the tool will not upload the CL for review",
    )

    args = parser.parse_args()
    if args.subparser_name not in subparser_names:
        parser.error("one of %s must be specified" % subparser_names)

    if args.cont and args.restart:
        parser.error("Please select either --continue or --restart")

    if os.path.exists(args.state_file):
        if not args.cont and not args.restart:
            parser.error(
                "State file exists, so you should either --continue "
                "or --restart"
            )
    if args.cont and not os.path.exists(args.state_file):
        parser.error("Indicate --continue but the state file does not exist")

    if args.restart and os.path.exists(args.state_file):
        os.remove(args.state_file)

    return args


def prepare_uprev(
    rust_version: RustVersion, template: Optional[RustVersion]
) -> Optional[Tuple[RustVersion, str, RustVersion]]:
    if template is None:
        ebuild_path = find_ebuild_for_package("rust")
        ebuild_name = os.path.basename(ebuild_path)
        template_version = RustVersion.parse_from_ebuild(ebuild_name)
    else:
        ebuild_path = find_ebuild_for_rust_version(template)
        template_version = template

    bootstrap_version = get_rust_bootstrap_version()

    if rust_version <= template_version:
        logging.info(
            "Requested version %s is not newer than the template version %s.",
            rust_version,
            template_version,
        )
        return None

    logging.info(
        "Template Rust version is %s (ebuild: %r)",
        template_version,
        ebuild_path,
    )
    logging.info("rust-bootstrap version is %s", bootstrap_version)

    return template_version, ebuild_path, bootstrap_version


def copy_patches(
    directory: Path, template_version: RustVersion, new_version: RustVersion
) -> None:
    patch_path = directory.joinpath("files")
    prefix = "%s-%s-" % (directory.name, template_version)
    new_prefix = "%s-%s-" % (directory.name, new_version)
    for f in os.listdir(patch_path):
        if not f.startswith(prefix):
            continue
        logging.info("Copy patch %s to new version", f)
        new_name = f.replace(str(template_version), str(new_version))
        shutil.copyfile(
            os.path.join(patch_path, f),
            os.path.join(patch_path, new_name),
        )

    subprocess.check_call(
        ["git", "add", f"{new_prefix}*.patch"], cwd=patch_path
    )


def create_ebuild(template_ebuild: str, new_version: RustVersion) -> str:
    shutil.copyfile(
        template_ebuild, RUST_PATH.joinpath(f"rust-{new_version}.ebuild")
    )
    subprocess.check_call(
        ["git", "add", f"rust-{new_version}.ebuild"], cwd=RUST_PATH
    )
    return os.path.join(RUST_PATH, f"rust-{new_version}.ebuild")


def update_bootstrap_ebuild(new_bootstrap_version: RustVersion) -> None:
    old_ebuild = find_ebuild_path(rust_bootstrap_path(), "rust-bootstrap")
    m = re.match(r"^rust-bootstrap-(\d+).(\d+).(\d+)", old_ebuild.name)
    assert m, old_ebuild.name
    old_version = RustVersion(m.group(1), m.group(2), m.group(3))
    new_ebuild = old_ebuild.parent.joinpath(
        f"rust-bootstrap-{new_bootstrap_version}.ebuild"
    )
    old_text = old_ebuild.read_text(encoding="utf-8")
    new_text, changes = re.subn(
        r"(RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=\([^)]*)",
        f"\\1\t{old_version}\n",
        old_text,
        flags=re.MULTILINE,
    )
    assert changes == 1, "Failed to update RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE"
    new_ebuild.write_text(new_text, encoding="utf-8")


def update_ebuild(ebuild_file: str, new_bootstrap_version: RustVersion) -> None:
    contents = open(ebuild_file, encoding="utf-8").read()
    contents, subs = re.subn(
        r"^BOOTSTRAP_VERSION=.*$",
        'BOOTSTRAP_VERSION="%s"' % (new_bootstrap_version,),
        contents,
        flags=re.MULTILINE,
    )
    if not subs:
        raise RuntimeError("BOOTSTRAP_VERSION not found in rust ebuild")
    open(ebuild_file, "w", encoding="utf-8").write(contents)
    logging.info(
        "Rust ebuild file has BOOTSTRAP_VERSION updated to %s",
        new_bootstrap_version,
    )


def ebuild_actions(
    package: str, actions: List[str], sudo: bool = False
) -> None:
    ebuild_path_inchroot = find_ebuild_for_package(package)
    cmd = ["ebuild", ebuild_path_inchroot] + actions
    if sudo:
        cmd = ["sudo"] + cmd
    subprocess.check_call(cmd)


def fetch_distfile_from_mirror(name: str) -> None:
    """Gets the named file from the local mirror.

    This ensures that the file exists on the mirror, and
    that we can read it. We overwrite any existing distfile
    to ensure the checksums that update_manifest() records
    match the file as it exists on the mirror.

    This function also attempts to verify the ACL for
    the file (which is expected to have READER permission
    for allUsers). We can only see the ACL if the user
    gsutil runs with is the owner of the file. If not,
    we get an access denied error. We also count this
    as a success, because it means we were able to fetch
    the file even though we don't own it.
    """
    mirror_file = MIRROR_PATH + "/" + name
    local_file = Path(get_distdir(), name)
    cmd = [GSUTIL, "cp", mirror_file, local_file]
    logging.info("Running %r", cmd)
    rc = subprocess.call(cmd)
    if rc != 0:
        logging.error(
            """Could not fetch %s

If the file does not yet exist at %s
please download the file, verify its integrity
with something like:

curl -O https://static.rust-lang.org/dist/%s
gpg --verify %s.asc

You may need to import the signing key first, e.g.:

gpg --recv-keys 85AB96E6FA1BE5FE

Once you have verify the integrity of the file, upload
it to the local mirror using gsutil cp.
""",
            mirror_file,
            MIRROR_PATH,
            name,
            name,
        )
        raise Exception(f"Could not fetch {mirror_file}")
    # Check that the ACL allows allUsers READER access.
    # If we get an AccessDeniedAcception here, that also
    # counts as a success, because we were able to fetch
    # the file as a non-owner.
    cmd = [GSUTIL, "acl", "get", mirror_file]
    logging.info("Running %r", cmd)
    output = get_command_output_unchecked(cmd, stderr=subprocess.STDOUT)
    acl_verified = False
    if "AccessDeniedException:" in output:
        acl_verified = True
    else:
        acl = json.loads(output)
        for x in acl:
            if x["entity"] == "allUsers" and x["role"] == "READER":
                acl_verified = True
                break
    if not acl_verified:
        logging.error("Output from acl get:\n%s", output)
        raise Exception("Could not verify that allUsers has READER permission")


def fetch_bootstrap_distfiles(
    old_version: RustVersion, new_version: RustVersion
) -> None:
    """Fetches rust-bootstrap distfiles from the local mirror

    Fetches the distfiles for a rust-bootstrap ebuild to ensure they
    are available on the mirror and the local copies are the same as
    the ones on the mirror.
    """
    fetch_distfile_from_mirror(
        compute_rust_bootstrap_prebuilt_name(old_version)
    )
    fetch_distfile_from_mirror(compute_rustc_src_name(new_version))


def fetch_rust_distfiles(version: RustVersion) -> None:
    """Fetches rust distfiles from the local mirror

    Fetches the distfiles for a rust ebuild to ensure they
    are available on the mirror and the local copies are
    the same as the ones on the mirror.
    """
    fetch_distfile_from_mirror(compute_rustc_src_name(version))


def get_distdir() -> os.PathLike:
    """Returns portage's distdir."""
    return get_command_output(["portageq", "distdir"])


def update_manifest(ebuild_file: os.PathLike) -> None:
    """Updates the MANIFEST for the ebuild at the given path."""
    ebuild = Path(ebuild_file)
    ebuild_actions(ebuild.parent.name, ["manifest"])


def update_rust_packages(rust_version: RustVersion, add: bool) -> None:
    package_file = RUST_PATH.joinpath(
        "../../profiles/targets/chromeos/package.provided"
    )
    with open(package_file, encoding="utf-8") as f:
        contents = f.read()
    if add:
        rust_packages_re = re.compile(r"dev-lang/rust-(\d+\.\d+\.\d+)")
        rust_packages = rust_packages_re.findall(contents)
        # Assume all the rust packages are in alphabetical order, so insert the new
        # version to the place after the last rust_packages
        new_str = f"dev-lang/rust-{rust_version}"
        new_contents = contents.replace(
            rust_packages[-1], f"{rust_packages[-1]}\n{new_str}"
        )
        logging.info("%s has been inserted into package.provided", new_str)
    else:
        old_str = f"dev-lang/rust-{rust_version}\n"
        assert old_str in contents, f"{old_str!r} not found in package.provided"
        new_contents = contents.replace(old_str, "")
        logging.info("%s has been removed from package.provided", old_str)

    with open(package_file, "w", encoding="utf-8") as f:
        f.write(new_contents)


def update_virtual_rust(
    template_version: RustVersion, new_version: RustVersion
) -> None:
    template_ebuild = find_ebuild_path(
        RUST_PATH.joinpath("../../virtual/rust"), "rust", template_version
    )
    virtual_rust_dir = template_ebuild.parent
    new_name = f"rust-{new_version}.ebuild"
    new_ebuild = virtual_rust_dir.joinpath(new_name)
    shutil.copyfile(template_ebuild, new_ebuild)
    subprocess.check_call(["git", "add", new_name], cwd=virtual_rust_dir)


def perform_step(
    state_file: pathlib.Path,
    tmp_state_file: pathlib.Path,
    completed_steps: Dict[str, Any],
    step_name: str,
    step_fn: Callable[[], T],
    result_from_json: Optional[Callable[[Any], T]] = None,
    result_to_json: Optional[Callable[[T], Any]] = None,
) -> T:
    if step_name in completed_steps:
        logging.info("Skipping previously completed step %s", step_name)
        if result_from_json:
            return result_from_json(completed_steps[step_name])
        return completed_steps[step_name]

    logging.info("Running step %s", step_name)
    val = step_fn()
    logging.info("Step %s complete", step_name)
    if result_to_json:
        completed_steps[step_name] = result_to_json(val)
    else:
        completed_steps[step_name] = val

    with tmp_state_file.open("w", encoding="utf-8") as f:
        json.dump(completed_steps, f, indent=4)
    tmp_state_file.rename(state_file)
    return val


def prepare_uprev_from_json(
    obj: Any,
) -> Optional[Tuple[RustVersion, str, RustVersion]]:
    if not obj:
        return None
    version, ebuild_path, bootstrap_version = obj
    return RustVersion(*version), ebuild_path, RustVersion(*bootstrap_version)


def create_rust_uprev(
    rust_version: RustVersion,
    maybe_template_version: Optional[RustVersion],
    skip_compile: bool,
    run_step: Callable[[], T],
) -> None:
    template_version, template_ebuild, old_bootstrap_version = run_step(
        "prepare uprev",
        lambda: prepare_uprev(rust_version, maybe_template_version),
        result_from_json=prepare_uprev_from_json,
    )
    if template_ebuild is None:
        return

    # The fetch steps will fail (on purpose) if the files they check for
    # are not available on the mirror. To make them pass, fetch the
    # required files yourself, verify their checksums, then upload them
    # to the mirror.
    run_step(
        "fetch bootstrap distfiles",
        lambda: fetch_bootstrap_distfiles(
            old_bootstrap_version, template_version
        ),
    )
    run_step("fetch rust distfiles", lambda: fetch_rust_distfiles(rust_version))
    run_step(
        "update bootstrap ebuild",
        lambda: update_bootstrap_ebuild(template_version),
    )
    run_step(
        "update bootstrap manifest",
        lambda: update_manifest(
            rust_bootstrap_path().joinpath(
                f"rust-bootstrap-{template_version}.ebuild"
            )
        ),
    )
    run_step(
        "copy patches",
        lambda: copy_patches(RUST_PATH, template_version, rust_version),
    )
    ebuild_file = run_step(
        "create ebuild", lambda: create_ebuild(template_ebuild, rust_version)
    )
    run_step(
        "update ebuild", lambda: update_ebuild(ebuild_file, template_version)
    )
    run_step(
        "update manifest to add new version",
        lambda: update_manifest(Path(ebuild_file)),
    )
    if not skip_compile:
        run_step(
            "emerge rust",
            lambda: subprocess.check_call(["sudo", "emerge", "dev-lang/rust"]),
        )
    run_step(
        "insert version into rust packages",
        lambda: update_rust_packages(rust_version, add=True),
    )
    run_step(
        "upgrade virtual/rust",
        lambda: update_virtual_rust(template_version, rust_version),
    )


def find_rust_versions_in_chroot() -> List[Tuple[RustVersion, str]]:
    return [
        (RustVersion.parse_from_ebuild(x), os.path.join(RUST_PATH, x))
        for x in os.listdir(RUST_PATH)
        if x.endswith(".ebuild")
    ]


def find_oldest_rust_version_in_chroot() -> Tuple[RustVersion, str]:
    rust_versions = find_rust_versions_in_chroot()
    if len(rust_versions) <= 1:
        raise RuntimeError("Expect to find more than one Rust versions")
    return min(rust_versions)


def find_ebuild_for_rust_version(version: RustVersion) -> str:
    rust_ebuilds = [
        ebuild for x, ebuild in find_rust_versions_in_chroot() if x == version
    ]
    if not rust_ebuilds:
        raise ValueError(f"No Rust ebuilds found matching {version}")
    if len(rust_ebuilds) > 1:
        raise ValueError(
            f"Multiple Rust ebuilds found matching {version}: "
            f"{rust_ebuilds}"
        )
    return rust_ebuilds[0]


def remove_files(filename: str, path: str) -> None:
    subprocess.check_call(["git", "rm", filename], cwd=path)


def remove_rust_bootstrap_version(
    version: RustVersion, run_step: Callable[[], T]
) -> None:
    prefix = f"rust-bootstrap-{version}"
    run_step(
        "remove old bootstrap ebuild",
        lambda: remove_files(f"{prefix}*.ebuild", rust_bootstrap_path()),
    )
    ebuild_file = find_ebuild_for_package("rust-bootstrap")
    run_step(
        "update bootstrap manifest to delete old version",
        lambda: update_manifest(ebuild_file),
    )


def remove_rust_uprev(
    rust_version: Optional[RustVersion], run_step: Callable[[], T]
) -> None:
    def find_desired_rust_version():
        if rust_version:
            return rust_version, find_ebuild_for_rust_version(rust_version)
        return find_oldest_rust_version_in_chroot()

    def find_desired_rust_version_from_json(
        obj: Any,
    ) -> Tuple[RustVersion, str]:
        version, ebuild_path = obj
        return RustVersion(*version), ebuild_path

    delete_version, delete_ebuild = run_step(
        "find rust version to delete",
        find_desired_rust_version,
        result_from_json=find_desired_rust_version_from_json,
    )
    run_step(
        "remove patches",
        lambda: remove_files(f"files/rust-{delete_version}-*.patch", RUST_PATH),
    )
    run_step("remove ebuild", lambda: remove_files(delete_ebuild, RUST_PATH))
    ebuild_file = find_ebuild_for_package("rust")
    run_step(
        "update manifest to delete old version",
        lambda: update_manifest(ebuild_file),
    )
    run_step(
        "remove version from rust packages",
        lambda: update_rust_packages(delete_version, add=False),
    )
    run_step("remove virtual/rust", lambda: remove_virtual_rust(delete_version))


def remove_virtual_rust(delete_version: RustVersion) -> None:
    ebuild = find_ebuild_path(
        RUST_PATH.joinpath("../../virtual/rust"), "rust", delete_version
    )
    subprocess.check_call(["git", "rm", str(ebuild.name)], cwd=ebuild.parent)


def rust_bootstrap_path() -> Path:
    return RUST_PATH.joinpath("../rust-bootstrap")


def create_new_repo(rust_version: RustVersion) -> None:
    output = get_command_output(["git", "status", "--porcelain"], cwd=RUST_PATH)
    if output:
        raise RuntimeError(
            f"{RUST_PATH} has uncommitted changes, please either discard them "
            "or commit them."
        )
    git.CreateBranch(RUST_PATH, f"rust-to-{rust_version}")


def build_cross_compiler() -> None:
    # Get target triples in ebuild
    rust_ebuild = find_ebuild_for_package("rust")
    with open(rust_ebuild, encoding="utf-8") as f:
        contents = f.read()

    target_triples_re = re.compile(r"RUSTC_TARGET_TRIPLES=\(([^)]+)\)")
    m = target_triples_re.search(contents)
    assert m, "RUST_TARGET_TRIPLES not found in rust ebuild"
    target_triples = m.group(1).strip().split("\n")

    compiler_targets_to_install = [
        target.strip() for target in target_triples if "cros-" in target
    ]
    for target in target_triples:
        if "cros-" not in target:
            continue
        target = target.strip()

    # We also always need arm-none-eabi, though it's not mentioned in
    # RUSTC_TARGET_TRIPLES.
    compiler_targets_to_install.append("arm-none-eabi")

    logging.info("Emerging cross compilers %s", compiler_targets_to_install)
    subprocess.check_call(
        ["sudo", "emerge", "-j", "-G"]
        + [f"cross-{target}/gcc" for target in compiler_targets_to_install]
    )


def create_new_commit(rust_version: RustVersion) -> None:
    subprocess.check_call(["git", "add", "-A"], cwd=RUST_PATH)
    messages = [
        f"[DO NOT SUBMIT] dev-lang/rust: upgrade to Rust {rust_version}",
        "",
        "This CL is created by rust_uprev tool automatically." "",
        "BUG=None",
        "TEST=Use CQ to test the new Rust version",
    ]
    git.UploadChanges(RUST_PATH, f"rust-to-{rust_version}", messages)


def main() -> None:
    if not chroot.InChroot():
        raise RuntimeError("This script must be executed inside chroot")

    logging.basicConfig(level=logging.INFO)

    args = parse_commandline_args()

    state_file = pathlib.Path(args.state_file)
    tmp_state_file = state_file.with_suffix(".tmp")

    try:
        with state_file.open(encoding="utf-8") as f:
            completed_steps = json.load(f)
    except FileNotFoundError:
        completed_steps = {}

    def run_step(
        step_name: str,
        step_fn: Callable[[], T],
        result_from_json: Optional[Callable[[Any], T]] = None,
        result_to_json: Optional[Callable[[T], Any]] = None,
    ) -> T:
        return perform_step(
            state_file,
            tmp_state_file,
            completed_steps,
            step_name,
            step_fn,
            result_from_json,
            result_to_json,
        )

    if args.subparser_name == "create":
        create_rust_uprev(
            args.rust_version, args.template, args.skip_compile, run_step
        )
    elif args.subparser_name == "remove":
        remove_rust_uprev(args.rust_version, run_step)
    elif args.subparser_name == "remove-bootstrap":
        remove_rust_bootstrap_version(args.version, run_step)
    else:
        # If you have added more subparser_name, please also add the handlers above
        assert args.subparser_name == "roll"
        run_step("create new repo", lambda: create_new_repo(args.uprev))
        if not args.skip_cross_compiler:
            run_step("build cross compiler", build_cross_compiler)
        create_rust_uprev(
            args.uprev, args.template, args.skip_compile, run_step
        )
        remove_rust_uprev(args.remove, run_step)
        bootstrap_version = prepare_uprev_from_json(
            completed_steps["prepare uprev"]
        )[2]
        remove_rust_bootstrap_version(bootstrap_version, run_step)
        if not args.no_upload:
            run_step(
                "create rust uprev CL", lambda: create_new_commit(args.uprev)
            )


if __name__ == "__main__":
    sys.exit(main())
