# Copyright 2016 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""Functions that implement the actual checks."""

import fnmatch
import json
import os
import platform
import re
import sys
from typing import Callable, NamedTuple

_path = os.path.realpath(__file__ + '/../..')
if sys.path[0] != _path:
    sys.path.insert(0, _path)
del _path

# pylint: disable=wrong-import-position
import rh.git
import rh.results
import rh.utils


class Placeholders(object):
    """Holder class for replacing ${vars} in arg lists.

    To add a new variable to replace in config files, just add it as a @property
    to this class using the form.  So to add support for BIRD:
      @property
      def var_BIRD(self):
        return <whatever this is>

    You can return either a string or an iterable (e.g. a list or tuple).
    """

    def __init__(self, diff=()):
        """Initialize.

        Args:
          diff: The list of files that changed.
        """
        self.diff = diff

    def expand_vars(self, args):
        """Perform place holder expansion on all of |args|.

        Args:
          args: The args to perform expansion on.

        Returns:
          The updated |args| list.
        """
        all_vars = set(self.vars())
        replacements = dict((var, self.get(var)) for var in all_vars)

        ret = []
        for arg in args:
            if arg.endswith('${PREUPLOAD_FILES_PREFIXED}'):
                if arg == '${PREUPLOAD_FILES_PREFIXED}':
                    assert len(ret) > 1, ('PREUPLOAD_FILES_PREFIXED cannot be '
                                          'the 1st or 2nd argument')
                    prev_arg = ret[-1]
                    ret = ret[0:-1]
                    for file in self.get('PREUPLOAD_FILES'):
                        ret.append(prev_arg)
                        ret.append(file)
                else:
                    prefix = arg[0:-len('${PREUPLOAD_FILES_PREFIXED}')]
                    ret.extend(
                        prefix + file for file in self.get('PREUPLOAD_FILES'))
            else:
                # First scan for exact matches
                for key, val in replacements.items():
                    var = '${' + key + '}'
                    if arg == var:
                        if isinstance(val, str):
                            ret.append(val)
                        else:
                            ret.extend(val)
                        # We break on first hit to avoid double expansion.
                        break
                else:
                    # If no exact matches, do an inline replacement.
                    def replace(m):
                        val = self.get(m.group(1))
                        if isinstance(val, str):
                            return val
                        return ' '.join(val)
                    ret.append(re.sub(r'\$\{(' + '|'.join(all_vars) + r')\}',
                                      replace, arg))
        return ret

    @classmethod
    def vars(cls):
        """Yield all replacement variable names."""
        for key in dir(cls):
            if key.startswith('var_'):
                yield key[4:]

    def get(self, var):
        """Helper function to get the replacement |var| value."""
        return getattr(self, f'var_{var}')

    @property
    def var_PREUPLOAD_COMMIT_MESSAGE(self):
        """The git commit message."""
        return os.environ.get('PREUPLOAD_COMMIT_MESSAGE', '')

    @property
    def var_PREUPLOAD_COMMIT(self):
        """The git commit sha1."""
        return os.environ.get('PREUPLOAD_COMMIT', '')

    @property
    def var_PREUPLOAD_FILES(self):
        """List of files modified in this git commit."""
        return [x.file for x in self.diff if x.status != 'D']

    @property
    def var_REPO_PATH(self):
        """The path to the project relative to the root"""
        return os.environ.get('REPO_PATH', '')

    @property
    def var_REPO_PROJECT(self):
        """The name of the project"""
        return os.environ.get('REPO_PROJECT', '')

    @property
    def var_REPO_ROOT(self):
        """The root of the repo (sub-manifest) checkout."""
        return rh.git.find_repo_root()

    @property
    def var_REPO_OUTER_ROOT(self):
        """The root of the repo (outer) checkout."""
        return rh.git.find_repo_root(outer=True)

    @property
    def var_BUILD_OS(self):
        """The build OS (see _get_build_os_name for details)."""
        return _get_build_os_name()


class ExclusionScope(object):
    """Exclusion scope for a hook.

    An exclusion scope can be used to determine if a hook has been disabled for
    a specific project.
    """

    def __init__(self, scope):
        """Initialize.

        Args:
          scope: A list of shell-style wildcards (fnmatch) or regular
              expression. Regular expressions must start with the ^ character.
        """
        self._scope = []
        for path in scope:
            if path.startswith('^'):
                self._scope.append(re.compile(path))
            else:
                self._scope.append(path)

    def __contains__(self, proj_dir):
        """Checks if |proj_dir| matches the excluded paths.

        Args:
          proj_dir: The relative path of the project.
        """
        for exclusion_path in self._scope:
            if hasattr(exclusion_path, 'match'):
                if exclusion_path.match(proj_dir):
                    return True
            elif fnmatch.fnmatch(proj_dir, exclusion_path):
                return True
        return False


