#!/usr/bin/env vpython3

# Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
#
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file in the root of the source
# tree. An additional intellectual property rights grant can be found
# in the file PATENTS.  All contributing project authors may
# be found in the AUTHORS file in the root of the source tree.
"""Script to automatically roll dependencies in the WebRTC DEPS file."""


import argparse
import base64
import collections
import logging
import os
import re
import subprocess
import sys
import urllib.request


def FindSrcDirPath():
  """Returns the abs path to the src/ dir of the project."""
  src_dir = os.path.dirname(os.path.abspath(__file__))
  while os.path.basename(src_dir) != 'src':
    src_dir = os.path.normpath(os.path.join(src_dir, os.pardir))
  return src_dir


# Skip these dependencies (list without solution name prefix).
DONT_AUTOROLL_THESE = [
    'src/examples/androidtests/third_party/gradle',
    # Disable the roll of 'android_ndk' as it won't appear in chromium DEPS.
    'src/third_party/android_ndk',
    'src/third_party/mockito/src',
]

# These dependencies are missing in chromium/src/DEPS, either unused or already
# in-tree. For instance, src/base is a part of the Chromium source git repo,
# but we pull it through a subtree mirror, so therefore it isn't listed in
# Chromium's deps but it is in ours.
WEBRTC_ONLY_DEPS = [
    'src/base',
    'src/build',
    'src/buildtools',
    'src/ios',
    'src/testing',
    'src/third_party',
    'src/third_party/gtest-parallel',
    'src/third_party/pipewire/linux-amd64',
    'src/tools',
]

WEBRTC_URL = 'https://webrtc.googlesource.com/src'
CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src'
CHROMIUM_COMMIT_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s'
CHROMIUM_LOG_TEMPLATE = CHROMIUM_SRC_URL + '/+log/%s'
CHROMIUM_FILE_TEMPLATE = CHROMIUM_SRC_URL + '/+/%s/%s'

COMMIT_POSITION_RE = re.compile('^Cr-Commit-Position: .*#([0-9]+).*$')
CLANG_REVISION_RE = re.compile(r'^CLANG_REVISION = \'([-0-9a-z]+)\'$')
ROLL_BRANCH_NAME = 'roll_chromium_revision'

SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
CHECKOUT_SRC_DIR = FindSrcDirPath()
CHECKOUT_ROOT_DIR = os.path.realpath(os.path.join(CHECKOUT_SRC_DIR, os.pardir))

# Copied from tools/android/roll/android_deps/.../BuildConfigGenerator.groovy.
ANDROID_DEPS_START = r'=== ANDROID_DEPS Generated Code Start ==='
ANDROID_DEPS_END = r'=== ANDROID_DEPS Generated Code End ==='
# Location of automically gathered android deps.
ANDROID_DEPS_PATH = 'src/third_party/android_deps/'

NOTIFY_EMAIL = 'webrtc-trooper@grotations.appspotmail.com'

sys.path.append(os.path.join(CHECKOUT_SRC_DIR, 'build'))
import find_depot_tools

find_depot_tools.add_depot_tools_to_path()

CLANG_UPDATE_SCRIPT_URL_PATH = 'tools/clang/scripts/update.py'
CLANG_UPDATE_SCRIPT_LOCAL_PATH = os.path.join(CHECKOUT_SRC_DIR, 'tools',
                                              'clang', 'scripts', 'update.py')

DepsEntry = collections.namedtuple('DepsEntry', 'path url revision')
ChangedDep = collections.namedtuple('ChangedDep',
                                    'path url current_rev new_rev')
CipdDepsEntry = collections.namedtuple('CipdDepsEntry', 'path packages')
VersionEntry = collections.namedtuple('VersionEntry', 'version')
ChangedCipdPackage = collections.namedtuple(
    'ChangedCipdPackage', 'path package current_version new_version')
