# -*- coding: utf-8 -*-
# Copyright 2018 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Command for managing branches of chromiumos.

See go/cros-release-faq for information on types of branches, branching
frequency, naming conventions, etc.
"""

from __future__ import print_function

import collections
import os
import re
import sys

from chromite.cbuildbot import manifest_version
from chromite.cli import command
from chromite.lib import cros_logging as logging
from chromite.lib import config_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import git
from chromite.lib import osutils
from chromite.lib import repo_manifest
from chromite.lib import repo_util
from chromite.lib import retry_util


assert sys.version_info >= (3, 6), 'This module requires Python 3.6+'


# A ProjectBranch is, simply, a git branch on a project.
#
# Fields:
#  - project: The repo_manifest.Project associated with the git branch.
#  - branch: The name of the git branch.
ProjectBranch = collections.namedtuple('ProjectBranch', ['project', 'branch'])


class BranchError(Exception):
  """Raised whenever any branch operation fails."""


def BranchMode(project):
  """Returns the project's explicit branch mode, if specified."""
  return project.Annotations().get('branch-mode', None)


def CanBranchProject(project):
  """Returns true if the project can be branched.

  The preferred way to specify branchability is by adding a "branch-mode"
  annotation on the project in the manifest. Of course, only one project
  in the manifest actually does this.

  The legacy method is to peek at the project's remote.

  Args:
    project: The repo_manifest.Project in question.

  Returns:
    True if the project is not pinned or ToT.
  """
  site_params = config_lib.GetSiteParams()
  remote = project.Remote().GitName()
  explicit_mode = BranchMode(project)
  if not explicit_mode:
    return (remote in site_params.CROS_REMOTES and
            remote in site_params.BRANCHABLE_PROJECTS and
            re.match(site_params.BRANCHABLE_PROJECTS[remote], project.name))
  return explicit_mode == constants.MANIFEST_ATTR_BRANCHING_CREATE


def CanPinProject(project):
  """Returns true if the project can be pinned.

  Args:
    project: The repo_manifest.Project in question.

  Returns:
    True if the project is pinned.
  """
  explicit_mode = BranchMode(project)
  if not explicit_mode:
    return not CanBranchProject(project)
  return explicit_mode == constants.MANIFEST_ATTR_BRANCHING_PIN


class ManifestRepository(object):
  """Represents a git repository of manifest XML files."""

  def __init__(self, checkout, project):
    self._checkout = checkout
    self._project = project

  def _AbsoluteManifestPath(self, path):
    """Returns the full path to the manifest.

    Args:
      path: Relative path to the manifest.

    Returns:
      Full path to the manifest.
    """
    return self._checkout.AbsoluteProjectPath(self._project, path)

  def _ReadManifest(self, path):
    """Read the manifest at the given path.

    Args:
      path: Path to the manifest.

    Returns:
      repo_manifest.Manifest object.
    """
    return repo_manifest.Manifest.FromFile(
        path, allow_unsupported_features=True)

  def _ListManifests(self, root_manifests):
    """Finds all manifests included directly or indirectly by root manifests.

    For convenience, the returned set includes the root manifests. If any
    manifest is not found on disk, it is ignored.

    Args:
      root_manifests: Names of manifests whose includes will be traversed.

    Returns:
      Set of paths to included manifests.
    """
    pending = list(root_manifests)
    found = set()
    while pending:
      path = self._AbsoluteManifestPath(pending.pop())
      if path in found or not os.path.exists(path):
        continue
      found.add(path)
      manifest = self._ReadManifest(path)
      pending.extend([inc.name for inc in manifest.Includes()])
    return found

  def RepairManifest(self, path, branches_by_path):
    """Reads the manifest at the given path and repairs it in memory.

    Because humans rarely read branched manifests, this function optimizes for
    code readability and explicitly sets revision on every project in the
    manifest, deleting any defaults.

    Args:
      path: Path to the manifest, relative to the manifest project root.
      branches_by_path: Dict mapping project paths to branch names.

    Returns:
      The repaired repo_manifest.Manifest object.
    """
    manifest = self._ReadManifest(path)

    # Delete the default revision if specified by original manifest.
    default = manifest.Default()
    if default.revision:
      del default.revision

    # Delete remote revisions if specified by original manifest.
    for remote in manifest.Remotes():
      if remote.revision:
        del remote.revision

    # Update all project revisions. Note we cannot call CanBranchProject and
    # related functions because they read the project remote, which may not
    # be defined in the current manifest file.
    for project in manifest.Projects():
      self._checkout.EnsureProject(project)
      path = project.Path()

      # If project path is in the dict, the project must've been branched
      if path in branches_by_path:
        project.revision = git.NormalizeRef(branches_by_path[path])

      # Otherwise, check if project is explicitly TOT.
      elif BranchMode(project) == constants.MANIFEST_ATTR_BRANCHING_TOT:
        project.revision = git.NormalizeRef('master')

      # If not, it's pinned.
      else:
        project.revision = self._checkout.GitRevision(project)

      if project.upstream:
        del project.upstream

    return manifest

  def RepairManifestsOnDisk(self, branches):
    """Repairs the revision and upstream attributes of manifest elements.

    The original manifests are overwritten by the repaired manifests.
    Note this method is "deep" because it processes includes.

    Args:
      branches: List a ProjectBranches for each branched project.
    """
    logging.notice('Repairing manifest project %s.', self._project.name)
    manifest_paths = self._ListManifests(
        [constants.DEFAULT_MANIFEST, constants.OFFICIAL_MANIFEST])
    branches_by_path = {project.Path(): branch for project, branch in branches}
    for manifest_path in manifest_paths:
      logging.notice('Repairing manifest file %s', manifest_path)
      manifest = self.RepairManifest(manifest_path, branches_by_path)
      manifest.Write(manifest_path)


