# Copyright 2019 The ANGLE 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.
"""Top-level presubmit script for code generation.

See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
for more details on the presubmit API built into depot_tools.
"""

import itertools
import os
import re
import shutil
import subprocess
import sys
import tempfile
import textwrap
import pathlib

# This line is 'magic' in that git-cl looks for it to decide whether to
# use Python3 instead of Python2 when running the code in this file.
USE_PYTHON3 = True

# Fragment of a regular expression that matches C/C++ and Objective-C++ implementation files and headers.
_IMPLEMENTATION_AND_HEADER_EXTENSIONS = r'\.(c|cc|cpp|cxx|mm|h|hpp|hxx)$'

# Fragment of a regular expression that matches C++ and Objective-C++ header files.
_HEADER_EXTENSIONS = r'\.(h|hpp|hxx)$'

_PRIMARY_EXPORT_TARGETS = [
    '//:libEGL',
    '//:libGLESv1_CM',
    '//:libGLESv2',
    '//:translator',
]


def _SplitIntoMultipleCommits(description_text):
    paragraph_split_pattern = r"(?m)(^\s*$\n)"
    multiple_paragraphs = re.split(paragraph_split_pattern, description_text)
    multiple_commits = [""]
    change_id_pattern = re.compile(r"(?m)^Change-Id: [a-zA-Z0-9]*$")
    for paragraph in multiple_paragraphs:
        multiple_commits[-1] += paragraph
        if change_id_pattern.search(paragraph):
            multiple_commits.append("")
    if multiple_commits[-1] == "":
        multiple_commits.pop()
    return multiple_commits


def _CheckCommitMessageFormatting(input_api, output_api):

    def _IsLineBlank(line):
        return line.isspace() or line == ""

    def _PopBlankLines(lines, reverse=False):
        if reverse:
            while len(lines) > 0 and _IsLineBlank(lines[-1]):
                lines.pop()
        else:
            while len(lines) > 0 and _IsLineBlank(lines[0]):
                lines.pop(0)

    def _IsTagLine(line):
        return ":" in line

    def _CheckTabInCommit(lines):
        return all([line.find("\t") == -1 for line in lines])

    allowlist_strings = ['Revert', 'Roll', 'Manual roll', 'Reland', 'Re-land']
    summary_linelength_warning_lower_limit = 65
    summary_linelength_warning_upper_limit = 70
    description_linelength_limit = 72

    git_output = input_api.change.DescriptionText()

    multiple_commits = _SplitIntoMultipleCommits(git_output)
    errors = []

    for k in range(len(multiple_commits)):
        commit_msg_lines = multiple_commits[k].splitlines()
        commit_number = len(multiple_commits) - k
        commit_tag = "Commit " + str(commit_number) + ":"
        commit_msg_line_numbers = {}
        for i in range(len(commit_msg_lines)):
            commit_msg_line_numbers[commit_msg_lines[i]] = i + 1
        _PopBlankLines(commit_msg_lines, True)
        _PopBlankLines(commit_msg_lines, False)
        allowlisted = False
        if len(commit_msg_lines) > 0:
            for allowlist_string in allowlist_strings:
                if commit_msg_lines[0].startswith(allowlist_string):
                    allowlisted = True
                    break
        if allowlisted:
            continue

        if not _CheckTabInCommit(commit_msg_lines):
            errors.append(
                output_api.PresubmitError(commit_tag + "Tabs are not allowed in commit message."))

        # the tags paragraph is at the end of the message
        # the break between the tags paragraph is the first line without ":"
        # this is sufficient because if a line is blank, it will not have ":"
        last_paragraph_line_count = 0
        while len(commit_msg_lines) > 0 and _IsTagLine(commit_msg_lines[-1]):
            last_paragraph_line_count += 1
            commit_msg_lines.pop()
        if last_paragraph_line_count == 0:
            errors.append(
                output_api.PresubmitError(
                    commit_tag +
                    "Please ensure that there are tags (e.g., Bug:, Test:) in your description."))
        if len(commit_msg_lines) > 0:
            if not _IsLineBlank(commit_msg_lines[-1]):
                output_api.PresubmitError(commit_tag +
                                          "Please ensure that there exists 1 blank line " +
                                          "between tags and description body.")
            else:
                # pop the blank line between tag paragraph and description body
                commit_msg_lines.pop()
                if len(commit_msg_lines) > 0 and _IsLineBlank(commit_msg_lines[-1]):
                    errors.append(
                        output_api.PresubmitError(
                            commit_tag + 'Please ensure that there exists only 1 blank line '
                            'between tags and description body.'))
                    # pop all the remaining blank lines between tag and description body
                    _PopBlankLines(commit_msg_lines, True)
        if len(commit_msg_lines) == 0:
            errors.append(
                output_api.PresubmitError(commit_tag +
                                          'Please ensure that your description summary'
                                          ' and description body are not blank.'))
            continue

        if summary_linelength_warning_lower_limit <= len(commit_msg_lines[0]) \
        <= summary_linelength_warning_upper_limit:
            errors.append(
                output_api.PresubmitPromptWarning(
                    commit_tag + "Your description summary should be on one line of " +
                    str(summary_linelength_warning_lower_limit - 1) + " or less characters."))
        elif len(commit_msg_lines[0]) > summary_linelength_warning_upper_limit:
            errors.append(
                output_api.PresubmitError(
                    commit_tag + "Please ensure that your description summary is on one line of " +
                    str(summary_linelength_warning_lower_limit - 1) + " or less characters."))
        commit_msg_lines.pop(0)  # get rid of description summary
        if len(commit_msg_lines) == 0:
            continue
        if not _IsLineBlank(commit_msg_lines[0]):
            errors.append(
                output_api.PresubmitError(commit_tag +
                                          'Please ensure the summary is only 1 line and '
                                          'there is 1 blank line between the summary '
                                          'and description body.'))
        else:
            commit_msg_lines.pop(0)  # pop first blank line
            if len(commit_msg_lines) == 0:
                continue
            if _IsLineBlank(commit_msg_lines[0]):
                errors.append(
                    output_api.PresubmitError(commit_tag +
                                              'Please ensure that there exists only 1 blank line '
                                              'between description summary and description body.'))
                # pop all the remaining blank lines between
                # description summary and description body
                _PopBlankLines(commit_msg_lines)

        # loop through description body
        while len(commit_msg_lines) > 0:
            line = commit_msg_lines.pop(0)
            # lines starting with 4 spaces, quotes or lines without space(urls)
            # are exempt from length check
            if line.startswith("    ") or line.startswith("> ") or " " not in line:
                continue
            if len(line) > description_linelength_limit:
                errors.append(
                    output_api.PresubmitError(
                        commit_tag + 'Line ' + str(commit_msg_line_numbers[line]) +
                        ' is too long.\n' + '"' + line + '"\n' + 'Please wrap it to ' +
                        str(description_linelength_limit) + ' characters. ' +
                        "Lines without spaces or lines starting with 4 spaces are exempt."))
                break
    return errors