ChangedVersionEntry = collections.namedtuple(
    'ChangedVersionEntry', 'path current_version new_version')

ChromiumRevisionUpdate = collections.namedtuple('ChromiumRevisionUpdate',
                                                ('current_chromium_rev '
                                                 'new_chromium_rev '))


class RollError(Exception):
  pass


def StrExpansion():
  return lambda str_value: str_value


def VarLookup(local_scope):
  return lambda var_name: local_scope['vars'][var_name]


def ParseDepsDict(deps_content):
  local_scope = {}
  global_scope = {
      'Str': StrExpansion(),
      'Var': VarLookup(local_scope),
      'deps_os': {},
  }
  exec(deps_content, global_scope, local_scope)
  return local_scope


def ParseLocalDepsFile(filename):
  with open(filename, 'rb') as f:
    deps_content = f.read().decode('utf-8')
  return ParseDepsDict(deps_content)


def ParseCommitPosition(commit_message):
  for line in reversed(commit_message.splitlines()):
    m = COMMIT_POSITION_RE.match(line.strip())
    if m:
      return int(m.group(1))
  logging.error('Failed to parse commit position id from:\n%s\n',
                commit_message)
  sys.exit(-1)


def _RunCommand(command,
                working_dir=None,
                ignore_exit_code=False,
                extra_env=None,
                input_data=None):
  """Runs a command and returns the output from that command.

    If the command fails (exit code != 0), the function will exit the process.

    Returns:
      A tuple containing the stdout and stderr outputs as strings.
    """
  working_dir = working_dir or CHECKOUT_SRC_DIR
  logging.debug('CMD: %s CWD: %s', ' '.join(command), working_dir)
  env = os.environ.copy()
  if extra_env:
    assert all(isinstance(value, str) for value in extra_env.values())
    logging.debug('extra env: %s', extra_env)
    env.update(extra_env)
  p = subprocess.Popen(command,
                       stdin=subprocess.PIPE,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE,
                       env=env,
                       cwd=working_dir,
                       universal_newlines=True)
  std_output, err_output = p.communicate(input_data)
  p.stdout.close()
  p.stderr.close()
  if not ignore_exit_code and p.returncode != 0:
    logging.error('Command failed: %s\n'
                  'stdout:\n%s\n'
                  'stderr:\n%s\n', ' '.join(command), std_output, err_output)
    sys.exit(p.returncode)
  return std_output, err_output


def _GetBranches():
  """Returns a tuple of active,branches.

    The 'active' is the name of the currently active branch and 'branches' is a
    list of all branches.
    """
  lines = _RunCommand(['git', 'branch'])[0].split('\n')
  branches = []
  active = ''
  for line in lines:
    if '*' in line:
      # The assumption is that the first char will always be the '*'.
      active = line[1:].strip()
      branches.append(active)
    else:
      branch = line.strip()
      if branch:
        branches.append(branch)
  return active, branches


def _ReadGitilesContent(url):
  # Download and decode BASE64 content until
  # https://code.google.com/p/gitiles/issues/detail?id=7 is fixed.
  base64_content = ReadUrlContent(url + '?format=TEXT')
  return base64.b64decode(base64_content[0]).decode('utf-8')


def ReadRemoteCrFile(path_below_src, revision):
  """Reads a remote Chromium file of a specific revision.

    Args:
      path_below_src: A path to the target file relative to src dir.
      revision: Revision to read.
    Returns:
      A string with file content.
    """
  return _ReadGitilesContent(CHROMIUM_FILE_TEMPLATE %
                             (revision, path_below_src))


def ReadRemoteCrCommit(revision):
  """Reads a remote Chromium commit message. Returns a string."""
  return _ReadGitilesContent(CHROMIUM_COMMIT_TEMPLATE % revision)


