#!/usr/bin/env vpython3
# Copyright 2025 The Dawn & Tint Authors
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
#    list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its
#    contributors may be used to endorse or promote products derived from
#    this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Rolls DEPS entries shared with Chromium."""

import abc
import argparse
import base64
import dataclasses
import datetime
import logging
import pathlib
import posixpath
import subprocess
import sys
from typing import Any, Self, Type

import requests

DAWN_ROOT = pathlib.Path(__file__).resolve().parents[1]
DEPS_FILE = DAWN_ROOT / 'DEPS'

CHROMIUM_SRC_URL = 'https://chromium.googlesource.com/chromium/src'
CHROMIUM_REVISION_VAR = 'chromium_revision'

DEFAULT_REVISION_CHARACTERS = 10

# GN variables that need to be synced. A map from Dawn variable name to
# Chromium variable name.
SYNCED_VARIABLES = {}

# DEPS entries which have dep_type = cipd. In the Chromium DEPS file, these
# will be prefixed with src/.
SYNCED_CIPD_DEPS = {
    'buildtools/linux64',
    'buildtools/mac',
    'buildtools/reclient',
    'buildtools/win',
    'third_party/ninja',
    'third_party/siso/cipd',
}

# DEPS entries which have dep_type = gcs. In the Chromium DEPS file, these will
# be prefixed with src/.
SYNCED_GCS_DEPS = {
    'build/linux/debian_bullseye_arm64-sysroot',
    'build/linux/debian_bullseye_armhf-sysroot',
    'build/linux/debian_bullseye_i386-sysroot',
    'build/linux/debian_bullseye_mipsel-sysroot',
    'build/linux/debian_bullseye_mips64el-sysroot',
    'build/linux/debian_bullseye_amd64-sysroot',
}

# Repos that are independently synced by Chromium and Dawn. A map from Dawn
# names to Chromium names. None means that the names are identical. In the
# Chromium DEPS file, these will be prefixed with src/.
# The following repos are already synced by dedicated autorollers:
# * https://autoroll.skia.org/r/angle-dawn-autoroll
#   * third_party/angle
# * https://autoroll.skia.org/r/swiftshader-dawn-autoroll
#   * third_party/swiftshader
# * https://autoroll.skia.org/r/vulkan-deps-dawn-autoroll
#   * third_party/glslang/src
#   * third_party/spirv-headers/src
#   * third_party/spirv-tools/src
#   * third_party/vulkan-deps
#   * third_party/vulkan-headers/src
#   * third_party/vulkan-loader/src
#   * third_party/vulkan-tools/src
#   * third_party/vulkan-utility-libraries/src
#   * third_party/vulkan-validation-layers/src
SYNCED_REPOS = {
    'third_party/catapult': None,
    'third_party/clang-format/script': None,
    'third_party/depot_tools': None,
    # third_party/dxheaders is technically used by both Chromium and Dawn, but
    # for different purposes and on non-overlapping platforms. Thus, there is
    # no need to sync their revisions.
    'third_party/google_benchmark/src': None,
    'third_party/googletest': 'third_party/googletest/src',
    'third_party/jsoncpp': 'third_party/jsoncpp/source',
    'third_party/libc++/src': None,
    'third_party/libc++abi/src': None,
    'third_party/libprotobuf-mutator/src': None,
    'third_party/llvm-libc/src': None,
    'third_party/libdrm/src': None,
    'third_party/libFuzzer/src': None,
    # third_party/vulkan_memory_allocator is shared with Chromium, but is
    # manually rolled since it typically requires additional code changes in
    # the repo.
    # third_party/webgpu-cts is technically used by both Chromium and Dawn, but
    # they are used for different purposes and the CTS roller needs to roll
    # Dawn's copy in order to update expectations.
}

