# Copyright 2012 the V8 project authors. All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
#     * Redistributions of source code must retain the above copyright
#       notice, this list of conditions and the following disclaimer.
#     * 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.
#     * Neither the name of Google Inc. 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
# OWNER 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.

"""Top-level presubmit script for V8.

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

import json
import os
import re
import sys

# 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

_EXCLUDED_PATHS = (
    r"^test[\\\/].*",
    r"^testing[\\\/].*",
    r"^third_party[\\\/].*",
    r"^tools[\\\/].*",
)

_LICENSE_FILE = (
    r"LICENSE"
)

# Regular expression that matches code which should not be run through cpplint.
_NO_LINT_PATHS = (
    r'src[\\\/]base[\\\/]export-template\.h',
)


# Regular expression that matches code only used for test binaries
# (best effort).
_TEST_CODE_EXCLUDED_PATHS = (
    r'.+-unittest\.cc',
    # Has a method VisitForTest().
    r'src[\\\/]compiler[\\\/]ast-graph-builder\.cc',
    # Test extension.
    r'src[\\\/]extensions[\\\/]gc-extension\.cc',
    # Runtime functions used for testing.
    r'src[\\\/]runtime[\\\/]runtime-test\.cc',
    # Testing helpers.
    r'src[\\\/]heap[\\\/]cppgc[\\\/]testing\.cc',
)


_TEST_ONLY_WARNING = (
    'You might be calling functions intended only for testing from\n'
    'production code.  It is OK to ignore this warning if you know what\n'
    'you are doing, as the heuristics used to detect the situation are\n'
    'not perfect.  The commit queue will not block on this warning.')


def _V8PresubmitChecks(input_api, output_api):
  """Runs the V8 presubmit checks."""
  import sys
  sys.path.append(input_api.os_path.join(
        input_api.PresubmitLocalPath(), 'tools'))
  from v8_presubmit import CppLintProcessor
  from v8_presubmit import GCMoleProcessor
  from v8_presubmit import JSLintProcessor
  from v8_presubmit import TorqueLintProcessor
  from v8_presubmit import SourceProcessor
  from v8_presubmit import StatusFilesProcessor

  def FilterFile(affected_file):
    return input_api.FilterSourceFile(
      affected_file,
      files_to_check=None,
      files_to_skip=_NO_LINT_PATHS)

  def FilterTorqueFile(affected_file):
    return input_api.FilterSourceFile(
      affected_file,
      files_to_check=(r'.+\.tq'))

  def FilterJSFile(affected_file):
    return input_api.FilterSourceFile(
      affected_file,
      files_to_check=(r'.+\.m?js'))

  results = []
  if not CppLintProcessor().RunOnFiles(
      input_api.AffectedFiles(file_filter=FilterFile, include_deletes=False)):
    results.append(output_api.PresubmitError("C++ lint check failed"))
  if not TorqueLintProcessor().RunOnFiles(
      input_api.AffectedFiles(file_filter=FilterTorqueFile,
                              include_deletes=False)):
    results.append(output_api.PresubmitError("Torque format check failed"))
  if not JSLintProcessor().RunOnFiles(
      input_api.AffectedFiles(file_filter=FilterJSFile,
                              include_deletes=False)):
    results.append(output_api.PresubmitError("JS format check failed"))
  if not SourceProcessor().RunOnFiles(
      input_api.AffectedFiles(include_deletes=False)):
    results.append(output_api.PresubmitError(
        "Copyright header, trailing whitespaces and two empty lines " \
        "between declarations check failed"))
  if not StatusFilesProcessor().RunOnFiles(
      input_api.AffectedFiles(include_deletes=True)):
    results.append(output_api.PresubmitError("Status file check failed"))
  if not GCMoleProcessor().RunOnFiles(
      input_api.AffectedFiles(include_deletes=False)):
    results.append(output_api.PresubmitError("GCMole pattern check failed"))
  results.extend(input_api.canned_checks.CheckAuthorizedAuthor(
      input_api, output_api, bot_allowlist=[
        'v8-ci-autoroll-builder@chops-service-accounts.iam.gserviceaccount.com',
        'v8-ci-test262-import-export@chops-service-accounts.iam.gserviceaccount.com',
      ]))
  return results


def _CheckUnwantedDependencies(input_api, output_api):
  """Runs checkdeps on #include statements added in this
  change. Breaking - rules is an error, breaking ! rules is a
  warning.
  """
  # We need to wait until we have an input_api object and use this
  # roundabout construct to import checkdeps because this file is
  # eval-ed and thus doesn't have __file__.
  original_sys_path = sys.path
  try:
    sys.path = sys.path + [input_api.os_path.join(
        input_api.PresubmitLocalPath(), 'buildtools', 'checkdeps')]
    import checkdeps
    from cpp_checker import CppChecker
    from rules import Rule
  finally:
    # Restore sys.path to what it was before.
    sys.path = original_sys_path

  def _FilesImpactedByDepsChange(files):
    all_files = [f.AbsoluteLocalPath() for f in files]
    deps_files = [p for p in all_files if IsDepsFile(p)]
    impacted_files = union([_CollectImpactedFiles(path) for path in deps_files])
    impacted_file_objs = [ImpactedFile(path) for path in impacted_files]
    return impacted_file_objs

  def IsDepsFile(p):
    return os.path.isfile(p) and os.path.basename(p) == 'DEPS'

  def union(list_of_lists):
    """Ensure no duplicates"""
    return set(sum(list_of_lists, []))

  def _CollectImpactedFiles(deps_file):
    # TODO(liviurau): Do not walk paths twice. Then we have no duplicates.
    # Higher level DEPS changes may dominate lower level DEPS changes.
    # TODO(liviurau): Check if DEPS changed in the right way.
    # 'include_rules' impact c++ files but 'vars' or 'deps' do not.
    # Maybe we just eval both old and new DEPS content and check
    # if the list are the same.
    result = []
    parent_dir = os.path.dirname(deps_file)
    for relative_f in input_api.change.AllFiles(parent_dir):
      abs_f = os.path.join(parent_dir, relative_f)
      if CppChecker.IsCppFile(abs_f):
        result.append(abs_f)
    return result

  class ImpactedFile(object):
    """Duck type version of AffectedFile needed to check files under directories
    where a DEPS file changed. Extend the interface along the line of
    AffectedFile if you need it for other checks."""

    def __init__(self, path):
      self._path = path

    def LocalPath(self):
      path = self._path.replace(os.sep, '/')
      return os.path.normpath(path)

    def ChangedContents(self):
      with open(self._path) as f:
        # TODO(liviurau): read only '#include' lines
        lines = f.readlines()
      return enumerate(lines, start=1)

  def _FilterDuplicates(impacted_files, affected_files):
    """"We include all impacted files but exclude affected files that are also
    impacted. Files impacted by DEPS changes take precedence before files
    affected by direct changes."""
    result = impacted_files[:]
    only_paths = set([imf.LocalPath() for imf in impacted_files])
    for af in affected_files:
      if not af.LocalPath() in only_paths:
        result.append(af)
    return result

  added_includes = []
  affected_files = input_api.AffectedFiles()
  impacted_by_deps = _FilesImpactedByDepsChange(affected_files)
  for f in _FilterDuplicates(impacted_by_deps, affected_files):
    if not CppChecker.IsCppFile(f.LocalPath()):
      continue

    changed_lines = [line for line_num, line in f.ChangedContents()]
    added_includes.append([f.LocalPath(), changed_lines])

  deps_checker = checkdeps.DepsChecker(input_api.PresubmitLocalPath())

  error_descriptions = []
  warning_descriptions = []
  for path, rule_type, rule_description in deps_checker.CheckAddedCppIncludes(
      added_includes):
    description_with_path = '{}\n    {}'.format(path, rule_description)
    if rule_type == Rule.DISALLOW:
      error_descriptions.append(description_with_path)
    else:
      warning_descriptions.append(description_with_path)

  results = []
  if error_descriptions:
    results.append(output_api.PresubmitError(
        'You added one or more #includes that violate checkdeps rules.',
        error_descriptions))
  if warning_descriptions:
    results.append(output_api.PresubmitPromptOrNotify(
        'You added one or more #includes of files that are temporarily\n'
        'allowed but being removed. Can you avoid introducing the\n'
        '#include? See relevant DEPS file(s) for details and contacts.',
        warning_descriptions))
  return results


def _CheckHeadersHaveIncludeGuards(input_api, output_api):
  """Ensures that all header files have include guards."""
  file_inclusion_pattern = r'src/.+\.h'

  def FilterFile(affected_file):
    files_to_skip = _EXCLUDED_PATHS + input_api.DEFAULT_FILES_TO_SKIP
    return input_api.FilterSourceFile(
      affected_file,
      files_to_check=(file_inclusion_pattern, ),
      files_to_skip=files_to_skip)

  leading_src_pattern = input_api.re.compile(r'^src[\\\/]')
  dash_dot_slash_pattern = input_api.re.compile(r'[-.\\\/]')

  def PathToGuardMacro(path):
    """Guards should be of the form V8_PATH_TO_FILE_WITHOUT_SRC_H_."""
    x = input_api.re.sub(leading_src_pattern, 'v8_', path)
    x = input_api.re.sub(dash_dot_slash_pattern, '_', x)
    x = x.upper() + "_"
    return x

  problems = []
  for f in input_api.AffectedSourceFiles(FilterFile):
    local_path = f.LocalPath()
    guard_macro = PathToGuardMacro(local_path)
    guard_patterns = [
            input_api.re.compile(r'^#ifndef ' + guard_macro + '$'),
            input_api.re.compile(r'^#define ' + guard_macro + '$'),
            input_api.re.compile(r'^#endif  // ' + guard_macro + '$')]
    skip_check_pattern = input_api.re.compile(
            r'^// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD')
    found_patterns = [ False, False, False ]
    file_omitted = False

    for line in f.NewContents():
      for i in range(len(guard_patterns)):
        if guard_patterns[i].match(line):
          found_patterns[i] = True
      if skip_check_pattern.match(line):
        file_omitted = True
        break

    if not file_omitted and not all(found_patterns):
      problems.append('{}: Missing include guard \'{}\''.format(
          local_path, guard_macro))

  if problems:
    return [output_api.PresubmitError(
        'You added one or more header files without an appropriate\n'
        'include guard. Add the include guard {#ifndef,#define,#endif}\n'
        'triplet or omit the check entirely through the magic comment:\n'
        '"// PRESUBMIT_INTENTIONALLY_MISSING_INCLUDE_GUARD".', problems)]
  else:
    return []


def _CheckNoInlineHeaderIncludesInNormalHeaders(input_api, output_api):
  """Attempts to prevent inclusion of inline headers into normal header
  files. This tries to establish a layering where inline headers can be
  included by other inline headers or compilation units only."""
  file_inclusion_pattern = r'(?!.+-inl\.h).+\.h'
  include_directive_pattern = input_api.re.compile(r'#include ".+-inl.h"')
  include_error = (
    'You are including an inline header (e.g. foo-inl.h) within a normal\n'
    'header (e.g. bar.h) file.  This violates layering of dependencies.')

  def FilterFile(affected_file):
    files_to_skip = _EXCLUDED_PATHS + input_api.DEFAULT_FILES_TO_SKIP
    return input_api.FilterSourceFile(
      affected_file,
      files_to_check=(file_inclusion_pattern, ),
      files_to_skip=files_to_skip)

  problems = []
  for f in input_api.AffectedSourceFiles(FilterFile):
    local_path = f.LocalPath()
    for line_number, line in f.ChangedContents():
      if (include_directive_pattern.search(line)):
        problems.append('{}:{}\n    {}'.format(local_path, line_number,
                                               line.strip()))

  if problems:
    return [output_api.PresubmitError(include_error, problems)]
  else:
    return []


def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
  """Attempts to prevent use of functions intended only for testing in
  non-testing code. For now this is just a best-effort implementation
  that ignores header files and may have some false positives. A
  better implementation would probably need a proper C++ parser.
  """
  # We only scan .cc files, as the declaration of for-testing functions in
  # header files are hard to distinguish from calls to such functions without a
  # proper C++ parser.
  file_inclusion_pattern = r'.+\.cc'

  base_function_pattern = r'[ :]test::[^\s]+|ForTest(ing)?|for_test(ing)?'
  inclusion_pattern = input_api.re.compile(
      r'({})\s*\('.format(base_function_pattern))
  comment_pattern = input_api.re.compile(
      r'//.*({})'.format(base_function_pattern))
  exclusion_pattern = input_api.re.compile(
      r'::[A-Za-z0-9_]+({})|({})[^;]+'.format(base_function_pattern,
                                              base_function_pattern) + '\{')

  def FilterFile(affected_file):
    files_to_skip = (_EXCLUDED_PATHS +
                     _TEST_CODE_EXCLUDED_PATHS +
                     input_api.DEFAULT_FILES_TO_SKIP)
    return input_api.FilterSourceFile(
      affected_file,
      files_to_check=(file_inclusion_pattern, ),
      files_to_skip=files_to_skip)

  problems = []
  for f in input_api.AffectedSourceFiles(FilterFile):
    local_path = f.LocalPath()
    for line_number, line in f.ChangedContents():
      if (inclusion_pattern.search(line) and
          not comment_pattern.search(line) and
          not exclusion_pattern.search(line)):
        problems.append('{}:{}\n    {}'.format(local_path, line_number,
                                               line.strip()))

  if problems:
    return [output_api.PresubmitPromptOrNotify(_TEST_ONLY_WARNING, problems)]
  else:
    return []


def _CheckGenderNeutralInLicenses(input_api, output_api):
  # License files are taken as is, even if they include gendered pronouns.
  def LicenseFilter(path):
    input_api.FilterSourceFile(path, files_to_skip=_LICENSE_FILE)

  return input_api.canned_checks.CheckGenderNeutral(
    input_api, output_api, source_file_filter=LicenseFilter)


def _RunTestsWithVPythonSpec(input_api, output_api):
  return input_api.RunTests(
    input_api.canned_checks.CheckVPythonSpec(input_api, output_api))


def _CommonChecks(input_api, output_api):
  """Checks common to both upload and commit."""
  # TODO(machenbach): Replace some of those checks, e.g. owners and copyright,
  # with the canned PanProjectChecks. Need to make sure that the checks all
  # pass on all existing files.
  checks = [
    input_api.canned_checks.CheckOwnersFormat,
    input_api.canned_checks.CheckOwners,
    _CheckCommitMessageBugEntry,
    input_api.canned_checks.CheckPatchFormatted,
    _CheckGenderNeutralInLicenses,
    _V8PresubmitChecks,
    _CheckUnwantedDependencies,
    _CheckNoProductionCodeUsingTestOnlyFunctions,
    _CheckHeadersHaveIncludeGuards,
    _CheckNoInlineHeaderIncludesInNormalHeaders,
    _CheckJSONFiles,
    _CheckNoexceptAnnotations,
    _RunTestsWithVPythonSpec,
  ]

  return sum([check(input_api, output_api) for check in checks], [])


def _SkipTreeCheck(input_api, output_api):
  """Check the env var whether we want to skip tree check.
     Only skip if include/v8-version.h has been updated."""
  src_version = 'include/v8-version.h'
  if not input_api.AffectedSourceFiles(
      lambda file: file.LocalPath() == src_version):
    return False
  return input_api.environ.get('PRESUBMIT_TREE_CHECK') == 'skip'


def _CheckCommitMessageBugEntry(input_api, output_api):
  """Check that bug entries are well-formed in commit message."""
  bogus_bug_msg = (
      'Bogus BUG entry: {}. Please specify prefix:number for v8 or chromium '
      '(e.g. chromium:12345) or b/number for buganizer.')
  results = []
  for bug in (input_api.change.BUG or '').split(','):
    bug = bug.strip()
    if 'none'.startswith(bug.lower()):
      continue
    if ':' not in bug and not bug.startswith('b/'):
      try:
        if int(bug) < 10000000:
          if int(bug) > 200000:
            prefix_guess = 'chromium'
          else:
            prefix_guess = 'v8'
          results.append(
              'BUG entry requires issue tracker prefix, e.g. {}:{}'.format(
                  prefix_guess, bug))
      except ValueError:
        results.append(bogus_bug_msg.format(bug))
    elif not re.match(r'\w+[:\/]\d+', bug):
      results.append(bogus_bug_msg.format(bug))
  return [output_api.PresubmitError(r) for r in results]


def _CheckJSONFiles(input_api, output_api):
  def FilterFile(affected_file):
    return input_api.FilterSourceFile(
        affected_file,
        files_to_check=(r'.+\.json',))

  results = []
  for f in input_api.AffectedFiles(
      file_filter=FilterFile, include_deletes=False):
    with open(f.LocalPath()) as j:
      try:
        json.load(j)
      except Exception as e:
        results.append('JSON validation failed for {}. Error:\n{}'.format(
            f.LocalPath(), e))

  return [output_api.PresubmitError(r) for r in results]


def _CheckNoexceptAnnotations(input_api, output_api):
  """
  Checks that all user-defined constructors and assignment operators are marked
  V8_NOEXCEPT.

  This is required for standard containers to pick the right constructors. Our
  macros (like MOVE_ONLY_WITH_DEFAULT_CONSTRUCTORS) add this automatically.
  Omitting it at some places can result in weird compiler errors if this is
  mixed with other classes that have the annotation.

  TODO(clemensb): This check should eventually be enabled for all files via
  tools/presubmit.py (https://crbug.com/v8/8616).
  """

  def FilterFile(affected_file):
    files_to_skip = _EXCLUDED_PATHS + (
        # Skip api.cc since we cannot easily add the 'noexcept' annotation to
        # public methods.
        r'src[\\\/]api[\\\/]api\.cc',
        # Skip src/bigint/ because it's meant to be V8-independent.
        r'src[\\\/]bigint[\\\/].*',
    )
    return input_api.FilterSourceFile(
        affected_file,
        files_to_check=(r'src[\\\/].*\.cc', r'src[\\\/].*\.h',
                        r'test[\\\/].*\.cc', r'test[\\\/].*\.h'),
        files_to_skip=files_to_skip)

  # matches any class name.
  class_name = r'\b([A-Z][A-Za-z0-9_:]*)(?:::\1)?'
  # initial class name is potentially followed by this to declare an assignment
  # operator.
  potential_assignment = r'(?:&\s+(?:\1::)?operator=)?\s*'
  # matches an argument list that contains only a reference to a class named
  # like the first capture group, potentially const.
  single_class_ref_arg = r'\(\s*(?:const\s+)?\1(?:::\1)?&&?[^,;)]*\)'
  # matches anything but a sequence of whitespaces followed by either
  # V8_NOEXCEPT or "= delete".
  not_followed_by_noexcept = r'(?!\s+(?:V8_NOEXCEPT|=\s+delete)\b)'
  full_pattern = r'^.*?' + class_name + potential_assignment + \
      single_class_ref_arg + not_followed_by_noexcept + '.*?$'
  regexp = input_api.re.compile(full_pattern, re.MULTILINE)

  errors = []
  for f in input_api.AffectedFiles(file_filter=FilterFile,
                                   include_deletes=False):
    with open(f.LocalPath()) as fh:
      for match in re.finditer(regexp, fh.read()):
        errors.append(f'in {f.LocalPath()}: {match.group().strip()}')

  if errors:
    return [output_api.PresubmitPromptOrNotify(
        'Copy constructors, move constructors, copy assignment operators and '
        'move assignment operators should be marked V8_NOEXCEPT.\n'
        'Please report false positives on https://crbug.com/v8/8616.',
        errors)]
  return []


def CheckChangeOnUpload(input_api, output_api):
  results = []
  results.extend(_CommonChecks(input_api, output_api))
  return results


def CheckChangeOnCommit(input_api, output_api):
  results = []
  results.extend(_CommonChecks(input_api, output_api))
  results.extend(input_api.canned_checks.CheckChangeHasDescription(
      input_api, output_api))
  if not _SkipTreeCheck(input_api, output_api):
    results.extend(input_api.canned_checks.CheckTreeIsOpen(
        input_api, output_api,
        json_url='http://v8-status.appspot.com/current?format=json'))
  return results