def _CheckChangeHasBugField(input_api, output_api):
    """Requires that the changelist have a Bug: field from a known project."""
    bugs = input_api.change.BugsFromDescription()

    # The bug must be in the form of "project:number".  None is also accepted, which is used by
    # rollers as well as in very minor changes.
    if len(bugs) == 1 and bugs[0] == 'None':
        return []

    projects = [
        'angleproject:', 'chromium:', 'dawn:', 'fuchsia:', 'skia:', 'swiftshader:', 'tint:', 'b/'
    ]
    bug_regex = re.compile(r"([a-z]+[:/])(\d+)")
    errors = []
    extra_help = False

    if not bugs:
        errors.append('Please ensure that your description contains\n'
                      'Bug: bugtag\n'
                      'directly above the Change-Id tag (no empty line in-between)')
        extra_help = True

    for bug in bugs:
        if bug == 'None':
            errors.append('Invalid bug tag "None" in presence of other bug tags.')
            continue

        match = re.match(bug_regex, bug)
        if match == None or bug != match.group(0) or match.group(1) not in projects:
            errors.append('Incorrect bug tag "' + bug + '".')
            extra_help = True

    if extra_help:
        change_ids = re.findall('^Change-Id:', input_api.change.FullDescriptionText(), re.M)
        if len(change_ids) > 1:
            errors.append('Note: multiple Change-Id tags found in description')

        errors.append('''Acceptable bugtags:
    project:bugnumber - where project is one of ({projects})
    b/bugnumber - for Buganizer/IssueTracker bugs
'''.format(projects=', '.join(p[:-1] for p in projects if p != 'b/')))

    return [output_api.PresubmitError('\n\n'.join(errors))] if errors else []