def ReadUrlContent(url):
  """Connect to a remote host and read the contents.

    Args:
      url: URL to connect to.
    Returns:
      A list of lines.
    """
  conn = urllib.request.urlopen(url)
  try:
    return conn.readlines()
  except IOError as e:
    logging.exception('Error connecting to %s. Error: %s', url, e)
    raise
  finally:
    conn.close()


def GetMatchingDepsEntries(depsentry_dict, dir_path):
  """Gets all deps entries matching the provided path.

    This list may contain more than one DepsEntry object.
    Example: dir_path='src/testing' would give results containing both
    'src/testing/gtest' and 'src/testing/gmock' deps entries for Chromium's
    DEPS.
    Example 2: dir_path='src/build' should return 'src/build' but not
    'src/buildtools'.

    Returns:
      A list of DepsEntry objects.
    """
  result = []
  for path, depsentry in depsentry_dict.items():
    if path == dir_path:
      result.append(depsentry)
    else:
      parts = path.split('/')
      if all(part == parts[i] for i, part in enumerate(dir_path.split('/'))):
        result.append(depsentry)
  return result


def BuildDepsentryDict(deps_dict):
  """Builds a dict of paths to DepsEntry objects from a raw deps dict."""
  result = {}

  def AddDepsEntries(deps_subdict):
    for path, dep in deps_subdict.items():
      if path in result:
        continue
      if not isinstance(dep, dict):
        dep = {'url': dep}
      if dep.get('dep_type') == 'cipd':
        result[path] = CipdDepsEntry(path, dep['packages'])
      else:
        if '@' not in dep['url']:
          url, revision = dep['url'], 'HEAD'
        else:
          url, revision = dep['url'].split('@')
        result[path] = DepsEntry(path, url, revision)

  def AddVersionEntry(vars_subdict):
    for key, value in vars_subdict.items():
      if key in result:
        continue
      if not key.endswith('_version'):
        continue
      key = re.sub('_version$', '', key)
      result[key] = VersionEntry(value)

  AddDepsEntries(deps_dict['deps'])
  for deps_os in ['win', 'mac', 'linux', 'android', 'ios', 'unix']:
    AddDepsEntries(deps_dict.get('deps_os', {}).get(deps_os, {}))
  AddVersionEntry(deps_dict.get('vars', {}))
  return result


def _FindChangedCipdPackages(path, old_pkgs, new_pkgs):
  old_pkgs_names = {p['package'] for p in old_pkgs}
  new_pkgs_names = {p['package'] for p in new_pkgs}
  pkgs_equal = (old_pkgs_names == new_pkgs_names)
  added_pkgs = [p for p in new_pkgs_names if p not in old_pkgs_names]
  removed_pkgs = [p for p in old_pkgs_names if p not in new_pkgs_names]

  assert pkgs_equal, ('Old: %s\n New: %s.\nYou need to do a manual roll '
                      'and remove/add entries in DEPS so the old and new '
                      'list match.\nMost likely, you should add \"%s\" and '
                      'remove \"%s\"' %
                      (old_pkgs, new_pkgs, added_pkgs, removed_pkgs))

  for old_pkg in old_pkgs:
    for new_pkg in new_pkgs:
      old_version = old_pkg['version']
      new_version = new_pkg['version']
      if (old_pkg['package'] == new_pkg['package']
          and old_version != new_version):
        logging.debug('Roll dependency %s to %s', path, new_version)
        yield ChangedCipdPackage(path, old_pkg['package'], old_version,
                                 new_version)


def _FindChangedVars(name, old_version, new_version):
  if old_version != new_version:
    logging.debug('Roll dependency %s to %s', name, new_version)
    yield ChangedVersionEntry(name, old_version, new_version)


def _FindNewDeps(old, new):
  """ Gather dependencies only in `new` and return corresponding paths. """
  old_entries = set(BuildDepsentryDict(old))
  new_entries = set(BuildDepsentryDict(new))
  return [
      path for path in new_entries - old_entries
      if path not in DONT_AUTOROLL_THESE
  ]