class HookOptions(object):
    """Holder class for hook options."""

    def __init__(self, name, args, tool_paths):
        """Initialize.

        Args:
          name: The name of the hook.
          args: The override commandline arguments for the hook.
          tool_paths: A dictionary with tool names to paths.
        """
        self.name = name
        self._args = args
        self._tool_paths = tool_paths

    @staticmethod
    def expand_vars(args, diff=()):
        """Perform place holder expansion on all of |args|."""
        replacer = Placeholders(diff=diff)
        return replacer.expand_vars(args)

    def args(self, default_args=(), diff=()):
        """Gets the hook arguments, after performing place holder expansion.

        Args:
          default_args: The list to return if |self._args| is empty.
          diff: The list of files that changed in the current commit.

        Returns:
          A list with arguments.
        """
        args = self._args
        if not args:
            args = default_args

        return self.expand_vars(args, diff=diff)

    def tool_path(self, tool_name):
        """Gets the path in which the |tool_name| executable can be found.

        This function performs expansion for some place holders.  If the tool
        does not exist in the overridden |self._tool_paths| dictionary, the tool
        name will be returned and will be run from the user's $PATH.

        Args:
          tool_name: The name of the executable.

        Returns:
          The path of the tool with all optional place holders expanded.
        """
        assert tool_name in TOOL_PATHS
        if tool_name not in self._tool_paths:
            return TOOL_PATHS[tool_name]

        tool_path = os.path.normpath(self._tool_paths[tool_name])
        return self.expand_vars([tool_path])[0]


class CallableHook(NamedTuple):
    """A callable hook."""
    name: str
    hook: Callable
    scope: ExclusionScope


def _run(cmd, **kwargs):
    """Helper command for checks that tend to gather output."""
    kwargs.setdefault('combine_stdout_stderr', True)
    kwargs.setdefault('capture_output', True)
    kwargs.setdefault('check', False)
    # Make sure hooks run with stdin disconnected to avoid accidentally
    # interactive tools causing pauses.
    kwargs.setdefault('input', '')
    return rh.utils.run(cmd, **kwargs)


def _match_regex_list(subject, expressions):
    """Try to match a list of regular expressions to a string.

    Args:
      subject: The string to match regexes on.
      expressions: An iterable of regular expressions to check for matches with.

    Returns:
      Whether the passed in subject matches any of the passed in regexes.
    """
    for expr in expressions:
        if re.search(expr, subject):
            return True
    return False


def _filter_diff(diff, include_list, exclude_list=()):
    """Filter out files based on the conditions passed in.

    Args:
      diff: list of diff objects to filter.
      include_list: list of regex that when matched with a file path will cause
          it to be added to the output list unless the file is also matched with
          a regex in the exclude_list.
      exclude_list: list of regex that when matched with a file will prevent it
          from being added to the output list, even if it is also matched with a
          regex in the include_list.

    Returns:
      A list of filepaths that contain files matched in the include_list and not
      in the exclude_list.
    """
    filtered = []
    for d in diff:
        if (d.status != 'D' and
                _match_regex_list(d.file, include_list) and
                not _match_regex_list(d.file, exclude_list)):
            # We've got a match!
            filtered.append(d)
    return filtered


def _get_build_os_name():
    """Gets the build OS name.

    Returns:
      A string in a format usable to get prebuilt tool paths.
    """
    system = platform.system()
    if 'Darwin' in system or 'Macintosh' in system:
        return 'darwin-x86'

    # TODO: Add more values if needed.
    return 'linux-x86'


def _check_cmd(hook_name, project, commit, cmd, fixup_cmd=None, **kwargs):
    """Runs |cmd| and returns its result as a HookCommandResult."""
    return [rh.results.HookCommandResult(hook_name, project, commit,
                                         _run(cmd, **kwargs),
                                         fixup_cmd=fixup_cmd)]


# Where helper programs exist.
TOOLS_DIR = os.path.realpath(__file__ + '/../../tools')

def get_helper_path(tool):
    """Return the full path to the helper |tool|."""
    return os.path.join(TOOLS_DIR, tool)


def check_custom(project, commit, _desc, diff, options=None, **kwargs):
    """Run a custom hook."""
    return _check_cmd(options.name, project, commit, options.args((), diff),
                      **kwargs)