# Chromium directories that are exported as pseudo-repos in
# chromium.googlesource.com under chromium/src/. Mapping of Dawn path to
# Chromium src-relative path. None means that the names are identical.
EXPORTED_CHROMIUM_REPOS = {
    'build': None,
    'buildtools': None,
    'testing': None,
    'third_party/abseil-cpp': None,
    'third_party/jinja2': None,
    'third_party/markupsafe': None,
    'third_party/partition_alloc': 'base/allocator/partition_allocator',
    'third_party/protobuf': None,
    'third_party/zlib': None,
    'tools/clang': None,
    'tools/mb': None,
    'tools/memory': None,
    'tools/protoc_wrapper': None,
    'tools/valgrind': None,
    'tools/win': None,
}


@dataclasses.dataclass
class ChangedDepsEntry(abc.ABC):
    """Base class for all changed DEPS entries."""
    # The name of the dependency in Dawn's DEPS file.
    name: str

    @abc.abstractmethod
    def setdep_args(self) -> list[str]:
        """Returns 'gclient setdep'-compatible arguments.

        The returned arguments will cause 'gclient setdep' to update the DEPS
        file content to the new version.
        """

    @abc.abstractmethod
    def commit_message_lines(self) -> list[str]:
        """Returns lines to add to the commit message."""


@dataclasses.dataclass
class ChangedVariable(ChangedDepsEntry):
    """Represents a single changed DEPS variable."""
    # The old version in Dawn's DEPS file.
    old_version: str
    # The new version that Dawn's DEPS file will contain.
    new_version: str

    def setdep_args(self) -> list[str]:
        return [
            '--var',
            f'{self.name}={self.new_version}',
        ]

    def commit_message_lines(self) -> list[str]:
        return [
            f'  {self.name}: {self.old_version} -> {self.new_version}',
        ]


@dataclasses.dataclass
class ChangedRepo(ChangedDepsEntry):
    """Represents a single changed DEPS repo entry."""
    # The URL of the repo that Dawn depends on.
    url: str
    # The old revision in Dawn's DEPS file.
    old_revision: str
    # The new revision that Dawn's DEPS file will contain.
    new_revision: str

    def setdep_args(self) -> list[str]:
        return [
            '--revision',
            f'{self.name}@{self.new_revision}',
        ]

    def commit_message_lines(self) -> list[str]:
        return [f'  {self.name}: {self.log_link()}']

    def revision_range(self, num_characters: int | None = None) -> str:
        num_characters = num_characters or DEFAULT_REVISION_CHARACTERS
        return (f'{self.old_revision[:num_characters]}'
                f'..'
                f'{self.new_revision[:num_characters]}')

    def log_link(self, num_characters: int | None = None) -> str:
        return f'{self.url}/+log/{self.revision_range(num_characters)}'

    def commit_link(self, num_characters: int | None = None) -> str:
        return f'{self.url}/+/{self.revision_range(num_characters)}'


@dataclasses.dataclass
class CipdPackage:
    """Represents a single element of a CIPD DEPS entry's 'packages' list."""
    package: str
    version: str

    @classmethod
    def from_dict(cls, dict_repr: dict[str, str]) -> Self:
        """Creates an instance from a DEPS entry dict.

        Args:
            dict_repr: A dictionary from a GCS DEPS entry's 'packages' list.

        Returns:
            A CipdPackage instance filled with the information contained within
            |dict_repr|.
        """
        return cls(
            package=dict_repr['package'],
            version=dict_repr['version'],
        )

    def setdep_str(self) -> str:
        """Gets a 'gclient setdep'-compatible string representation."""
        # Remove any double curly braces, e.g. ${{arch}}
        package = self.package.format()
        return f'{package}@{self.version}'


@dataclasses.dataclass
class ChangedCipd(ChangedDepsEntry):
    """Represents a single changed DEPS CIPD entry."""
    # The old packages in Dawn's DEPS file
    old_packages: list[CipdPackage]
    # The new packages that Dawn's DEPS file will contain.
    new_packages: list[CipdPackage]

    def setdep_args(self) -> list[str]:
        revisions = [
            f'{self.name}:{p.setdep_str()}' for p in self.new_packages
        ]
        return ['--revision'] + revisions

    def commit_message_lines(self) -> list[str]:
        return [
            f'  {self.name}',
        ]