def _CheckCodeGeneration(input_api, output_api):

    class Msg(output_api.PresubmitError):
        """Specialized error message"""

        def __init__(self, message, **kwargs):
            super(output_api.PresubmitError, self).__init__(
                message,
                long_text='Please ensure your ANGLE repositiory is synced to tip-of-tree\n'
                'and all ANGLE DEPS are fully up-to-date by running gclient sync.\n'
                '\n'
                'If that fails, run scripts/run_code_generation.py to refresh generated hashes.\n'
                '\n'
                'If you are building ANGLE inside Chromium you must bootstrap ANGLE\n'
                'before gclient sync. See the DevSetup documentation for more details.\n',
                **kwargs)

    code_gen_path = input_api.os_path.join(input_api.PresubmitLocalPath(),
                                           'scripts/run_code_generation.py')
    cmd_name = 'run_code_generation'
    cmd = [input_api.python3_executable, code_gen_path, '--verify-no-dirty']
    test_cmd = input_api.Command(name=cmd_name, cmd=cmd, kwargs={}, message=Msg)
    if input_api.verbose:
        print('Running ' + cmd_name)
    return input_api.RunTests([test_cmd])


# Taken directly from Chromium's PRESUBMIT.py
def _CheckNewHeaderWithoutGnChange(input_api, output_api):
    """Checks that newly added header files have corresponding GN changes.
  Note that this is only a heuristic. To be precise, run script:
  build/check_gn_headers.py.
  """

    def headers(f):
        return input_api.FilterSourceFile(f, files_to_check=(r'.+%s' % _HEADER_EXTENSIONS,))

    new_headers = []
    for f in input_api.AffectedSourceFiles(headers):
        if f.Action() != 'A':
            continue
        new_headers.append(f.LocalPath())

    def gn_files(f):
        return input_api.FilterSourceFile(f, files_to_check=(r'.+\.gn',))

    all_gn_changed_contents = ''
    for f in input_api.AffectedSourceFiles(gn_files):
        for _, line in f.ChangedContents():
            all_gn_changed_contents += line

    problems = []
    for header in new_headers:
        basename = input_api.os_path.basename(header)
        if basename not in all_gn_changed_contents:
            problems.append(header)

    if problems:
        return [
            output_api.PresubmitPromptWarning(
                'Missing GN changes for new header files',
                items=sorted(problems),
                long_text='Please double check whether newly added header files need '
                'corresponding changes in gn or gni files.\nThis checking is only a '
                'heuristic. Run build/check_gn_headers.py to be precise.\n'
                'Read https://crbug.com/661774 for more info.')
        ]
    return []


def _CheckExportValidity(input_api, output_api):
    outdir = tempfile.mkdtemp()
    # shell=True is necessary on Windows, as otherwise subprocess fails to find
    # either 'gn' or 'vpython3' even if they are findable via PATH.
    use_shell = input_api.is_windows
    try:
        try:
            subprocess.check_output(
                [sys.executable, 'third_party/depot_tools/gn.py', 'gen', outdir], shell=use_shell)
        except subprocess.CalledProcessError as e:
            return [
                output_api.PresubmitError('Unable to run gn gen for export_targets.py: %s' %
                                          e.output.decode())
            ]
        export_target_script = os.path.join(input_api.PresubmitLocalPath(), 'scripts',
                                            'export_targets.py')
        try:
            subprocess.check_output(
                ['vpython3', export_target_script, outdir] + _PRIMARY_EXPORT_TARGETS,
                stderr=subprocess.STDOUT,
                shell=use_shell)
        except subprocess.CalledProcessError as e:
            if input_api.is_committing:
                return [
                    output_api.PresubmitError('export_targets.py failed: %s' % e.output.decode())
                ]
            return [
                output_api.PresubmitPromptWarning(
                    'export_targets.py failed, this may just be due to your local checkout: %s' %
                    e.output.decode())
            ]
        return []
    finally:
        shutil.rmtree(outdir)


def _CheckTabsInSourceFiles(input_api, output_api):
    """Forbids tab characters in source files due to a WebKit repo requirement."""

    def implementation_and_headers_including_third_party(f):
        # Check third_party files too, because WebKit's checks don't make exceptions.
        return input_api.FilterSourceFile(
            f,
            files_to_check=(r'.+%s' % _IMPLEMENTATION_AND_HEADER_EXTENSIONS,),
            files_to_skip=[f for f in input_api.DEFAULT_FILES_TO_SKIP if not "third_party" in f])

    files_with_tabs = []
    for f in input_api.AffectedSourceFiles(implementation_and_headers_including_third_party):
        for (num, line) in f.ChangedContents():
            if '\t' in line:
                files_with_tabs.append(f)
                break

    if files_with_tabs:
        return [
            output_api.PresubmitError(
                'Tab characters in source files.',
                items=sorted(files_with_tabs),
                long_text=
                'Tab characters are forbidden in ANGLE source files because WebKit\'s Subversion\n'
                'repository does not allow tab characters in source files.\n'
                'Please remove tab characters from these files.')
        ]
    return []