def FindAddedDeps(webrtc_deps, new_cr_deps):
  """
    Calculate new deps entries of interest.

    Ideally, that would mean: only appearing in chromium DEPS
    but transitively used in WebRTC.

    Since it's hard to compute, we restrict ourselves to a well defined subset:
    deps sitting in `ANDROID_DEPS_PATH`.
    Otherwise, assumes that's a Chromium-only dependency.

    Args:
      webrtc_deps: dict of deps as defined in the WebRTC DEPS file.
      new_cr_deps: dict of deps as defined in the chromium DEPS file.

    Caveat: Doesn't detect a new package in existing dep.

    Returns:
      A tuple consisting of:
        A list of paths added dependencies sitting in `ANDROID_DEPS_PATH`.
        A list of paths for other added dependencies.
    """
  all_added_deps = _FindNewDeps(webrtc_deps, new_cr_deps)
  generated_android_deps = [
      path for path in all_added_deps if path.startswith(ANDROID_DEPS_PATH)
  ]
  other_deps = [
      path for path in all_added_deps if path not in generated_android_deps
  ]
  return generated_android_deps, other_deps


def FindRemovedDeps(webrtc_deps, new_cr_deps):
  """
    Calculate obsolete deps entries.

    Ideally, that would mean: no more appearing in chromium DEPS
    and not used in WebRTC.

    Since it's hard to compute:
     1/ We restrict ourselves to a well defined subset:
        deps sitting in `ANDROID_DEPS_PATH`.
     2/ We rely on existing behavior of CalculateChangeDeps.
        I.e. Assumes non-CIPD dependencies are WebRTC-only, don't remove them.

    Args:
      webrtc_deps: dict of deps as defined in the WebRTC DEPS file.
      new_cr_deps: dict of deps as defined in the chromium DEPS file.

    Caveat: Doesn't detect a deleted package in existing dep.

    Returns:
      A tuple consisting of:
        A list of paths of dependencies removed from `ANDROID_DEPS_PATH`.
        A list of paths of unexpected disappearing dependencies.
    """
  all_removed_deps = _FindNewDeps(new_cr_deps, webrtc_deps)
  generated_android_deps = sorted(
      [path for path in all_removed_deps if path.startswith(ANDROID_DEPS_PATH)])
  # Webrtc-only dependencies are handled in CalculateChangedDeps.
  other_deps = sorted([
      path for path in all_removed_deps
      if path not in generated_android_deps and path not in WEBRTC_ONLY_DEPS
  ])
  return generated_android_deps, other_deps


def CalculateChangedDeps(webrtc_deps, new_cr_deps):
  """
    Calculate changed deps entries based on entries defined in the WebRTC DEPS
    file:
     - If a shared dependency with the Chromium DEPS file: roll it to the same
       revision as Chromium (i.e. entry in the new_cr_deps dict)
     - If it's a Chromium sub-directory, roll it to the HEAD revision (notice
       this means it may be ahead of the chromium_revision, but generally these
       should be close).
     - If it's another DEPS entry (not shared with Chromium), roll it to HEAD
       unless it's configured to be skipped.

    Returns:
      A list of ChangedDep objects representing the changed deps.
    """
  result = []
  webrtc_entries = BuildDepsentryDict(webrtc_deps)
  new_cr_entries = BuildDepsentryDict(new_cr_deps)
  for path, webrtc_deps_entry in webrtc_entries.items():
    if path in DONT_AUTOROLL_THESE:
      continue
    cr_deps_entry = new_cr_entries.get(path)
    if cr_deps_entry:
      assert type(cr_deps_entry) is type(webrtc_deps_entry)

      if isinstance(cr_deps_entry, CipdDepsEntry):
        result.extend(
            _FindChangedCipdPackages(path, webrtc_deps_entry.packages,
                                     cr_deps_entry.packages))
        continue

      if isinstance(cr_deps_entry, VersionEntry):
        result.extend(
            _FindChangedVars(path, webrtc_deps_entry.version,
                             cr_deps_entry.version))
        continue

      # Use the revision from Chromium's DEPS file.
      new_rev = cr_deps_entry.revision
      assert webrtc_deps_entry.url == cr_deps_entry.url, (
          'WebRTC DEPS entry %s has a different URL %s than Chromium %s.' %
          (path, webrtc_deps_entry.url, cr_deps_entry.url))
    else:
      if isinstance(webrtc_deps_entry, DepsEntry):
        # Use the HEAD of the deps repo.
        stdout, _ = _RunCommand(
            ['git', 'ls-remote', webrtc_deps_entry.url, 'HEAD'])
        new_rev = stdout.strip().split('\t')[0]
      else:
        # The dependency has been removed from chromium.
        # This is handled by FindRemovedDeps.
        continue

    # Check if an update is necessary.
    if webrtc_deps_entry.revision != new_rev:
      logging.debug('Roll dependency %s to %s', path, new_rev)
      result.append(
          ChangedDep(path, webrtc_deps_entry.url, webrtc_deps_entry.revision,
                     new_rev))
  return sorted(result)