@dataclasses.dataclass
class GcsObject:
    """Represents a single element of a GCS DEPS entry's 'objects' list."""
    object_name: str
    sha256sum: str
    size_bytes: int
    generation: int

    @classmethod
    def from_dict(cls, dict_repr: dict[str, str | int]) -> Self:
        """Creates an instance from a DEPS entry dict.

        Args:
            dict_repr: A dictionary from a GCS DEPS entry's 'objects' list.

        Returns:
            A GcsObject instance filled with the information contained within
            |dict_repr|.
        """
        return cls(
            object_name=dict_repr['object_name'],
            sha256sum=dict_repr['sha256sum'],
            size_bytes=dict_repr['size_bytes'],
            generation=dict_repr['generation'],
        )

    def as_comma_separated_str(self) -> str:
        return (f'{self.object_name},{self.sha256sum},{self.size_bytes},'
                f'{self.generation}')


@dataclasses.dataclass
class ChangedGcs(ChangedDepsEntry):
    """Represents a single changed DEPS GCS entry."""
    # The old objects in Dawn's DEPS file.
    old_objects: list[GcsObject]
    # The new objects that Dawn's DEPS file will contain.
    new_objects: list[GcsObject]

    def setdep_args(self) -> list[str]:
        comma_separated_objects = [
            o.as_comma_separated_str() for o in self.new_objects
        ]
        object_string = '?'.join(comma_separated_objects)
        return ['--revision', f'{self.name}@{object_string}']

    def commit_message_lines(self) -> list[str]:
        return [
            f'  {self.name}',
        ]


def _parse_deps_file(deps_content: str) -> dict[str, Any]:
    """Parses DEPS file content into a Python dict.

    Args:
        deps_content: The content of a DEPS file.

    Returns:
        A dict containing all content of the DEPS file. For example, the top
        level `vars` mapping in a DEPS file can be accessed via the 'vars' item
        in the returned dictionary.
    """
    local_scope = {}
    global_scope = {
        'Str': lambda str_value: str_value,
        'Var': lambda var_name: local_scope['vars'][var_name],
    }
    exec(deps_content, global_scope, local_scope)
    return local_scope


def _add_depot_tools_to_path() -> None:
    sys.path.append(str(DAWN_ROOT / 'build'))
    import find_depot_tools
    find_depot_tools.add_depot_tools_to_path()


def _is_tree_clean() -> bool:
    """Checks for untracked/uncommitted files.

    Returns:
        True iff there are no untracked or uncommitted files.
    """
    proc = subprocess.run(['git', 'status', '--porcelain'],
                          capture_output=True,
                          text=True,
                          check=True)
    if not proc.stdout:
        return True

    logging.error('Dirty or untracked files:\n%s', proc.stdout)
    return False