# https://stackoverflow.com/a/196392
def is_ascii(s):
    return all(ord(c) < 128 for c in s)


def _CheckNonAsciiInSourceFiles(input_api, output_api):
    """Forbids non-ascii characters in source files."""

    def implementation_and_headers(f):
        return input_api.FilterSourceFile(
            f, files_to_check=(r'.+%s' % _IMPLEMENTATION_AND_HEADER_EXTENSIONS,))

    files_with_non_ascii = []
    for f in input_api.AffectedSourceFiles(implementation_and_headers):
        for (num, line) in f.ChangedContents():
            if not is_ascii(line):
                files_with_non_ascii.append("%s: %s" % (f, line))
                break

    if files_with_non_ascii:
        return [
            output_api.PresubmitError(
                'Non-ASCII characters in source files.',
                items=sorted(files_with_non_ascii),
                long_text='Non-ASCII characters are forbidden in ANGLE source files.\n'
                'Please remove non-ASCII characters from these files.')
        ]
    return []


def _CheckCommentBeforeTestInTestFiles(input_api, output_api):
    """Require a comment before TEST_P() and other tests."""

    def test_files(f):
        return input_api.FilterSourceFile(
            f, files_to_check=(r'^src/tests/.+\.cpp$', r'^src/.+_unittest\.cpp$'))

    tests_with_no_comment = []
    for f in input_api.AffectedSourceFiles(test_files):
        diff = f.GenerateScmDiff()
        last_line_was_comment = False
        for line in diff.splitlines():
            # Skip removed lines
            if line.startswith('-'):
                continue

            # Note: we don't always get the context of the diff, so if a test already has a comment
            # but is only renamed, the diff looks like:
            #
            #     @@ <line info>
            #     -TEST_P(OLD, NAME)
            #     +TEST_P(NEW, NAME)
            #
            # Treat @@ as if it was a comment in that case, assuming the test already had a comment
            # previously.
            new_line_is_comment = (
                line.startswith(' //') or line.startswith('+//') or line.startswith('@@'))
            new_line_is_test_declaration = (
                line.startswith('+TEST_P(') or line.startswith('+TEST(') or
                line.startswith('+TYPED_TEST('))

            if new_line_is_test_declaration and not last_line_was_comment:
                tests_with_no_comment.append(line[1:])

            last_line_was_comment = new_line_is_comment

    if tests_with_no_comment:
        return [
            output_api.PresubmitError(
                'Tests without comment.',
                items=sorted(tests_with_no_comment),
                long_text='ANGLE requires a comment describing what a test does.')
        ]
    return []


def _CheckWildcardInTestExpectationFiles(input_api, output_api):
    """Require wildcard as API tag (i.e. in foo.bar/*) in expectations when no additional feature is
    enabled."""

    def expectation_files(f):
        return input_api.FilterSourceFile(
            f, files_to_check=[r'^src/tests/angle_end2end_tests_expectations.txt$'])

    expectation_pattern = re.compile(r'^.*:\s*[a-zA-Z0-9._*]+\/([^ ]*)\s*=.*$')

    expectations_without_wildcard = []
    for f in input_api.AffectedSourceFiles(expectation_files):
        diff = f.GenerateScmDiff()
        for line in diff.splitlines():
            # Only look at new lines
            if not line.startswith('+'):
                continue

            match = re.match(expectation_pattern, line[1:].strip())
            if match is None:
                continue

            tag = match.group(1)

            # The tag is in the following general form:
            #
            #     FRONTENDAPI_BACKENDAPI[_FEATURE]*
            #
            # Any part of the above may be a wildcard.  Warn about usage of FRONTEND_BACKENDAPI as
            # the tag.  Instead, the backend should be specified before the : and `*` used as the
            # tag.  If any additional tags are present, it's a specific expectation that should
            # remain specific (and not wildcarded).  NoFixture is an exception as X_Y_NoFixture is
            # the generic form of the tags of tests that don't use the fixture.

            sections = [section for section in tag.split('_') if section != 'NoFixture']

            # Allow '*_...', or 'FRONTENDAPI_*_...'.
            if '*' in sections[0] or (len(sections) > 1 and '*' in sections[1]):
                continue

            # Warn if no additional tags are present
            if len(sections) == 2:
                expectations_without_wildcard.append(line[1:])

    if expectations_without_wildcard:
        return [
            output_api.PresubmitError(
                'Use wildcard in API tags (after /) in angle_end2end_tests_expectations.txt.',
                items=expectations_without_wildcard,
                long_text="""ANGLE prefers end2end expections to use the following form:

1234 MAC OPENGL : Foo.Bar/* = SKIP

instead of:

1234 MAC OPENGL : Foo.Bar/ES2_OpenGL = SKIP
1234 MAC OPENGL : Foo.Bar/ES3_OpenGL = SKIP

Expectatations that are specific (such as Foo.Bar/ES2_OpenGL_SomeFeature) are allowed.""")
        ]
    return []