class CrosCheckout(object):
  """Represents a checkout of chromiumos on disk."""

  def __init__(self,
               root,
               manifest=None,
               manifest_url=None,
               repo_url=None,
               groups=None):
    """Read the checkout manifest.

    Args:
      root: The repo root.
      manifest: The checkout manifest. Read from `repo manifest` if None.
      manifest_url: Manifest repository URL. repo_sync_manifest sets default.
      repo_url: Repo repository URL. repo_sync_manifest sets default.
      groups: Repo groups to sync.
    """
    self.root = root
    self.manifest = manifest or repo_util.Repository(root).Manifest()
    self.manifest_url = manifest_url
    self.repo_url = repo_url
    self.groups = groups

  @staticmethod
  def TempRoot():
    """Returns an osutils.TempDir for a checkout. Not inlined for testing."""
    return osutils.TempDir(prefix='cros-branch-')

  @classmethod
  def Initialize(cls,
                 root,
                 manifest_url,
                 repo_url=None,
                 repo_branch=None,
                 groups=None):
    """Initialize the checkout if necessary. Otherwise a no-op.

    Args:
      root: The repo root.
      manifest_url: Manifest repository URL.
      repo_url: Repo repository URL. Uses default googlesource repo if None.
      repo_branch: Repo repository branch.
      groups: Repo groups to sync.
    """
    osutils.SafeMakedirs(root)
    if git.FindRepoCheckoutRoot(root) is None:
      logging.notice('Will initialize checkout %s for this run.', root)
      repo_util.Repository.Initialize(
          root, manifest_url,
          repo_url=repo_url,
          repo_branch=repo_branch,
          groups=groups)
    else:
      logging.notice('Will use existing checkout %s for this run.', root)
    return cls(
        root, manifest_url=manifest_url, repo_url=repo_url, groups=groups)

  def _Sync(self, manifest_args):
    """Run repo_sync_manifest command.

    Args:
      manifest_args: List of args for manifest group of repo_sync_manifest.
    """
    cmd = [
        os.path.join(constants.CHROMITE_DIR, 'scripts/repo_sync_manifest'),
        '--repo-root', self.root
    ] + manifest_args
    if self.repo_url:
      cmd += ['--repo-url', self.repo_url]
    if self.manifest_url:
      cmd += ['--manifest-url', self.manifest_url]
    if self.groups:
      cmd += ['--groups', self.groups]

    cros_build_lib.run(cmd, print_cmd=True)
    self.manifest = repo_util.Repository(self.root).Manifest()

  def SyncBranch(self, branch):
    """Sync to the given branch.

    Args:
      branch: Name of branch to sync to.
    """
    logging.notice('Syncing checkout %s to branch %s.', self.root, branch)
    self._Sync(['--branch', branch])

  def SyncVersion(self, version):
    """Sync to the given manifest version.

    Args:
      version: Version string to sync to.
    """
    logging.notice('Syncing checkout %s to version %s.', self.root, version)
    site_params = config_lib.GetSiteParams()
    self._Sync([
        '--manifest-versions-int',
        self.AbsolutePath(site_params.INTERNAL_MANIFEST_VERSIONS_PATH),
        '--manifest-versions-ext',
        self.AbsolutePath(site_params.EXTERNAL_MANIFEST_VERSIONS_PATH),
        '--version', version
    ])

  def SyncFile(self, path):
    """Sync to the given manifest file.

    Args:
      path: Path to the manifest file.
    """
    logging.notice('Syncing checkout %s to manifest %s.', self.root, path)
    # SyncFile uses repo sync instead of repo_sync_manifest because
    # repo_sync_manifest sometimes corrupts .repo/manifest.xml when
    # syncing to a file. See crbug.com/973106.
    cmd = ['repo', 'sync', '--manifest-name', os.path.abspath(path)]
    cros_build_lib.run(cmd, cwd=self.root, print_cmd=True)
    self.manifest = repo_util.Repository(self.root).Manifest()

  def ReadVersion(self, **kwargs):
    """Returns VersionInfo for the current checkout."""
    return manifest_version.VersionInfo.from_repo(self.root, **kwargs)

  def BumpVersion(self, which, branch, message, dry_run=True, fetch=False):
    """Increment version in chromeos_version.sh and commit it.

    Args:
      which: Which version should be incremented. One of
          'chrome_branch', 'build', 'branch, 'patch'.
      branch: The branch to push to.
      message: The commit message for the version bump.
      dry_run: Whether to use git --dry-run.
      fetch: Whether to fetch and checkout to the given branch.
    """
    logging.notice(message)

    chromiumos_overlay = self.manifest.GetUniqueProject(
        'chromiumos/overlays/chromiumos-overlay')
    remote = chromiumos_overlay.Remote().GitName()
    ref = git.NormalizeRef(branch)

    if fetch:
      self.RunGit(chromiumos_overlay, ['fetch', remote, ref])
      self.RunGit(chromiumos_overlay, ['checkout', '-B', branch, 'FETCH_HEAD'])

    new_version = self.ReadVersion(incr_type=which)
    new_version.IncrementVersion()
    remote_ref = git.RemoteRef(remote, ref)
    new_version.UpdateVersionFile(message, dry_run=dry_run, push_to=remote_ref)

  def EnsureProject(self, project):
    """Checks that the project exists in the checkout.

    Args:
      project: The repo_manifest.Project in question.

    Raises:
      BranchError if project does not exist in checkout.
    """
    path = self.AbsoluteProjectPath(project)
    if not os.path.exists(path):
      raise BranchError(
          'Project %s does not exist at path %s in checkout. '
          'This likely means that manifest-internal is out of sync '
          'with manifest, and the manifest file you are branching from '
          'is corrupted.' % (project.name, path))

  def AbsolutePath(self, *args):
    """Joins the path components with the repo root.

    Args:
      *paths: Arbitrary relative path components, e.g. 'chromite/'

    Returns:
      The absolute checkout path.
    """
    return os.path.join(self.root, *args)

  def AbsoluteProjectPath(self, project, *args):
    """Joins the path components to the project's root.

    Args:
      project: The repo_manifest.Project in question.
      *args: Arbitrary relative path components.

    Returns:
      The joined project path.
    """
    return self.AbsolutePath(project.Path(), *args)

  def RunGit(self, project, cmd, retries=3):
    """Run a git command inside the given project.

    Args:
      project: repo_manifest.Project to run the command in.
      cmd: Command as a list of arguments. Callers should exclude 'git'.
      retries: Maximum number of retries for the git command.
    """
    retry_util.RetryCommand(
        git.RunGit,
        retries,
        self.AbsoluteProjectPath(project),
        cmd,
        print_cmd=True,
        sleep=2,
        log_retries=True)

  def GitBranch(self, project):
    """Returns the project's current branch on disk.

    Args:
      project: The repo_manifest.Project in question.
    """
    return git.GetCurrentBranch(self.AbsoluteProjectPath(project))

  def GitRevision(self, project):
    """Return the project's current git revision on disk.

    Args:
      project: The repo_manifest.Project in question.

    Returns:
      Git revision as a string.
    """
    return git.GetGitRepoRevision(self.AbsoluteProjectPath(project))

  def BranchExists(self, project, pattern):
    """Determines if any branch exists that matches the given pattern.

    Args:
      project: The repo_manifest.Project in question.
      pattern: Branch name pattern to search for.

    Returns:
      True if a matching branch exists on the remote.
    """
    matches = git.MatchBranchName(self.AbsoluteProjectPath(project), pattern)
    return len(matches) != 0