def CalculateChangedClang(new_cr_rev):

  def GetClangRev(lines):
    for line in lines:
      match = CLANG_REVISION_RE.match(line)
      if match:
        return match.group(1)
    raise RollError('Could not parse Clang revision!')

  with open(CLANG_UPDATE_SCRIPT_LOCAL_PATH, 'r') as f:
    current_lines = f.readlines()
  current_rev = GetClangRev(current_lines)

  new_clang_update_py = ReadRemoteCrFile(CLANG_UPDATE_SCRIPT_URL_PATH,
                                         new_cr_rev).splitlines()
  new_rev = GetClangRev(new_clang_update_py)
  return ChangedDep(CLANG_UPDATE_SCRIPT_LOCAL_PATH, None, current_rev, new_rev)


def GenerateCommitMessage(
        rev_update,
        current_commit_pos,
        new_commit_pos,
        changed_deps_list,
        added_deps_paths=None,
        removed_deps_paths=None,
        clang_change=None,
):
  current_cr_rev = rev_update.current_chromium_rev[0:10]
  new_cr_rev = rev_update.new_chromium_rev[0:10]
  rev_interval = '%s..%s' % (current_cr_rev, new_cr_rev)
  git_number_interval = '%s:%s' % (current_commit_pos, new_commit_pos)

  commit_msg = [
      'Roll chromium_revision %s (%s)\n' % (rev_interval, git_number_interval),
      'Change log: %s' % (CHROMIUM_LOG_TEMPLATE % rev_interval),
      'Full diff: %s\n' % (CHROMIUM_COMMIT_TEMPLATE % rev_interval)
  ]

  def Section(adjective, deps):
    noun = 'dependency' if len(deps) == 1 else 'dependencies'
    commit_msg.append('%s %s' % (adjective, noun))

  if changed_deps_list:
    Section('Changed', changed_deps_list)

    for c in changed_deps_list:
      if isinstance(c, ChangedCipdPackage):
        commit_msg.append('* %s: %s..%s' %
                          (c.path, c.current_version, c.new_version))
      elif isinstance(c, ChangedVersionEntry):
        commit_msg.append('* %s_version: %s..%s' %
                          (c.path, c.current_version, c.new_version))
      else:
        commit_msg.append('* %s: %s/+log/%s..%s' %
                          (c.path, c.url, c.current_rev[0:10], c.new_rev[0:10]))

  if added_deps_paths:
    Section('Added', added_deps_paths)
    commit_msg.extend('* %s' % p for p in added_deps_paths)

  if removed_deps_paths:
    Section('Removed', removed_deps_paths)
    commit_msg.extend('* %s' % p for p in removed_deps_paths)

  if any([changed_deps_list, added_deps_paths, removed_deps_paths]):
    change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval, 'DEPS')
    commit_msg.append('DEPS diff: %s\n' % change_url)
  else:
    commit_msg.append('No dependencies changed.')

  if clang_change and clang_change.current_rev != clang_change.new_rev:
    commit_msg.append('Clang version changed %s:%s' %
                      (clang_change.current_rev, clang_change.new_rev))
    change_url = CHROMIUM_FILE_TEMPLATE % (rev_interval,
                                           CLANG_UPDATE_SCRIPT_URL_PATH)
    commit_msg.append('Details: %s\n' % change_url)
  else:
    commit_msg.append('No update to Clang.\n')

  commit_msg.append('BUG=None')
  return '\n'.join(commit_msg)