def check_aosp_license(project, commit, _desc, diff, options=None):
    """Checks that if all new added files has AOSP licenses"""

    exclude_dir_args = [x for x in options.args()
                        if x.startswith('--exclude-dirs=')]
    exclude_dirs = [x[len('--exclude-dirs='):].split(',')
                    for x in exclude_dir_args]
    exclude_list = [fr'^{x}/.*$' for dir_list in exclude_dirs for x in dir_list]

    # Filter diff based on extension.
    include_list = [
        # Coding languages and scripts.
        r".*\.c$",
        r".*\.cc$",
        r".*\.cpp$",
        r".*\.h$",
        r".*\.java$",
        r".*\.kt$",
        r".*\.rs$",
        r".*\.py$",
        r".*\.sh$",

        # Build and config files.
        r".*\.bp$",
        r".*\.xml$",
    ]
    diff = _filter_diff(diff, include_list, exclude_list)

    # Only check the new-added files.
    diff = [d for d in diff if d.status == 'A']

    if not diff:
        return None

    cmd = [get_helper_path('check_aosp_license.py'), '--commit_hash', commit]
    cmd += HookOptions.expand_vars(('${PREUPLOAD_FILES}',), diff)
    return _check_cmd('aosp_license', project, commit, cmd)


def check_bpfmt(project, commit, _desc, diff, options=None):
    """Checks that Blueprint files are formatted with bpfmt."""
    filtered = _filter_diff(diff, [r'\.bp$'])
    if not filtered:
        return None

    bpfmt = options.tool_path('bpfmt')
    bpfmt_options = options.args((), filtered)
    cmd = [bpfmt, '-d'] + bpfmt_options
    fixup_cmd = [bpfmt, '-w']
    if '-s' in bpfmt_options:
        fixup_cmd.append('-s')
    fixup_cmd.append('--')

    ret = []
    for d in filtered:
        data = rh.git.get_file_content(commit, d.file)
        result = _run(cmd, input=data)
        if result.stdout:
            ret.append(rh.results.HookResult(
                'bpfmt', project, commit,
                error=result.stdout,
                files=(d.file,),
                fixup_cmd=fixup_cmd))
    return ret


def check_checkpatch(project, commit, _desc, diff, options=None):
    """Run |diff| through the kernel's checkpatch.pl tool."""
    tool = get_helper_path('checkpatch.pl')
    cmd = ([tool, '-', '--root', project.dir] +
           options.args(('--ignore=GERRIT_CHANGE_ID',), diff))
    return _check_cmd('checkpatch.pl', project, commit, cmd,
                      input=rh.git.get_patch(commit))


def check_clang_format(project, commit, _desc, diff, options=None):
    """Run git clang-format on the commit."""
    tool = get_helper_path('clang-format.py')
    clang_format = options.tool_path('clang-format')
    git_clang_format = options.tool_path('git-clang-format')
    tool_args = (['--clang-format', clang_format, '--git-clang-format',
                  git_clang_format] +
                 options.args(('--style', 'file', '--commit', commit), diff))
    cmd = [tool] + tool_args
    fixup_cmd = [tool, '--fix'] + tool_args
    return _check_cmd('clang-format', project, commit, cmd,
                      fixup_cmd=fixup_cmd)


def check_google_java_format(project, commit, _desc, _diff, options=None):
    """Run google-java-format on the commit."""
    include_dir_args = [x for x in options.args()
                        if x.startswith('--include-dirs=')]
    include_dirs = [x[len('--include-dirs='):].split(',')
                    for x in include_dir_args]
    patterns = [fr'^{x}/.*\.java$' for dir_list in include_dirs
                for x in dir_list]
    if not patterns:
        patterns = [r'\.java$']

    filtered = _filter_diff(_diff, patterns)

    if not filtered:
        return None

    args = [x for x in options.args() if x not in include_dir_args]

    tool = get_helper_path('google-java-format.py')
    google_java_format = options.tool_path('google-java-format')
    google_java_format_diff = options.tool_path('google-java-format-diff')
    tool_args = ['--google-java-format', google_java_format,
                 '--google-java-format-diff', google_java_format_diff,
                 '--commit', commit] + args
    cmd = [tool] + tool_args + HookOptions.expand_vars(
                   ('${PREUPLOAD_FILES}',), filtered)
    fixup_cmd = [tool, '--fix'] + tool_args
    return [rh.results.HookCommandResult('google-java-format', project, commit,
                                         _run(cmd),
                                         files=[x.file for x in filtered],
                                         fixup_cmd=fixup_cmd)]


