# Copyright 2018 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Presubmit tests for android_webview/javatests/

Runs various style checks before upload.
"""

def CheckChangeOnUpload(input_api, output_api):
  results = []
  results.extend(_CheckAwJUnitTestRunner(input_api, output_api))
  results.extend(_CheckNoSkipCommandLineAnnotation(input_api, output_api))
  results.extend(_CheckNoSandboxedRendererSwitch(input_api, output_api))
  return results


def _CheckAwJUnitTestRunner(input_api, output_api):
  """Checks that new tests use the AwJUnit4ClassRunner instead of some other
  test runner. This is because WebView has special logic in the
  AwJUnit4ClassRunner.
  """

  run_with_pattern = input_api.re.compile(
      r'^@RunWith\((.*)\)$')
  correct_runner = 'AwJUnit4ClassRunner.class'

  errors = []

  def _FilterFile(affected_file):
    return input_api.FilterSourceFile(
        affected_file,
        black_list=input_api.DEFAULT_BLACK_LIST,
        white_list=[r'.*\.java$'])

  for f in input_api.AffectedSourceFiles(_FilterFile):
    for line_num, line in f.ChangedContents():
      match = run_with_pattern.search(line)
      if match and match.group(1) != correct_runner:
        errors.append("%s:%d" % (f.LocalPath(), line_num))

  results = []

  if errors:
    results.append(output_api.PresubmitPromptWarning("""
android_webview/javatests/ should use the AwJUnit4ClassRunner test runner, not
any other test runner (e.g., BaseJUnit4ClassRunner).
""", errors))

  return results


def _CheckNoSkipCommandLineAnnotation(input_api, output_api):
  """Checks that tests do not add @SkipCommandLineParameterization annotation.
  This was previously used to run the test in single-process-mode only (or,
  multi-process-mode only if used with
  @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER)). This is
  obsolete because we have dedicated annotations (@OnlyRunInSingleProcessMode
  and @OnlyRunInMultiProcessMode).
  """

  skip_command_line_annotation = input_api.re.compile(
      r'^\s*@SkipCommandLineParameterization.*$')

  errors = []

  def _FilterFile(affected_file):
    return input_api.FilterSourceFile(
        affected_file,
        black_list=input_api.DEFAULT_BLACK_LIST,
        white_list=[r'.*\.java$'])

  for f in input_api.AffectedSourceFiles(_FilterFile):
    for line_num, line in f.ChangedContents():
      match = skip_command_line_annotation.search(line)
      if match:
        errors.append("%s:%d" % (f.LocalPath(), line_num))

  results = []

  if errors:
    results.append(output_api.PresubmitPromptWarning("""
android_webview/javatests/ should not use @SkipCommandLineParameterization to
run in either multi-process or single-process only. Instead, use @OnlyRunIn.
""", errors))

  return results


def _CheckNoSandboxedRendererSwitch(input_api, output_api):
  """Checks that tests do not add the AwSwitches.WEBVIEW_SANDBOXED_RENDERER
  command line flag. Tests should instead use @OnlyRunIn(MULTI_PROCESS).
  """

  # This will not catch multi-line annotations (which are valid if adding
  # multiple switches), but is better than nothing (and avoids false positives).
  sandboxed_renderer_pattern = input_api.re.compile(
      r'^\s*@CommandLineFlags\.Add\(.*'
      r'\bAwSwitches\.WEBVIEW_SANDBOXED_RENDERER\b.*\)$')

  errors = []

  def _FilterFile(affected_file):
    return input_api.FilterSourceFile(
        affected_file,
        black_list=input_api.DEFAULT_BLACK_LIST,
        white_list=[r'.*\.java$'])

  for f in input_api.AffectedSourceFiles(_FilterFile):
    for line_num, line in f.ChangedContents():
      match = sandboxed_renderer_pattern.search(line)
      if match:
        errors.append("%s:%d" % (f.LocalPath(), line_num))

  results = []

  if errors:
    results.append(output_api.PresubmitPromptWarning("""
android_webview/javatests/ should not use AwSwitches.WEBVIEW_SANDBOXED_RENDERER
to run in multi-process only. Instead, use @OnlyRunIn(MULTI_PROCESS).
""", errors))

  return results