def UpdateDepsFile(deps_filename, rev_update, changed_deps, new_cr_content):
  """Update the DEPS file with the new revision."""

  with open(deps_filename, 'rb') as deps_file:
    deps_content = deps_file.read().decode('utf-8')

  # Update the chromium_revision variable.
  deps_content = deps_content.replace(rev_update.current_chromium_rev,
                                      rev_update.new_chromium_rev)

  # Add and remove dependencies. For now: only generated android deps.
  # Since gclient cannot add or remove deps, we on the fact that
  # these android deps are located in one place we can copy/paste.
  deps_re = re.compile(ANDROID_DEPS_START + '.*' + ANDROID_DEPS_END, re.DOTALL)
  new_deps = deps_re.search(new_cr_content)
  old_deps = deps_re.search(deps_content)
  if not new_deps or not old_deps:
    faulty = 'Chromium' if not new_deps else 'WebRTC'
    raise RollError('Was expecting to find "%s" and "%s"\n'
                    'in %s DEPS' %
                    (ANDROID_DEPS_START, ANDROID_DEPS_END, faulty))
  deps_content = deps_re.sub(new_deps.group(0), deps_content)

  for dep in changed_deps:
    if isinstance(dep, ChangedVersionEntry):
      deps_content = deps_content.replace(dep.current_version, dep.new_version)

  with open(deps_filename, 'wb') as deps_file:
    deps_file.write(deps_content.encode('utf-8'))

  # Update each individual DEPS entry.
  for dep in changed_deps:
    # ChangedVersionEntry types are already been processed.
    if isinstance(dep, ChangedVersionEntry):
      continue
    local_dep_dir = os.path.join(CHECKOUT_ROOT_DIR, dep.path)
    if not os.path.isdir(local_dep_dir):
      raise RollError(
          'Cannot find local directory %s. Either run\n'
          'gclient sync --deps=all\n'
          'or make sure the .gclient file for your solution contains all '
          'platforms in the target_os list, i.e.\n'
          'target_os = ["android", "unix", "mac", "ios", "win"];\n'
          'Then run "gclient sync" again.' % local_dep_dir)
    if isinstance(dep, ChangedCipdPackage):
      package = dep.package.format()  # Eliminate double curly brackets
      update = '%s:%s@%s' % (dep.path, package, dep.new_version)
    else:
      update = '%s@%s' % (dep.path, dep.new_rev)
    _RunCommand(['gclient', 'setdep', '--revision', update],
                working_dir=CHECKOUT_SRC_DIR)


def _IsTreeClean():
  stdout, _ = _RunCommand(['git', 'status', '--porcelain'])
  if len(stdout) == 0:
    return True

  logging.error('Dirty/unversioned files:\n%s', stdout)
  return False


def _EnsureUpdatedMainBranch(dry_run):
  current_branch = _RunCommand(['git', 'rev-parse', '--abbrev-ref',
                                'HEAD'])[0].splitlines()[0]
  if current_branch != 'main':
    logging.error('Please checkout the main branch and re-run this script.')
    if not dry_run:
      sys.exit(-1)

  logging.info('Updating main branch...')
  _RunCommand(['git', 'pull'])


