# -*- 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.')
    remote_group.add_argument(
        '--ack-deprecation',
        action='store_true',
        help='Acknowledge that this tool is deprecated and that branch_util '
        'should be used instead. go/cros-branching')

    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):
    logging.warning(
        'The `cros branch` tool will be removed by end of year 2020. '
        'Instead, please use the new Go-based branch_util tool. Instructions '
        'for installing this tool and example usage can be found at '
        'http://go/cros-branching. Try `~/go/bin/branch_util help create` to '
        'see its full branch creation usage instructions.')
    # Require the user to ack that warning
    if not self.options.ack_deprecation:
      in_test_context = 'PYTEST_CURRENT_TEST' in os.environ
      if not in_test_context:
        cros_build_lib.Die(
          'Please use the new tool, or add --ack-deprecation to continue with '
          'use of `cros branch`')
    if self.options.root:
      self._RunInCheckout(self.options.root)
    else:
      with CrosCheckout.TempRoot() as root:
        self._RunInCheckout(root)
        logging.notice('Cleaning up...')