class Branch(object):
  """Represents a branch of chromiumos, which may or may not exist yet.

  Note that all local branch operations assume the current checkout is
  synced to the correct version.
  """

  def __init__(self, checkout, name):
    """Cache various configuration used by all branch operations.

    Args:
      checkout: The synced CrosCheckout.
      name: The name of the branch.
    """
    self.checkout = checkout
    self.name = name

  def _ProjectBranchName(self, branch, project, original=None):
    """Determine's the git branch name for the project.

    Args:
      branch: The base branch name.
      project: The repo_manfest.Project in question.
      original: Original branch name to remove from the branch suffix.

    Returns:
      The branch name for the project.
    """
    # If project has only one checkout, the base branch name is fine.
    checkouts = [p.name for p in self.checkout.manifest.Projects()]
    if checkouts.count(project.name) == 1:
      return branch

    # Otherwise, the project branch name needs a suffix. We append its
    # upstream or revision to distinguish it from other checkouts.
    suffix = '-' + git.StripRefs(project.upstream or project.Revision())

    # If the revision is itself a branch, we need to strip the old branch name
    # from the suffix to keep naming consistent.
    if original:
      suffix = re.sub('^-%s-' % original, '-', suffix)
    else:
      # If the suffix already has a version in it, trim that.
      # e.g. -release-R77-12371.B-wpa_supplicant-2.6 --> -wpa_supplicant-2.6
      suffix = re.sub('^-.*[.]B', '', suffix)
    return branch + suffix

  def _ProjectBranches(self, branch, original=None):
    """Return a list of ProjectBranches: one for each branchable project.

    Args:
      branch: The base branch name.
      original: Branch from which this branch of chromiumos stems, if any.
    """
    return [
        ProjectBranch(proj, self._ProjectBranchName(branch, proj, original))
        for proj in self.checkout.manifest.Projects()
        if CanBranchProject(proj)
    ]

  def _ValidateBranches(self, branches):
    """Validates that branches do not already exist.

    Args:
      branches: Collection of ProjectBranch objects to valdiate.

    Raises:
      BranchError if any branch exists.
    """
    logging.notice('Validating branch does not already exist.')
    for project, branch in branches:
      if self.checkout.BranchExists(project, branch):
        raise BranchError(
            'Branch %s exists for %s. '
            'Please rerun with --force to proceed.' % (branch, project.name))

  def _RepairManifestRepositories(self, branches):
    """Repair all manifests in all manifest repositories on current branch.

    Args:
      branches: List of ProjectBranches describing the repairs needed.
    """
    for project_name in config_lib.GetSiteParams().MANIFEST_PROJECTS:
      manifest_project = self.checkout.manifest.GetUniqueProject(project_name)
      manifest_repo = ManifestRepository(self.checkout, manifest_project)
      manifest_repo.RepairManifestsOnDisk(branches)
      self.checkout.RunGit(
          manifest_project,
          ['commit', '-a', '-m',
           'Manifests point to branch %s.' % self.name])

  def _WhichVersionShouldBump(self):
    """Returns which version is incremented by builds on a new branch."""
    vinfo = self.checkout.ReadVersion()
    assert not int(vinfo.patch_number)
    return 'patch' if int(vinfo.branch_build_number) else 'branch'

  def _PushBranchesToRemote(self, branches, dry_run=True, force=False):
    """Push state of local git branches to remote.

    Args:
      branches: List of ProjectBranches to push.
      force: Whether or not to overwrite existing branches on the remote.
      dry_run: Whether or not to set --dry-run.
    """
    logging.notice('Pushing branches to remote (%s --dry-run).',
                   'with' if dry_run else 'without')
    for project, branch in branches:
      branch = git.NormalizeRef(branch)

      # The refspec should look like 'HEAD:refs/heads/branch'.
      refspec = 'HEAD:%s' % branch
      remote = project.Remote().GitName()

      cmd = ['push', remote, refspec]
      if dry_run:
        cmd.append('--dry-run')
      if force:
        cmd.append('--force')

      self.checkout.RunGit(project, cmd)

  def _DeleteBranchesOnRemote(self, branches, dry_run=True):
    """Push deletions of this branch for all projects.

    Args:
      branches: List of ProjectBranches for which to push delete.
      dry_run: Whether or not to set --dry-run.
    """
    logging.notice('Deleting old branches on remote (%s --dry-run).',
                   'with' if dry_run else 'without')
    for project, branch in branches:
      branch = git.NormalizeRef(branch)
      cmd = ['push', project.Remote().GitName(), '--delete', branch]
      if dry_run:
        cmd.append('--dry-run')
      self.checkout.RunGit(project, cmd)

  def Create(self, push=False, force=False):
    """Creates a new branch from the given version.

    Branches are always created locally, even when push is true.

    Args:
      push: Whether to push the new branch to remote.
      force: Whether or not to overwrite an existing branch.
    """
    branches = self._ProjectBranches(self.name)

    if not force:
      self._ValidateBranches(branches)

    self._RepairManifestRepositories(branches)
    self._PushBranchesToRemote(branches, dry_run=not push, force=force)

    # Must bump version last because of how VersionInfo is implemented. Sigh...
    which_version = self._WhichVersionShouldBump()
    self.checkout.BumpVersion(
        which_version,
        self.name,
        'Bump %s number after creating branch %s.' % (which_version, self.name),
        dry_run=not push)
    # Increment branch/build number for source 'master' branch.
    # manifest_version already does this for release branches.
    # TODO(@jackneus): Make this less of a hack.
    # In reality, this whole tool is being deleted pretty soon.
    if self.__class__.__name__ != 'ReleaseBranch':
      source_version = 'branch' if which_version == 'patch' else 'build'
      # Use the default node's revision if it exists. We stopped writing this
      # for new branches in 2019 though, so this won't be true for newer
      # branches.
      source_ref = self.checkout.manifest.Default().revision
      if not source_ref:
        # Otherwise, use the source version's upstream,
        # e.g. refs/heads/release-R77-12371.B
        source_ref = self.checkout.manifest.GetUniqueProject(
            'chromeos/manifest-internal').upstream
      self.checkout.BumpVersion(
          source_version,
          git.StripRefs(source_ref),
          'Bump %s number for source branch after creating branch %s' %
          (source_version, self.name),
          dry_run=not push)

  def Rename(self, original, push=False, force=False):
    """Create this branch by renaming some other branch.

    There is no way to atomically rename a remote branch. Therefore, this
    method creates a new branch and then deletes the original.

    Args:
      original: Name of the original branch.
      push: Whether to push changes to remote.
      force: Whether or not to overwrite an existing branch.
    """
    new_branches = self._ProjectBranches(self.name, original=original)

    if not force:
      self._ValidateBranches(new_branches)

    self._RepairManifestRepositories(new_branches)
    self._PushBranchesToRemote(new_branches, dry_run=not push, force=force)

    old_branches = self._ProjectBranches(original, original=original)
    self._DeleteBranchesOnRemote(old_branches, dry_run=not push)

  def Delete(self, push=False, force=False):
    """Delete this branch.

    Args:
      push: Whether to push the deletion to remote.
      force: Are you *really* sure you want to delete this branch on remote?
    """
    if push and not force:
      raise BranchError('Must set --force to delete remote branches.')
    branches = self._ProjectBranches(self.name, original=self.name)
    self._DeleteBranchesOnRemote(branches, dry_run=not push)