def _CreateRollBranch(dry_run):
  logging.info('Creating roll branch: %s', ROLL_BRANCH_NAME)
  if not dry_run:
    _RunCommand(['git', 'checkout', '-b', ROLL_BRANCH_NAME])


def _RemovePreviousRollBranch(dry_run):
  active_branch, branches = _GetBranches()
  if active_branch == ROLL_BRANCH_NAME:
    active_branch = 'main'
  if ROLL_BRANCH_NAME in branches:
    logging.info('Removing previous roll branch (%s)', ROLL_BRANCH_NAME)
    if not dry_run:
      _RunCommand(['git', 'checkout', active_branch])
      _RunCommand(['git', 'branch', '-D', ROLL_BRANCH_NAME])


def _LocalCommit(commit_msg, dry_run):
  logging.info('Committing changes locally.')
  if not dry_run:
    _RunCommand(['git', 'add', '--update', '.'])
    _RunCommand(['git', 'commit', '-m', commit_msg])


def ChooseCQMode(skip_cq, cq_over, current_commit_pos, new_commit_pos):
  if skip_cq:
    return 0
  if (new_commit_pos - current_commit_pos) < cq_over:
    return 1
  return 2


def _GetCcRecipients(changed_deps_list):
  """Returns a list of emails to notify based on the changed deps list.
    """
  cc_recipients = []
  for c in changed_deps_list:
    if 'libvpx' in c.path or 'libaom' in c.path:
      cc_recipients.append('marpan@webrtc.org')
      cc_recipients.append('jianj@chromium.org')
  return cc_recipients


def _UploadCL(commit_queue_mode, add_cc=None):
  """Upload the committed changes as a changelist to Gerrit.

    commit_queue_mode:
     - 2: Submit to commit queue.
     - 1: Run trybots but do not submit to CQ.
     - 0: Skip CQ, upload only.

    add_cc: A list of email addresses to add as CC recipients.
    """
  cc_recipients = [NOTIFY_EMAIL]
  if add_cc:
    cc_recipients.extend(add_cc)
  cmd = ['git', 'cl', 'upload', '--force', '--bypass-hooks']
  if commit_queue_mode >= 2:
    logging.info('Sending the CL to the CQ...')
    cmd.extend(['-o', 'label=Bot-Commit+1'])
    cmd.extend(['-o', 'label=Commit-Queue+2'])
    cmd.extend(['--send-mail', '--cc', ','.join(cc_recipients)])
  elif commit_queue_mode >= 1:
    logging.info('Starting CQ dry run...')
    cmd.extend(['-o', 'label=Commit-Queue+1'])
  extra_env = {
      'EDITOR': 'true',
      'SKIP_GCE_AUTH_FOR_GIT': '1',
  }
  stdout, stderr = _RunCommand(cmd, extra_env=extra_env)
  logging.debug('Output from "git cl upload":\nstdout:\n%s\n\nstderr:\n%s',
                stdout, stderr)


def GetRollRevisionRanges(opts, webrtc_deps):
  current_cr_rev = webrtc_deps['vars']['chromium_revision']
  new_cr_rev = opts.revision
  if not new_cr_rev:
    stdout, _ = _RunCommand(['git', 'ls-remote', CHROMIUM_SRC_URL, 'HEAD'])
    head_rev = stdout.strip().split('\t')[0]
    logging.info('No revision specified. Using HEAD: %s', head_rev)
    new_cr_rev = head_rev

  return ChromiumRevisionUpdate(current_cr_rev, new_cr_rev)


