#!/usr/bin/env python
# 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."""

from __future__ import absolute_import

import argparse
import base64
import collections
import logging
import os
import re
import subprocess
import sys

import six.moves.urllib.request
import six.moves.urllib.error
import six.moves.urllib.parse


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',
]

# 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/bazel',
    'src/third_party/findbugs',
    'src/third_party/gtest-parallel',
    'src/third_party/yasm/binaries',
    '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')
ChangedCipdPackage = collections.namedtuple(
    'ChangedCipdPackage', 'path package 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()
    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])


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 = six.moves.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']:
                    continue
                url, revision = dep['url'].split('@')
                result[path] = DepsEntry(path, url, revision)

    AddDepsEntries(deps_dict['deps'])
    for deps_os in ['win', 'mac', 'unix', 'android', 'ios', 'unix']:
        AddDepsEntries(deps_dict.get('deps_os', {}).get(deps_os, {}))
    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 _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

            # 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, 'rb') 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))
            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, 'r') as deps_file:
        deps_content = deps_file.read()

    # 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)

    with open(deps_filename, 'w') as deps_file:
        deps_file.write(deps_content)

    # Update each individual DEPS entry.
    for dep in changed_deps:
        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())