class StandardBranch(Branch):
  """Branch with a standard name, meaning it is suffixed by version."""

  def __init__(self, checkout, *args):
    """Determine the name for this branch.

    By convention, standard branch names must end with the major version from
    which they were created, followed by '.B'.

    For example:
      - A branch created from 1.0.0 must end with -1.B
      - A branch created from 1.2.0 must end with -1-2.B

    Args:
      checkout: The synced CrosCheckout.
      *args: Additional name components, which will be joined by dashes.
    """
    vinfo = checkout.ReadVersion()
    version = '.'.join(str(comp) for comp in vinfo.VersionComponents() if comp)
    name = '-'.join([x for x in args if x] + [version]) + '.B'
    super(StandardBranch, self).__init__(checkout, name)


class ReleaseBranch(StandardBranch):
  """Represents a release branch.

  Release branches have a slightly different naming scheme. They include
  the milestone from which they were created. Example: release-R12-1.2.B.

  Additionally, creating a release branches requires updating the milestone
  (Chrome branch) in chromeos_version.sh on master.
  """

  def __init__(self, checkout, descriptor=None):
    super(ReleaseBranch, self).__init__(
        checkout, 'release', descriptor,
        'R%s' % checkout.ReadVersion().chrome_branch)

  def Create(self, push=False, force=False):
    super(ReleaseBranch, self).Create(push=push, force=force)
    # When a release branch has been successfully created, we report it by
    # bumping the milestone on the master. Note this also bumps build number
    # as a workaround for crbug.com/213075
    self.checkout.BumpVersion(
        'chrome_branch',
        'master',
        'Bump milestone after creating release branch %s.' % self.name,
        dry_run=not push,
        fetch=True)