def check_ktfmt(project, commit, _desc, diff, options=None):
    """Checks that kotlin files are formatted with ktfmt."""

    include_dir_args = [x for x in options.args()
                        if x.startswith('--include-dirs=')]
    include_dirs = [x[len('--include-dirs='):].split(',')
                    for x in include_dir_args]
    patterns = [fr'^{x}/.*\.kt$' for dir_list in include_dirs
                for x in dir_list]
    if not patterns:
        patterns = [r'\.kt$']

    filtered = _filter_diff(diff, patterns)

    if not filtered:
        return None

    args = [x for x in options.args() if x not in include_dir_args]

    ktfmt = options.tool_path('ktfmt')
    cmd = [ktfmt, '--dry-run'] + args + HookOptions.expand_vars(
        ('${PREUPLOAD_FILES}',), filtered)
    result = _run(cmd)
    if result.stdout:
        fixup_cmd = [ktfmt] + args
        return [rh.results.HookResult(
            'ktfmt', project, commit, error='Formatting errors detected',
            files=[x.file for x in filtered], fixup_cmd=fixup_cmd)]
    return None


def check_commit_msg_bug_field(project, commit, desc, _diff, options=None):
    """Check the commit message for a 'Bug:' line."""
    field = 'Bug'
    regex = fr'^{field}: (None|[0-9]+(, [0-9]+)*)$'
    check_re = re.compile(regex)

    if options.args():
        raise ValueError(f'commit msg {field} check takes no options')

    found = []
    for line in desc.splitlines():
        if check_re.match(line):
            found.append(line)

    if not found:
        error = (
            f'Commit message is missing a "{field}:" line.  It must match the\n'
            f'following case-sensitive regex:\n\n    {regex}'
        )
    else:
        return None

    return [rh.results.HookResult(f'commit msg: "{field}:" check',
                                  project, commit, error=error)]


def check_commit_msg_changeid_field(project, commit, desc, _diff, options=None):
    """Check the commit message for a 'Change-Id:' line."""
    field = 'Change-Id'
    regex = fr'^{field}: I[a-f0-9]+$'
    check_re = re.compile(regex)

    if options.args():
        raise ValueError(f'commit msg {field} check takes no options')

    found = []
    for line in desc.splitlines():
        if check_re.match(line):
            found.append(line)

    if not found:
        error = (
            f'Commit message is missing a "{field}:" line.  It must match the\n'
            f'following case-sensitive regex:\n\n    {regex}'
        )
    elif len(found) > 1:
        error = (f'Commit message has too many "{field}:" lines.  There can be '
                 'only one.')
    else:
        return None

    return [rh.results.HookResult(f'commit msg: "{field}:" check',
                                  project, commit, error=error)]


PREBUILT_APK_MSG = """Commit message is missing required prebuilt APK
information.  To generate the information, use the aapt tool to dump badging
information of the APKs being uploaded, specify where the APK was built, and
specify whether the APKs are suitable for release:

    for apk in $(find . -name '*.apk' | sort); do
        echo "${apk}"
        ${AAPT} dump badging "${apk}" |
            grep -iE "(package: |sdkVersion:|targetSdkVersion:)" |
            sed -e "s/' /'\\n/g"
        echo
    done

It must match the following case-sensitive multiline regex searches:

    %s

For more information, see go/platform-prebuilt and go/android-prebuilt.

"""


def check_commit_msg_prebuilt_apk_fields(project, commit, desc, diff,
                                         options=None):
    """Check that prebuilt APK commits contain the required lines."""

    if options.args():
        raise ValueError('prebuilt apk check takes no options')

    filtered = _filter_diff(diff, [r'\.apk$'])
    if not filtered:
        return None

    regexes = [
        r'^package: .*$',
        r'^sdkVersion:.*$',
        r'^targetSdkVersion:.*$',
        r'^Built here:.*$',
        (r'^This build IS( NOT)? suitable for'
         r'( preview|( preview or)? public) release'
         r'( but IS NOT suitable for public release)?\.$')
    ]

    missing = []
    for regex in regexes:
        if not re.search(regex, desc, re.MULTILINE):
            missing.append(regex)

    if missing:
        error = PREBUILT_APK_MSG % '\n    '.join(missing)
    else:
        return None

    return [rh.results.HookResult('commit msg: "prebuilt apk:" check',
                                  project, commit, error=error)]


TEST_MSG = """Commit message is missing a "Test:" line.  It must match the
following case-sensitive regex:

    %s

The Test: stanza is free-form and should describe how you tested your change.
As a CL author, you'll have a consistent place to describe the testing strategy
you use for your work. As a CL reviewer, you'll be reminded to discuss testing
as part of your code review, and you'll more easily replicate testing when you
patch in CLs locally.

Some examples below:

Test: make WITH_TIDY=1 mmma art
Test: make test-art
Test: manual - took a photo
Test: refactoring CL. Existing unit tests still pass.

Check the git history for more examples. It's a free-form field, so we urge
you to develop conventions that make sense for your project. Note that many
projects use exact test commands, which are perfectly fine.

Adding good automated tests with new code is critical to our goals of keeping
the system stable and constantly improving quality. Please use Test: to
highlight this area of your development. And reviewers, please insist on
high-quality Test: descriptions.
"""