def main():
  p = argparse.ArgumentParser()
  p.add_argument('--clean',
                 action='store_true',
                 default=False,
                 help='Removes any previous local roll branch.')
  p.add_argument('-r',
                 '--revision',
                 help=('Chromium Git revision to roll to. Defaults to the '
                       'Chromium HEAD revision if omitted.'))
  p.add_argument('--dry-run',
                 action='store_true',
                 default=False,
                 help=('Calculate changes and modify DEPS, but don\'t create '
                       'any local branch, commit, upload CL or send any '
                       'tryjobs.'))
  p.add_argument('-i',
                 '--ignore-unclean-workdir',
                 action='store_true',
                 default=False,
                 help=('Ignore if the current branch is not main or if there '
                       'are uncommitted changes (default: %(default)s).'))
  grp = p.add_mutually_exclusive_group()
  grp.add_argument('--skip-cq',
                   action='store_true',
                   default=False,
                   help='Skip sending the CL to the CQ (default: %(default)s)')
  grp.add_argument('--cq-over',
                   type=int,
                   default=1,
                   help=('Commit queue dry run if the revision difference '
                         'is below this number (default: %(default)s)'))
  p.add_argument('-v',
                 '--verbose',
                 action='store_true',
                 default=False,
                 help='Be extra verbose in printing of log messages.')
  opts = p.parse_args()

  if opts.verbose:
    logging.basicConfig(level=logging.DEBUG)
  else:
    logging.basicConfig(level=logging.INFO)

  if not opts.ignore_unclean_workdir and not _IsTreeClean():
    logging.error('Please clean your local checkout first.')
    return 1

  if opts.clean:
    _RemovePreviousRollBranch(opts.dry_run)

  if not opts.ignore_unclean_workdir:
    _EnsureUpdatedMainBranch(opts.dry_run)

  deps_filename = os.path.join(CHECKOUT_SRC_DIR, 'DEPS')
  webrtc_deps = ParseLocalDepsFile(deps_filename)

  rev_update = GetRollRevisionRanges(opts, webrtc_deps)

  current_commit_pos = ParseCommitPosition(
      ReadRemoteCrCommit(rev_update.current_chromium_rev))
  new_commit_pos = ParseCommitPosition(
      ReadRemoteCrCommit(rev_update.new_chromium_rev))

  new_cr_content = ReadRemoteCrFile('DEPS', rev_update.new_chromium_rev)
  new_cr_deps = ParseDepsDict(new_cr_content)
  changed_deps = CalculateChangedDeps(webrtc_deps, new_cr_deps)
  # Discard other deps, assumed to be chromium-only dependencies.
  new_generated_android_deps, _ = FindAddedDeps(webrtc_deps, new_cr_deps)
  removed_generated_android_deps, other_deps = FindRemovedDeps(
      webrtc_deps, new_cr_deps)
  if other_deps:
    raise RollError('WebRTC DEPS entries are missing from Chromium: %s.\n'
                    'Remove them or add them to either '
                    'WEBRTC_ONLY_DEPS or DONT_AUTOROLL_THESE.' % other_deps)
  clang_change = CalculateChangedClang(rev_update.new_chromium_rev)
  commit_msg = GenerateCommitMessage(
      rev_update,
      current_commit_pos,
      new_commit_pos,
      changed_deps,
      added_deps_paths=new_generated_android_deps,
      removed_deps_paths=removed_generated_android_deps,
      clang_change=clang_change)
  logging.debug('Commit message:\n%s', commit_msg)

  _CreateRollBranch(opts.dry_run)
  if not opts.dry_run:
    UpdateDepsFile(deps_filename, rev_update, changed_deps, new_cr_content)
  if _IsTreeClean():
    logging.info("No DEPS changes detected, skipping CL creation.")
  else:
    _LocalCommit(commit_msg, opts.dry_run)
    commit_queue_mode = ChooseCQMode(opts.skip_cq, opts.cq_over,
                                     current_commit_pos, new_commit_pos)
    logging.info('Uploading CL...')
    if not opts.dry_run:
      _UploadCL(commit_queue_mode, _GetCcRecipients(changed_deps))
  return 0


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