class FactoryBranch(StandardBranch):
  """Represents a factory branch."""

  def __init__(self, checkout, descriptor=None):
    super(FactoryBranch, self).__init__(checkout, 'factory', descriptor)


class FirmwareBranch(StandardBranch):
  """Represents a firmware branch."""

  def __init__(self, checkout, descriptor=None):
    super(FirmwareBranch, self).__init__(checkout, 'firmware', descriptor)


class StabilizeBranch(StandardBranch):
  """Represents a minibranch."""

  def __init__(self, checkout, descriptor=None):
    super(StabilizeBranch, self).__init__(checkout, 'stabilize', descriptor)


@command.CommandDecorator('branch')
class BranchCommand(command.CliCommand):
  """Create, delete, or rename a branch of chromiumos.

  For details on what this tool does, see go/cros-branch.

  Performing any of these operations remotely requires special permissions.
  Please see go/cros-release-faq for details on obtaining those permissions.
  """

  EPILOG = """
Create example: firmware branch 'firmware-nocturne-11030.B'
  cros branch --push create --descriptor nocturne --version 11030.0.0 --firmware

Create example: release branch 'release-R70-11030.B'
  cros branch --push create --version 11030.0.0 --release

Create example: custom branch 'my-branch'
  cros branch --push create --version 11030.0.0 --custom my-branch

Create example: minibranch dry-run 'stabilize-test-11030.B'
  cros branch create --version 11030.0.0 --descriptor test --stabilize

Rename Examples:
  cros branch rename release-R70-10509.B release-R70-10508.B
  cros branch --push rename release-R70-10509.B release-R70-10508.B

Delete Examples:
  cros branch delete release-R70-10509.B
  cros branch --force --push delete release-R70-10509.B
"""

  @classmethod
  def AddParser(cls, parser):
    """Add parser arguments."""
    super(BranchCommand, cls).AddParser(parser)

    # Common flags.
    remote_group = parser.add_argument_group(
        'Remote options',
        description='Arguments determine how branch operations interact with '
        'remote repositories.')
    remote_group.add_argument(
        '--push',
        action='store_true',
        help='Push branch modifications to remote repos. '
        'Before setting this flag, ensure that you have the proper '
        'permissions and that you know what you are doing. Ye be warned.')
    remote_group.add_argument(
        '--force',
        action='store_true',
        help='Required for any remote operation that would delete an existing '
        'branch. Also required when trying to branch from a previously '
        'branched manifest version.')

    sync_group = parser.add_argument_group(
        'Sync options',
        description='Arguments relating to how the checkout is synced. '
        'These options are primarily used for testing.')
    sync_group.add_argument(
        '--root',
        help='Repo root of local checkout to branch. If the root does not '
        'exist, this tool will create it. If the root is not initialized, '
        'this tool will initialize it. If --root is not specificed, this '
        'tool will branch a fresh checkout in a temporary directory.')
    sync_group.add_argument(
        '--repo-url',
        help='Repo repository location. Defaults to repo '
        'googlesource URL.')
    sync_group.add_argument('--repo-branch', help='Branch to checkout repo to.')
    sync_group.add_argument(
        '--manifest-url',
        default='https://chrome-internal.googlesource.com'
        '/chromeos/manifest-internal.git',
        help='URL of the manifest to be checked out. Defaults to googlesource '
        'URL for manifest-internal.')
    sync_group.add_argument(
        '--groups', help='repo groups to sync.', default='all')

    # Create subcommand and flags.
    subparser = parser.add_subparsers(dest='subcommand')
    create_parser = subparser.add_parser('create', help='Create a branch.')

    name_group = create_parser.add_argument_group(
        'Name options', description='Arguments for determining branch name.')
    name_group.add_argument(
        '--descriptor',
        help='Optional descriptor for this branch. Typically, this is a build '
        'target or a device, depending on the nature of the branch. Used '
        'to generate the branch name. Cannot be used with --custom.')
    name_group.add_argument(
        '--yes',
        dest='yes',
        action='store_true',
        help='If set, disables the boolean prompt confirming the branch name.')

    manifest_group = create_parser.add_argument_group(
        'Manifest options', description='Which manifest should be branched?')
    manifest_ex_group = manifest_group.add_mutually_exclusive_group(
        required=True)
    manifest_ex_group.add_argument(
        '--version',
        help="Manifest version to branch off, e.g. '10509.0.0'."
        'You may not branch off of the same version twice unless you run '
        'with --force.')
    manifest_ex_group.add_argument(
        '--file', help='Path to manifest file to branch off.')

    kind_group = create_parser.add_argument_group(
        'Kind options',
        description='What kind of branch is this? '
        'These flags affect how manifest metadata is updated and '
        'how the branch is named.')
    kind_ex_group = kind_group.add_mutually_exclusive_group(required=True)
    kind_ex_group.add_argument(
        '--release',
        dest='cls',
        action='store_const',
        const=ReleaseBranch,
        help='The new branch is a release branch. '
        "Named as 'release-<descriptor>-R<Milestone>-<Major Version>.B'.")
    kind_ex_group.add_argument(
        '--factory',
        dest='cls',
        action='store_const',
        const=FactoryBranch,
        help='The new branch is a factory branch. '
        "Named as 'factory-<Descriptor>-<Major Version>.B'.")
    kind_ex_group.add_argument(
        '--firmware',
        dest='cls',
        action='store_const',
        const=FirmwareBranch,
        help='The new branch is a firmware branch. '
        "Named as 'firmware-<Descriptor>-<Major Version>.B'.")
    kind_ex_group.add_argument(
        '--stabilize',
        dest='cls',
        action='store_const',
        const=StabilizeBranch,
        help='The new branch is a minibranch. '
        "Named as 'stabilize-<Descriptor>-<Major Version>.B'.")
    kind_ex_group.add_argument(
        '--custom',
        dest='name',
        help='Use a custom branch type with an explicit name. '
        'WARNING: custom names are dangerous. This tool greps branch '
        'names to determine which versions have already been branched. '
        'Version validation is not possible when the naming convention '
        'is broken. Use this at your own risk.')

    # Rename subcommand and flags.
    rename_parser = subparser.add_parser('rename', help='Rename a branch.')
    rename_parser.add_argument('old', help='Branch to rename.')
    rename_parser.add_argument('new', help='New name for the branch.')

    # Delete subcommand and flags.
    delete_parser = subparser.add_parser('delete', help='Delete a branch.')
    delete_parser.add_argument('branch', help='Name of the branch to delete.')

  def _HandleCreate(self, checkout):
    """Sync to the version or file and create a branch.

    Args:
      checkout: The CrosCheckout to run commands in.
    """
    # Start with quick, immediate validations.
    if self.options.name and self.options.descriptor:
      raise BranchError('--descriptor cannot be used with --custom.')

    if self.options.version and not self.options.version.endswith('0'):
      raise BranchError('Cannot branch version from nonzero patch number.')

    # Handle sync. Unfortunately, we cannot fully validate the version until
    # we have a copy of chromeos_version.sh.
    if self.options.file:
      checkout.SyncFile(self.options.file)
    else:
      checkout.SyncVersion(self.options.version)

    # Now to validate the version. First, double check that the checkout
    # has a zero patch number in case we synced from file.
    vinfo = checkout.ReadVersion()
    if int(vinfo.patch_number):
      raise BranchError('Cannot branch version with nonzero patch number.')

    # Second, check that we did not already branch from this version.
    # manifest-internal serves as the sentinel project.
    manifest_internal = checkout.manifest.GetUniqueProject(
        'chromeos/manifest-internal')
    pattern = '.*-%s\\.B$' % '\\.'.join(
        str(comp) for comp in vinfo.VersionComponents() if comp)
    if (checkout.BranchExists(manifest_internal, pattern) and
        not self.options.force):
      raise BranchError(
          'Already branched %s. Please rerun with --force if you wish to '
          'proceed.' % vinfo.VersionString())

    # Determine if we are creating a custom branch or a standard branch.
    if self.options.cls:
      branch = self.options.cls(checkout, self.options.descriptor)
    else:
      branch = Branch(checkout, self.options.name)

    # Finally, double check the name with the user.
    proceed = self.options.yes or cros_build_lib.BooleanPrompt(
        prompt='New branch will be named %s. Continue?' % branch.name,
        default=False)

    if proceed:
      branch.Create(push=self.options.push, force=self.options.force)
      logging.notice('Successfully created branch %s.', branch.name)
    else:
      logging.notice('Aborted branch creation.')

  def _HandleRename(self, checkout):
    """Sync to the branch and rename it.

    Args:
      checkout: The CrosCheckout to run commands in.
    """
    checkout.SyncBranch(self.options.old)
    branch = Branch(checkout, self.options.new)
    branch.Rename(
        self.options.old, push=self.options.push, force=self.options.force)
    logging.notice('Successfully renamed branch %s to %s.', self.options.old,
                   self.options.new)

  def _HandleDelete(self, checkout):
    """Sync to the branch and delete it.

    Args:
      checkout: The CrosCheckout to run commands in.
    """
    checkout.SyncBranch(self.options.branch)
    branch = Branch(checkout, self.options.branch)
    branch.Delete(push=self.options.push, force=self.options.force)
    logging.notice('Successfully deleted branch %s.', self.options.branch)

  def _RunInCheckout(self, root):
    """Run cros branch in a checkout at the given root.

    Args:
      root: Path to checkout.
    """
    checkout = CrosCheckout.Initialize(
        root,
        self.options.manifest_url,
        repo_url=self.options.repo_url,
        repo_branch=self.options.repo_branch,
        groups=self.options.groups)
    handlers = {
        'create': self._HandleCreate,
        'rename': self._HandleRename,
        'delete': self._HandleDelete
    }
    handlers[self.options.subcommand](checkout)

  def Run(self):
    if self.options.root:
      self._RunInCheckout(self.options.root)
    else:
      with CrosCheckout.TempRoot() as root:
        self._RunInCheckout(root)
        logging.notice('Cleaning up...')