def check_commit_msg_test_field(project, commit, desc, _diff, options=None):
    """Check the commit message for a 'Test:' line."""
    field = 'Test'
    regex = fr'^{field}: .*$'
    check_re = re.compile(regex)

    if options.args():
        raise ValueError(f'commit msg {field} check takes no options')

    found = []
    for line in desc.splitlines():
        if check_re.match(line):
            found.append(line)

    if not found:
        error = TEST_MSG % (regex)
    else:
        return None

    return [rh.results.HookResult(f'commit msg: "{field}:" check',
                                  project, commit, error=error)]


RELNOTE_MISSPELL_MSG = """Commit message contains something that looks
similar to the "Relnote:" tag.  It must match the regex:

    %s

The Relnote: stanza is free-form and should describe what developers need to
know about your change.

Some examples below:

Relnote: "Added a new API `Class#isBetter` to determine whether or not the
class is better"
Relnote: Fixed an issue where the UI would hang on a double tap.

Check the git history for more examples. It's a free-form field, so we urge
you to develop conventions that make sense for your project.
"""

RELNOTE_MISSING_QUOTES_MSG = """Commit message contains something that looks
similar to the "Relnote:" tag but might be malformatted.  For multiline
release notes, you need to include a starting and closing quote.

Multi-line Relnote example:

Relnote: "Added a new API `Class#getSize` to get the size of the class.
    This is useful if you need to know the size of the class."

Single-line Relnote example:

Relnote: Added a new API `Class#containsData`
"""

RELNOTE_INVALID_QUOTES_MSG = """Commit message contains something that looks
similar to the "Relnote:" tag but might be malformatted.  If you are using
quotes that do not mark the start or end of a Relnote, you need to escape them
with a backslash.

Non-starting/non-ending quote Relnote examples:

Relnote: "Fixed an error with `Class#getBar()` where \"foo\" would be returned
in edge cases."
Relnote: Added a new API to handle strings like \"foo\"
"""