def _ensure_updated_main_branch() -> None:
    """Ensures that the main branch is checked out and up to date."""
    proc = subprocess.run(['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
                          capture_output=True,
                          text=True,
                          check=True)
    current_branch = proc.stdout.splitlines()[0]
    if current_branch != 'main':
        raise RuntimeError('Please run this from the main branch')

    logging.info('Updating main branch...')
    subprocess.run(['git', 'pull'], check=True)


def _create_roll_branch() -> None:
    """Creates a unique branch for a roll."""
    # YYYY-MM-DD-HH-MM-SS
    now = datetime.datetime.now().strftime('%Y-%m-%d-%H-%M-%S')
    branch_name = f'roll-chromium-deps-{now}'
    logging.info('Creating branch %s', branch_name)
    _ = subprocess.run(['git', 'checkout', '-b', branch_name], check=True)


def _amend_commit(commit_message: str) -> None:
    """Amends the most recent commit.

    Args:
        commit_message: The commit message to add to the existing commit
            message. This will be inserted towards the end of the existing
            message, just before "Bug:".
    """
    logging.info('Amending changes to local commit')

    proc = subprocess.run(['git', 'log', '-1', '--pretty=%B'],
                          capture_output=True,
                          text=True,
                          check=True)
    old_commit_message = proc.stdout.strip()
    logging.debug('Existing commit message:\n%s', old_commit_message)

    bug_index = old_commit_message.rfind('Bug:')
    if bug_index == -1:
        raise RuntimeError('"Bug:" not found in existing commit message.')

    new_commit_message = (f'{old_commit_message[:bug_index]}'
                          f'{commit_message}'
                          f'\n'
                          f'{old_commit_message[bug_index:]}')

    _ = subprocess.run(
        ['git', 'commit', '-a', '--amend', '-m', new_commit_message],
        capture_output=True,
        check=True)


def _commit(commit_message: str) -> None:
    """Commits all changed files.

    Args:
        commit_message: The commit message to use for the new commit.
    """
    # `gclient setdep` should have already staged changes and running
    # `git add -u` actually undoes the submodule changes, so commit as-is.
    _ = subprocess.run(['git', 'commit', '-m', commit_message],
                       capture_output=True,
                       check=True)


def _get_remote_head_revision(remote_url: str) -> str:
    """Retrieves the HEAD revision for a remote git URL.

    Args:
        remote_url: The remote git URL to get HEAD from.

    Returns:
        The revision currently corresponding to HEAD.
    """
    cmd = [
        'git',
        'ls-remote',
        remote_url,
        'HEAD',
    ]
    proc = subprocess.run(cmd,
                          check=True,
                          text=True,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.STDOUT)
    head_revision = proc.stdout.strip().split()[0]
    return head_revision


def _get_roll_revision_range(target_revision: str | None,
                             dawn_deps: dict) -> ChangedRepo:
    """Determines the range being rolled.

    Args:
        target_revision: The revision being targeted for the roll. If not
            specified, the HEAD revision will be determined and used.
        dawn_deps: The parsed contents of the Dawn DEPS file.

    Returns:
        A ChangedRepo with the determined revision range.
    """
    old_revision = dawn_deps['vars'][CHROMIUM_REVISION_VAR]
    new_revision = target_revision
    if not new_revision:
        new_revision = _get_remote_head_revision(CHROMIUM_SRC_URL)
        logging.info('Using %s as the HEAD revision.', new_revision)
    return ChangedRepo(name='chromium/src',
                       url=CHROMIUM_SRC_URL,
                       old_revision=old_revision,
                       new_revision=new_revision)


def _read_gitiles_content(file_url: str) -> str:
    """Reads the contents of a file from Gitiles.

    Args:
        file_url: A URL pointing to a file to read from Gitiles.

    Returns:
        The string content of the specified file.
    """
    file_url = file_url + '?format=TEXT'
    r = requests.get(file_url)
    r.raise_for_status()
    return base64.b64decode(r.text).decode('utf-8')


def _read_remote_chromium_file(src_relative_path: str, revision: str) -> str:
    """Reads the contents of a Chromium file from Gitiles.

    Args:
        src_relative_path: A POSIX path to the file to read relative to
            chromium/src.
        revision: The Chromium revision to read the file contents at.
    """
    file_url = posixpath.join(CHROMIUM_SRC_URL, '+', revision,
                              src_relative_path)
    return _read_gitiles_content(file_url)


def _get_changed_deps_entries(dawn_deps: dict,
                              chromium_deps: dict) -> list[ChangedDepsEntry]:
    """Gets all entries that have changed between the two provided DEPS.

    Args:
        dawn_deps: The parsed content of the Dawn DEPS file.
        chromium_deps: The parsed content of the Chromium DEPS file.

    Returns:
        A list ChangedDepsEntry objects, each one corresponding to a change
        between the two DEPS files.
    """
    changed_entries = []
    changed_entries.extend(_get_changed_variables(dawn_deps, chromium_deps))
    changed_entries.extend(_get_changed_cipd(dawn_deps, chromium_deps))
    changed_entries.extend(_get_changed_gcs(dawn_deps, chromium_deps))
    changed_entries.extend(
        _get_changed_non_exported_repos(dawn_deps, chromium_deps))
    changed_entries.extend(_get_changed_exported_repos(dawn_deps))
    return changed_entries


def _get_changed_variables(dawn_deps: dict,
                           chromium_deps: dict) -> list[ChangedVariable]:
    """Gets all GN variables that have changed between the two provided DEPS.

    Args:
        dawn_deps: The parsed content of the Dawn DEPS file.
        chromium_deps: The parsed content of the Chromium DEPS file.

    Returns:
        A list of all variable entries that have changed between the two DEPS
        files.
    """
    changed_variables = []
    for dawn_var, chromium_var in SYNCED_VARIABLES.items():
        dawn_value = dawn_deps['vars'].get(dawn_var)
        chromium_value = chromium_deps['vars'].get(chromium_var)
        if not dawn_value:
            raise RuntimeError(
                f'Could not find Dawn GN variable {dawn_var}. Was it removed?')
        if not chromium_value:
            raise RuntimeError(
                f'Could not find Chromium GN variable {chromium_var}. Was it '
                f'removed?')
        changed_variables.append(
            ChangedVariable(
                name=dawn_var,
                old_version=dawn_value,
                new_version=chromium_value,
            ))
    return changed_variables


def _get_changed_cipd(dawn_deps: dict,
                      chromium_deps: dict) -> list[ChangedCipd]:
    """Gets all CIPD entries that have changed between the two provided DEPS.

    Args:
        dawn_deps: The parsed content of the Dawn DEPS file.
        chromium_deps: The parsed content of the Chromium DEPS file.

    Returns:
        A list of all CIPD DEPS entries that have changed between the two
        DEPS files.
    """
    changed_cipd = []
    for dawn_name in SYNCED_CIPD_DEPS:
        chromium_name = 'src/' + dawn_name
        if dawn_name not in dawn_deps['deps']:
            raise RuntimeError(
                f'Unable to find Dawn CIPD entry {dawn_name}. Was it removed?')
        if chromium_name not in chromium_deps['deps']:
            raise RuntimeErrror(
                f'Unable to find Chromium CIPD entry {chromium_name}. Was it '
                f'removed?')

        dawn_packages = [
            CipdPackage.from_dict(p)
            for p in dawn_deps['deps'][dawn_name]['packages']
        ]
        chromium_packages = [
            CipdPackage.from_dict(p)
            for p in chromium_deps['deps'][chromium_name]['packages']
        ]
        # Unlike GCS entries which provide all object content with a single
        # --revision, CIPD entries provide one package to update per
        # --revision. The behavior when a package within an entry disappears is
        # not clearly defined, so just fail if we ever see that. This should
        # rarely happen, though.
        dawn_package_names = set(p.package for p in dawn_packages)
        chromium_package_names = set(p.package for p in chromium_packages)
        if not dawn_package_names.issubset(chromium_package_names):
            raise RuntimeError(
                f'Packages for CIPD entry {dawn_name} appear to have changed. '
                f'Please manually sync the package list.')
        if dawn_packages != chromium_packages:
            changed_cipd.append(
                ChangedCipd(
                    name=dawn_name,
                    old_packages=dawn_packages,
                    new_packages=chromium_packages,
                ))
    return changed_cipd


def _get_changed_gcs(dawn_deps: dict, chromium_deps: dict) -> list[ChangedGcs]:
    """Gets all GCS entries that have changed between the two provided DEPS.

    Args:
        dawn_deps: The parsed content of the Dawn DEPS file.
        chromium_deps: The parsed content of the Chromium DEPS file.

    Returns:
        A list of all GCS DEPS entries that have changed between the two DEPS
        files.
    """
    changed_gcs = []
    for dawn_name in SYNCED_GCS_DEPS:
        chromium_name = 'src/' + dawn_name
        if dawn_name not in dawn_deps['deps']:
            raise RuntimeError(
                f'Unable to find Dawn GCS entry {dawn_name}. Was it removed?')
        if chromium_name not in chromium_deps['deps']:
            raise RuntimeError(
                f'Unable to find Chromium GCS entry {chromium_name}. Was it '
                f'removed?')

        dawn_objects = [
            GcsObject.from_dict(o)
            for o in dawn_deps['deps'][dawn_name]['objects']
        ]
        chromium_objects = [
            GcsObject.from_dict(o)
            for o in chromium_deps['deps'][chromium_name]['objects']
        ]
        if dawn_objects != chromium_objects:
            changed_gcs.append(
                ChangedGcs(
                    name=dawn_name,
                    old_objects=dawn_objects,
                    new_objects=chromium_objects,
                ))
    return changed_gcs


def _get_changed_non_exported_repos(dawn_deps: dict,
                                    chromium_deps: dict) -> list[ChangedRepo]:
    """Gets all non-exported repos that have changed between the DEPS files.

    Args:
        dawn_deps: The parsed content of the Dawn DEPS file.
        chromium_deps: The parsed content of the Chromium DEPS file.

    Returns:
        A list of all repo entries that have changed between the two DEPS files
        that are not exported pseudo-repos from Chromium.
    """
    changed_repos = []
    for dawn_name, chromium_name in SYNCED_REPOS.items():
        chromium_name = chromium_name or dawn_name
        chromium_name = 'src/' + chromium_name
        if dawn_name not in dawn_deps['deps']:
            raise RuntimeError(
                f'Unable to find Dawn repo {dawn_name}. Was it removed?')
        if chromium_name not in chromium_deps['deps']:
            raise RuntimeError(
                f'Unable to find Chromium repo {chromium_name}. Was it '
                f'removed?')

        url, dawn_revision = _get_url_and_revision(
            _get_raw_url_for_dep_entry(dawn_name, dawn_deps),
            dawn_deps['vars'])
        _, chromium_revision = _get_url_and_revision(
            _get_raw_url_for_dep_entry(chromium_name, chromium_deps),
            chromium_deps['vars'])
        if dawn_revision != chromium_revision:
            changed_repos.append(
                ChangedRepo(
                    name=dawn_name,
                    url=url,
                    old_revision=dawn_revision,
                    new_revision=chromium_revision,
                ))
    return changed_repos


def _get_changed_exported_repos(dawn_deps: dict) -> list[ChangedRepo]:
    """Gets all exported repos that have changed since the last roll.

    Args:
        dawn_deps: The parsed content of the Dawn DEPS file.

    Returns:
        A list of all repo entries for exported pseudo-repos from Chromium
        whose HEAD revision is different from the revision currently used by
        Dawn.
    """
    changed_repos = []
    for dawn_name, chromium_path in EXPORTED_CHROMIUM_REPOS.items():
        chromium_path = chromium_path or dawn_name
        if dawn_name not in dawn_deps['deps']:
            raise RuntimeError(
                f'Unable to find Dawn repo {dawn_name}. Was it removed?')
        url, dawn_revision = _get_url_and_revision(
            _get_raw_url_for_dep_entry(dawn_name, dawn_deps),
            dawn_deps['vars'])
        head_revision = _get_remote_head_revision(url)
        if dawn_revision != head_revision:
            changed_repos.append(
                ChangedRepo(
                    name=dawn_name,
                    url=url,
                    old_revision=dawn_revision,
                    new_revision=head_revision,
                ))
    return changed_repos


def _get_raw_url_for_dep_entry(dep_name: str, deps: dict) -> str:
    """Gets the URL associated with the specified DEPS entry.

    Args:
        dep_name: The name of the DEPS entry to retrieve the URL for.
        deps: The parsed DEPS content to extract information from.

    Returns:
        A string containing the URL associated with |dep_name|.
    """
    dep_entry = deps['deps'][dep_name]
    # Most entries are dicts, but it's also valid for an entry to just be a
    # git URL.
    if isinstance(dep_entry, str):
        return dep_entry
    return dep_entry['url']


def _get_url_and_revision(deps_url: str, vars: dict) -> tuple[str, str]:
    """Extracts the repo URL and revision from a DEPS url value.

    Known substitutions are also performed on the URL, e.g. replacing
    {chromium_git} with the actual Chromium git URL.

    Args:
        deps_url: The URL to operate on.
        vars: The 'vars' mapping from the parsed DEPS content that |deps_url|
            came from.

    Returns:
        A tuple (url, revision).
    """
    url, revision = deps_url.rsplit('@', 1)
    for var, value in vars.items():
        if not isinstance(value, str):
            continue
        search_str = f'{{{var}}}'
        url = url.replace(search_str, value)
    return url, revision


def _generate_commit_message(changed_entries: list[ChangedDepsEntry],
                             chromium_revision_range: ChangedRepo,
                             autoroll: bool) -> str:
    """Generates a commit message for a roll.

    Args:
        changed_entries: A list of all ChangedDepsEntry for this roll.
        chromium_revision_range: The ChangedRepo entry for Chromium for this
            roll.
        autoroll: Whether this roll is being done by the autoroller.

    Returns:
        A string containing the commit message to use.
    """
    commit_message_lines = []
    commit_message_lines.extend(
        _generate_chromium_section(chromium_revision_range, autoroll))
    commit_message_lines.append('')
    commit_message_lines.extend(_generate_repo_section(changed_entries))
    commit_message_lines.append('')
    commit_message_lines.extend(_generate_cipd_section(changed_entries))
    commit_message_lines.append('')
    commit_message_lines.extend(_generate_gcs_section(changed_entries))
    commit_message_lines.append('')
    commit_message_lines.extend(_generate_variables_section(changed_entries))
    commit_message_lines.append('')
    commit_message_lines.extend(_generate_footers_section(autoroll))
    return '\n'.join(commit_message_lines)


def _generate_chromium_section(chromium_revision_range: ChangedRepo,
                               autoroll: bool) -> list[str]:
    """Generates the commit message section for Chromium.

    Args:
        chromium_revision_range: The ChangedRepo entry for Chromium for this
            roll.
        autoroll: Whether this roll is being done by the autoroller.

    Returns:
        A list of strings containing lines to append to the commit message.
    """
    chromium_lines = []
    # Autorolls already add information about chromium_revision to the commit
    # message.
    if autoroll:
        return chromium_lines

    chromium_lines.extend([
        f'Roll chromium_revision {chromium_revision_range.revision_range()}',
        f'',
        f'Change log: {chromium_revision_range.log_link()}',
        f'Full diff: {chromium_revision_range.commit_link()}',
    ])
    return chromium_lines


def _generate_section_for_entry_type(entry_type: Type[ChangedDepsEntry],
                                     changed_entries: list[ChangedDepsEntry],
                                     empty_message: str,
                                     header: str) -> list[str]:
    """Generates the commit message section for a given ChangedDepsEntry type.

    Args:
        entry_type: The type of DEPS entry that should be included in this
            section.
        changed_entries: A list of all ChangedDepsEntry for this roll.
        empty_message: The message to use if no matching entries are found.
        header: The message to use at the beginning of the section if at least
            one matching entry is found.

    Returns:
        A list of strings containing lines to append to the commit message.
    """
    matching_entries = []
    for ce in changed_entries:
        if isinstance(ce, entry_type):
            matching_entries.append(ce)

    if not matching_entries:
        return [empty_message]

    matching_entries.sort(key=lambda e: e.name)
    lines = [header]
    for me in matching_entries:
        lines.extend(me.commit_message_lines())
    return lines


def _generate_variables_section(
        changed_entries: list[ChangedDepsEntry]) -> list[str]:
    """Generates the commit message section for changed variables.

    Args:
        changed_entries: A list of all ChangedDepsEntry for this roll.

    Returns:
        A list of strings containing lines to append to the commit message.
    """
    return _generate_section_for_entry_type(
        ChangedVariable, changed_entries,
        'No explicitly synced GN variables in this roll',
        'Explicitly synced GN variables:')


def _generate_cipd_section(
        changed_entries: list[ChangedDepsEntry]) -> list[str]:
    """Generates the commit message section for changed CIPD entries.

    Args:
        changed_entries: A list of all ChangedDepsEntry for this roll.

    Returns:
        A list of strings containing lines to append to the commit message.
    """
    return _generate_section_for_entry_type(
        ChangedCipd, changed_entries, 'No CIPD entries changed in this roll',
        'CIPD entries:')


def _generate_gcs_section(
        changed_entries: list[ChangedDepsEntry]) -> list[str]:
    """Generates the commit message section for changed GCS entries.

    Args:
        changed_entries: A list of all ChangedDepsEntry for this roll.

    Returns:
        A list of strings containing lines to append to the commit message.
    """
    return _generate_section_for_entry_type(
        ChangedGcs, changed_entries, 'No GCS entries changed in this roll',
        'GCS entries:')


def _generate_repo_section(
        changed_entries: list[ChangedDepsEntry]) -> list[str]:
    """Generates the commit message section for change repo entries.

    Args:
        changed_entries: A list of all ChangedDepsEntry for this roll.

    Returns:
        A list of strings containing lines to append to the commit message.
    """
    return _generate_section_for_entry_type(
        ChangedRepo, changed_entries, 'No repo entries changed in this roll',
        'Repo entries:')


def _generate_footers_section(autoroll: bool) -> list[str]:
    """Generates the commit message section for CL footers.

    Args:
        autoroll: Whether this roll is being done by the autoroller.

    Returns:
        A list of strings containing lines to append to the commit message.
    """
    lines = []
    if not autoroll:
        lines.append('Bug: None')
    return lines


def _apply_changed_deps(changed_entries: list[ChangedDepsEntry]) -> None:
    """Applies all changed DEPS entries to the Dawn DEPS file.

    Args:
        changed_entries: All calculated ChangedDepsEntry objects.
    """
    cmd = [
        'gclient',
        'setdep',
    ]
    for ce in changed_entries:
        cmd.extend(ce.setdep_args())
    subprocess.run(cmd, check=True)


def _parse_args() -> argparse.Namespace:
    """Parses and returns command line arguments."""
    parser = argparse.ArgumentParser('Roll DEPS entries shared with Chromium.')
    parser.add_argument('--verbose',
                        '-v',
                        action='store_true',
                        help='Increase logging verbosity')
    parser.add_argument('--autoroll',
                        action='store_true',
                        help='Run the script in autoroll mode')
    parser.add_argument('--ignore-unclean-workdir',
                        action='store_true',
                        help=('Ignore uncommitted changes and being on a '
                              'non-main branch'))
    parser.add_argument('--revision',
                        help=('A Chromium revision to roll to. If '
                              'unspecified, HEAD is used.'))
    return parser.parse_args()


def main() -> None:
    args = _parse_args()
    if args.verbose:
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.INFO)

    # The autoroller does not have locally synced dependencies, so we cannot use
    # the copy under //third_party. Instead, we have to assume that it has
    # depot_tools in PATH already.
    if not args.autoroll:
        _add_depot_tools_to_path()

    if not args.ignore_unclean_workdir:
        if not _is_tree_clean():
            raise RuntimeError(
                'Uncommitted or untracked files found. Please commit them or '
                'pass --ignore-unclean-workdir')
        _ensure_updated_main_branch()

    with open(DEPS_FILE, encoding='utf-8') as infile:
        dawn_deps = _parse_deps_file(infile.read())
    revision_range = _get_roll_revision_range(args.revision, dawn_deps)
    chromium_deps = _parse_deps_file(
        _read_remote_chromium_file('DEPS', revision_range.new_revision))
    changed_entries = _get_changed_deps_entries(dawn_deps, chromium_deps)
    # Create the commit message before adding the entry for the Chromium
    # revision since Chromium information is explicitly added to the message.
    commit_message = _generate_commit_message(changed_entries, revision_range,
                                              args.autoroll)
    # We change the variable directly instead of using ChangedRepo since
    # 'gclient setdep --revision' does not work for repos if there is no entry
    # in .gitmodules.
    changed_entries.append(
        ChangedVariable(
            name=CHROMIUM_REVISION_VAR,
            old_version=revision_range.old_revision,
            new_version=revision_range.new_revision,
        ))

    # When running as part of the autoroller, we update the existing commit
    # on the current branch.
    if not args.autoroll:
        _create_roll_branch()

    _apply_changed_deps(changed_entries)

    if args.autoroll:
        _amend_commit(commit_message)
    else:
        if _is_tree_clean():
            logging.info('No DEPS changes detected, skipping commit')
        else:
            _commit(commit_message)
            logging.info('Changes committed locally and are ready for upload')


if __name__ == '__main__':
    main()