def _CheckShaderVersionInShaderLangHeader(input_api, output_api):
    """Requires an update to ANGLE_SH_VERSION when ShaderLang.h or ShaderVars.h change."""

    def headers(f):
        return input_api.FilterSourceFile(
            f,
            files_to_check=(r'^include/GLSLANG/ShaderLang.h$', r'^include/GLSLANG/ShaderVars.h$'))

    headers_changed = input_api.AffectedSourceFiles(headers)
    if len(headers_changed) == 0:
        return []

    # Skip this check for reverts and rolls.  Unlike
    # _CheckCommitMessageFormatting, relands are still checked because the
    # original change might have incremented the version correctly, but the
    # rebase over a new version could accidentally remove that (because another
    # change in the meantime identically incremented it).
    git_output = input_api.change.DescriptionText()
    multiple_commits = _SplitIntoMultipleCommits(git_output)
    for commit in multiple_commits:
        if commit.startswith('Revert') or commit.startswith('Roll'):
            return []

    diffs = '\n'.join(f.GenerateScmDiff() for f in headers_changed)
    versions = dict(re.findall(r'^([-+])#define ANGLE_SH_VERSION\s+(\d+)', diffs, re.M))

    if len(versions) != 2 or int(versions['+']) <= int(versions['-']):
        return [
            output_api.PresubmitError(
                'ANGLE_SH_VERSION should be incremented when ShaderLang.h or ShaderVars.h change.',
            )
        ]
    return []


def _CheckGClientExists(input_api, output_api, search_limit=None):
    presubmit_path = pathlib.Path(input_api.PresubmitLocalPath())

    for current_path in itertools.chain([presubmit_path], presubmit_path.parents):
        gclient_path = current_path.joinpath('.gclient')
        if gclient_path.exists() and gclient_path.is_file():
            return []
        # search_limit parameter is used in unit tests to prevent searching all the way to root
        # directory for reproducibility.
        elif search_limit != None and current_path == search_limit:
            break

    return [
        output_api.PresubmitError(
            'Missing .gclient file.',
            long_text=textwrap.fill(
                width=100,
                text='The top level directory of the repository must contain a .gclient file.'
                ' You can follow the steps outlined in the link below to get set up for ANGLE'
                ' development:') +
            '\n\nhttps://chromium.googlesource.com/angle/angle/+/refs/heads/main/doc/DevSetup.md')
    ]

def CheckChangeOnUpload(input_api, output_api):
    results = []
    results.extend(input_api.canned_checks.CheckForCommitObjects(input_api, output_api))
    results.extend(_CheckTabsInSourceFiles(input_api, output_api))
    results.extend(_CheckNonAsciiInSourceFiles(input_api, output_api))
    results.extend(_CheckCommentBeforeTestInTestFiles(input_api, output_api))
    results.extend(_CheckWildcardInTestExpectationFiles(input_api, output_api))
    results.extend(_CheckShaderVersionInShaderLangHeader(input_api, output_api))
    results.extend(_CheckCodeGeneration(input_api, output_api))
    results.extend(_CheckChangeHasBugField(input_api, output_api))
    results.extend(input_api.canned_checks.CheckChangeHasDescription(input_api, output_api))
    results.extend(_CheckNewHeaderWithoutGnChange(input_api, output_api))
    results.extend(_CheckExportValidity(input_api, output_api))
    results.extend(
        input_api.canned_checks.CheckPatchFormatted(
            input_api, output_api, result_factory=output_api.PresubmitError))
    results.extend(_CheckCommitMessageFormatting(input_api, output_api))
    results.extend(_CheckGClientExists(input_api, output_api))

    return results


def CheckChangeOnCommit(input_api, output_api):
    return CheckChangeOnUpload(input_api, output_api)