def check_commit_msg_relnote_field_format(project, commit, desc, _diff,
                                          options=None):
    """Check the commit for one correctly formatted 'Relnote:' line.

    Checks the commit message for two things:
    (1) Checks for possible misspellings of the 'Relnote:' tag.
    (2) Ensures that multiline release notes are properly formatted with a
    starting quote and an endling quote.
    (3) Checks that release notes that contain non-starting or non-ending
    quotes are escaped with a backslash.
    """
    field = 'Relnote'
    regex_relnote = fr'^{field}:.*$'
    check_re_relnote = re.compile(regex_relnote, re.IGNORECASE)

    if options.args():
        raise ValueError(f'commit msg {field} check takes no options')

    # Check 1: Check for possible misspellings of the `Relnote:` field.

    # Regex for misspelled fields.
    possible_field_misspells = {
        'Relnotes', 'ReleaseNote',
        'Rel-note', 'Rel note',
        'rel-notes', 'releasenotes',
        'release-note', 'release-notes',
    }
    re_possible_field_misspells = '|'.join(possible_field_misspells)
    regex_field_misspells = fr'^({re_possible_field_misspells}): .*$'
    check_re_field_misspells = re.compile(regex_field_misspells, re.IGNORECASE)

    ret = []
    for line in desc.splitlines():
        if check_re_field_misspells.match(line):
            error = RELNOTE_MISSPELL_MSG % (regex_relnote, )
            ret.append(
                rh.results.HookResult(
                    f'commit msg: "{field}:" tag spelling error',
                    project, commit, error=error))

    # Check 2: Check that multiline Relnotes are quoted.

    check_re_empty_string = re.compile(r'^$')

    # Regex to find other fields that could be used.
    regex_other_fields = r'^[a-zA-Z0-9-]+:'
    check_re_other_fields = re.compile(regex_other_fields)

    desc_lines = desc.splitlines()
    for i, cur_line in enumerate(desc_lines):
        # Look for a Relnote tag that is before the last line and
        # lacking any quotes.
        if (check_re_relnote.match(cur_line) and
                i < len(desc_lines) - 1 and
                '"' not in cur_line):
            next_line = desc_lines[i + 1]
            # Check that the next line does not contain any other field
            # and it's not an empty string.
            if (not check_re_other_fields.findall(next_line) and
                    not check_re_empty_string.match(next_line)):
                ret.append(
                    rh.results.HookResult(
                        f'commit msg: "{field}:" tag missing quotes',
                        project, commit, error=RELNOTE_MISSING_QUOTES_MSG))
                break

    # Check 3: Check that multiline Relnotes contain matching quotes.
    first_quote_found = False
    second_quote_found = False
    for cur_line in desc_lines:
        contains_quote = '"' in cur_line
        contains_field = check_re_other_fields.findall(cur_line)
        # If we have found the first quote and another field, break and fail.
        if first_quote_found and contains_field:
            break
        # If we have found the first quote, this line contains a quote,
        # and this line is not another field, break and succeed.
        if first_quote_found and contains_quote:
            second_quote_found = True
            break
        # Check that the `Relnote:` tag exists and it contains a starting quote.
        if check_re_relnote.match(cur_line) and contains_quote:
            first_quote_found = True
            # A single-line Relnote containing a start and ending triple quote
            # is valid.
            if cur_line.count('"""') == 2:
                second_quote_found = True
                break
            # A single-line Relnote containing a start and ending quote
            # is valid.
            if cur_line.count('"') - cur_line.count('\\"') == 2:
                second_quote_found = True
                break
    if first_quote_found != second_quote_found:
        ret.append(
            rh.results.HookResult(
                f'commit msg: "{field}:" tag missing closing quote',
                project, commit, error=RELNOTE_MISSING_QUOTES_MSG))

    # Check 4: Check that non-starting or non-ending quotes are escaped with a
    # backslash.
    line_needs_checking = False
    uses_invalid_quotes = False
    for cur_line in desc_lines:
        if check_re_other_fields.findall(cur_line):
            line_needs_checking = False
        on_relnote_line = check_re_relnote.match(cur_line)
        # Determine if we are parsing the base `Relnote:` line.
        if on_relnote_line and '"' in cur_line:
            line_needs_checking = True
            # We don't think anyone will type '"""' and then forget to
            # escape it, so we're not checking for this.
            if '"""' in cur_line:
                break
        if line_needs_checking:
            stripped_line = re.sub(fr'^{field}:', '', cur_line,
                                   flags=re.IGNORECASE).strip()
            for i, character in enumerate(stripped_line):
                if i == 0:
                    # Case 1: Valid quote at the beginning of the
                    # base `Relnote:` line.
                    if on_relnote_line:
                        continue
                    # Case 2: Invalid quote at the beginning of following
                    # lines, where we are not terminating the release note.
                    if character == '"' and stripped_line != '"':
                        uses_invalid_quotes = True
                        break
                # Case 3: Check all other cases.
                if (character == '"'
                        and 0 < i < len(stripped_line) - 1
                        and stripped_line[i-1] != '"'
                        and stripped_line[i-1] != "\\"):
                    uses_invalid_quotes = True
                    break

    if uses_invalid_quotes:
        ret.append(rh.results.HookResult(
            f'commit msg: "{field}:" tag using unescaped quotes',
            project, commit, error=RELNOTE_INVALID_QUOTES_MSG))
    return ret


RELNOTE_REQUIRED_CURRENT_TXT_MSG = """\
Commit contains a change to current.txt or public_plus_experimental_current.txt,
but the commit message does not contain the required `Relnote:` tag.  It must
match the regex:

    %s

The Relnote: stanza is free-form and should describe what developers need to
know about your change.  If you are making infrastructure changes, you
can set the Relnote: stanza to be "N/A" for the commit to not be included
in release notes.

Some examples:

Relnote: "Added a new API `Class#isBetter` to determine whether or not the
class is better"
Relnote: Fixed an issue where the UI would hang on a double tap.
Relnote: N/A

Check the git history for more examples.
"""

def check_commit_msg_relnote_for_current_txt(project, commit, desc, diff,
                                             options=None):
    """Check changes to current.txt contain the 'Relnote:' stanza."""
    field = 'Relnote'
    regex = fr'^{field}: .+$'
    check_re = re.compile(regex, re.IGNORECASE)

    if options.args():
        raise ValueError(f'commit msg {field} check takes no options')

    filtered = _filter_diff(
        diff,
        [r'(^|/)(public_plus_experimental_current|current)\.txt$']
    )
    # If the commit does not contain a change to *current.txt, then this repo
    # hook check no longer applies.
    if not filtered:
        return None

    found = []
    for line in desc.splitlines():
        if check_re.match(line):
            found.append(line)

    if not found:
        error = RELNOTE_REQUIRED_CURRENT_TXT_MSG % (regex)
    else:
        return None

    return [rh.results.HookResult(f'commit msg: "{field}:" check',
                                  project, commit, error=error)]


def check_cpplint(project, commit, _desc, diff, options=None):
    """Run cpplint."""
    # This list matches what cpplint expects.  We could run on more (like .cxx),
    # but cpplint would just ignore them.
    filtered = _filter_diff(diff, [r'\.(cc|h|cpp|cu|cuh)$'])
    if not filtered:
        return None

    cpplint = options.tool_path('cpplint')
    cmd = [cpplint] + options.args(('${PREUPLOAD_FILES}',), filtered)
    return _check_cmd('cpplint', project, commit, cmd)


def check_gofmt(project, commit, _desc, diff, options=None):
    """Checks that Go files are formatted with gofmt."""
    filtered = _filter_diff(diff, [r'\.go$'])
    if not filtered:
        return None

    gofmt = options.tool_path('gofmt')
    cmd = [gofmt, '-l'] + options.args()
    fixup_cmd = [gofmt, '-w'] + options.args()

    ret = []
    for d in filtered:
        data = rh.git.get_file_content(commit, d.file)
        result = _run(cmd, input=data)
        if result.stdout:
            ret.append(rh.results.HookResult(
                'gofmt', project, commit, error=result.stdout,
                files=(d.file,), fixup_cmd=fixup_cmd))
    return ret


def check_json(project, commit, _desc, diff, options=None):
    """Verify json files are valid."""
    if options.args():
        raise ValueError('json check takes no options')

    filtered = _filter_diff(diff, [r'\.json$'])
    if not filtered:
        return None

    ret = []
    for d in filtered:
        data = rh.git.get_file_content(commit, d.file)
        try:
            json.loads(data)
        except ValueError as e:
            ret.append(rh.results.HookResult(
                'json', project, commit, error=str(e),
                files=(d.file,)))
    return ret


def _check_pylint(project, commit, _desc, diff, extra_args=None, options=None):
    """Run pylint."""
    filtered = _filter_diff(diff, [r'\.py$'])
    if not filtered:
        return None

    if extra_args is None:
        extra_args = []

    pylint = options.tool_path('pylint')
    cmd = [
        get_helper_path('pylint.py'),
        '--executable-path', pylint,
    ] + extra_args + options.args(('${PREUPLOAD_FILES}',), filtered)
    return _check_cmd('pylint', project, commit, cmd)


def check_pylint2(project, commit, desc, diff, options=None):
    """Run pylint through Python 2."""
    return _check_pylint(project, commit, desc, diff, options=options)


def check_pylint3(project, commit, desc, diff, options=None):
    """Run pylint through Python 3."""
    return _check_pylint(project, commit, desc, diff,
                         extra_args=['--py3'],
                         options=options)


def check_rustfmt(project, commit, _desc, diff, options=None):
    """Run "rustfmt --check" on diffed rust files"""
    filtered = _filter_diff(diff, [r'\.rs$'])
    if not filtered:
        return None

    rustfmt = options.tool_path('rustfmt')
    cmd = [rustfmt] + options.args((), filtered)
    ret = []
    for d in filtered:
        data = rh.git.get_file_content(commit, d.file)
        result = _run(cmd, input=data)
        # If the parsing failed, stdout will contain enough details on the
        # location of the error.
        if result.returncode:
            ret.append(rh.results.HookResult(
                'rustfmt', project, commit, error=result.stdout,
                files=(d.file,)))
            continue
        # TODO(b/164111102): rustfmt stable does not support --check on stdin.
        # If no error is reported, compare stdin with stdout.
        if data != result.stdout:
            ret.append(rh.results.HookResult(
                'rustfmt', project, commit, error='Files not formatted',
                files=(d.file,), fixup_cmd=cmd))
    return ret


def check_xmllint(project, commit, _desc, diff, options=None):
    """Run xmllint."""
    # XXX: Should we drop most of these and probe for <?xml> tags?
    extensions = frozenset((
        'dbus-xml',  # Generated DBUS interface.
        'dia',       # File format for Dia.
        'dtd',       # Document Type Definition.
        'fml',       # Fuzzy markup language.
        'form',      # Forms created by IntelliJ GUI Designer.
        'fxml',      # JavaFX user interfaces.
        'glade',     # Glade user interface design.
        'grd',       # GRIT translation files.
        'iml',       # Android build modules?
        'kml',       # Keyhole Markup Language.
        'mxml',      # Macromedia user interface markup language.
        'nib',       # OS X Cocoa Interface Builder.
        'plist',     # Property list (for OS X).
        'pom',       # Project Object Model (for Apache Maven).
        'rng',       # RELAX NG schemas.
        'sgml',      # Standard Generalized Markup Language.
        'svg',       # Scalable Vector Graphics.
        'uml',       # Unified Modeling Language.
        'vcproj',    # Microsoft Visual Studio project.
        'vcxproj',   # Microsoft Visual Studio project.
        'wxs',       # WiX Transform File.
        'xhtml',     # XML HTML.
        'xib',       # OS X Cocoa Interface Builder.
        'xlb',       # Android locale bundle.
        'xml',       # Extensible Markup Language.
        'xsd',       # XML Schema Definition.
        'xsl',       # Extensible Stylesheet Language.
    ))

    filtered = _filter_diff(diff, [r'\.(' + '|'.join(extensions) + r')$'])
    if not filtered:
        return None

    # TODO: Figure out how to integrate schema validation.
    # XXX: Should we use python's XML libs instead?
    cmd = ['xmllint'] + options.args(('${PREUPLOAD_FILES}',), filtered)

    return _check_cmd('xmllint', project, commit, cmd)


def check_android_test_mapping(project, commit, _desc, diff, options=None):
    """Verify Android TEST_MAPPING files are valid."""
    if options.args():
        raise ValueError('Android TEST_MAPPING check takes no options')
    filtered = _filter_diff(diff, [r'(^|.*/)TEST_MAPPING$'])
    if not filtered:
        return None

    testmapping_format = options.tool_path('android-test-mapping-format')
    testmapping_args = ['--commit', commit]
    cmd = [testmapping_format] + options.args(
        (project.dir, '${PREUPLOAD_FILES}'), filtered) + testmapping_args
    return _check_cmd('android-test-mapping-format', project, commit, cmd)


def check_aidl_format(project, commit, _desc, diff, options=None):
    """Checks that AIDL files are formatted with aidl-format."""
    # All *.aidl files except for those under aidl_api directory.
    filtered = _filter_diff(diff, [r'\.aidl$'], [r'(^|/)aidl_api/'])
    if not filtered:
        return None
    aidl_format = options.tool_path('aidl-format')
    clang_format = options.tool_path('clang-format')
    diff_cmd = [aidl_format, '-d', '--clang-format-path', clang_format] + \
            options.args((), filtered)
    ret = []
    for d in filtered:
        data = rh.git.get_file_content(commit, d.file)
        result = _run(diff_cmd, input=data)
        if result.stdout:
            fixup_cmd = [aidl_format, '-w', '--clang-format-path', clang_format]
            ret.append(rh.results.HookResult(
                'aidl-format', project, commit, error=result.stdout,
                files=(d.file,), fixup_cmd=fixup_cmd))
    return ret


# Hooks that projects can opt into.
# Note: Make sure to keep the top level README.md up to date when adding more!
BUILTIN_HOOKS = {
    'aidl_format': check_aidl_format,
    'android_test_mapping_format': check_android_test_mapping,
    'aosp_license': check_aosp_license,
    'bpfmt': check_bpfmt,
    'checkpatch': check_checkpatch,
    'clang_format': check_clang_format,
    'commit_msg_bug_field': check_commit_msg_bug_field,
    'commit_msg_changeid_field': check_commit_msg_changeid_field,
    'commit_msg_prebuilt_apk_fields': check_commit_msg_prebuilt_apk_fields,
    'commit_msg_relnote_field_format': check_commit_msg_relnote_field_format,
    'commit_msg_relnote_for_current_txt':
        check_commit_msg_relnote_for_current_txt,
    'commit_msg_test_field': check_commit_msg_test_field,
    'cpplint': check_cpplint,
    'gofmt': check_gofmt,
    'google_java_format': check_google_java_format,
    'jsonlint': check_json,
    'ktfmt': check_ktfmt,
    'pylint': check_pylint3,
    'pylint2': check_pylint2,
    'pylint3': check_pylint3,
    'rustfmt': check_rustfmt,
    'xmllint': check_xmllint,
}

# Additional tools that the hooks can call with their default values.
# Note: Make sure to keep the top level README.md up to date when adding more!
TOOL_PATHS = {
    'aidl-format': 'aidl-format',
    'android-test-mapping-format':
        os.path.join(TOOLS_DIR, 'android_test_mapping_format.py'),
    'bpfmt': 'bpfmt',
    'clang-format': 'clang-format',
    'cpplint': os.path.join(TOOLS_DIR, 'cpplint.py'),
    'git-clang-format': 'git-clang-format',
    'gofmt': 'gofmt',
    'google-java-format': 'google-java-format',
    'google-java-format-diff': 'google-java-format-diff.py',
    'ktfmt': 'ktfmt',
    'pylint': 'pylint',
    'rustfmt': 'rustfmt',
}
