# Copyright (c) 2011 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 script for changes affecting chrome/

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

USE_PYTHON3 = True

import re

INCLUDE_CPP_FILES_ONLY = (
  r'.*\.(cc|h)$',
)

INCLUDE_SOURCE_FILES_ONLY = (
  r'.*\.(c|cc|cpp|h|m|mm)$',
)

EXCLUDE = (
  # Objective C confuses everything.
  r'.*cocoa.*',
  r'.*_mac\.(cc|h)$',
  r'.*_mac_.*',
  # All the messages files do weird multiple include trickery
  r'.*_messages.*\.h$',
  # Autogenerated window resources files are off limits
  r'.*resource.h$',
  # Header trickery
  r'.*-inl\.h$',
  # Has safe printf usage that cpplint complains about
  r'safe_browsing_util\.cc$',
)

def _CheckChangeLintsClean(input_api, output_api):
  """Makes sure that the chrome/ code is cpplint clean."""
  files_to_skip = input_api.DEFAULT_FILES_TO_SKIP + EXCLUDE
  sources = lambda x: input_api.FilterSourceFile(
    x, files_to_check=INCLUDE_CPP_FILES_ONLY, files_to_skip=files_to_skip)
  return input_api.canned_checks.CheckChangeLintsClean(
      input_api, output_api, sources)


def _CheckNoContentUnitTestsInChrome(input_api, output_api):
  """Makes sure that no unit tests from content/ are included in unit_tests."""
  problems = []
  for f in input_api.AffectedFiles():
    if not f.LocalPath().endswith('BUILD.gn'):
      continue

    for line_num, line in f.ChangedContents():
      m = re.search(r"'(.*\/content\/.*unittest.*)'", line)
      if m:
        problems.append(m.group(1))

  if not problems:
    return []
  return [output_api.PresubmitPromptWarning(
      'Unit tests located in content/ should be added to the ' +
      'content_unittests target.',
      items=problems)]


def _CheckNoIsAppleBuildFlagsInChromeFile(input_api, f):
  """Check for IS_APPLE in a given file in chrome/."""
  preprocessor_statement = input_api.re.compile(r'^\s*#')
  apple_buildflag = input_api.re.compile(r'BUILDFLAG\(IS_APPLE\)')
  results = []
  for lnum, line in f.ChangedContents():
    if preprocessor_statement.search(line) and apple_buildflag.search(line):
      results.append('    %s:%d' % (f.LocalPath(), lnum))

  return results


def _CheckNoIsAppleBuildFlagsInChrome(input_api, output_api):
  """Check for IS_APPLE which isn't used in chrome/."""
  apple_buildflags = []
  def SourceFilter(affected_file):
    return input_api.FilterSourceFile(affected_file, INCLUDE_SOURCE_FILES_ONLY,
                                      input_api.DEFAULT_FILES_TO_SKIP)
  for f in input_api.AffectedSourceFiles(SourceFilter):
    apple_buildflags.extend(_CheckNoIsAppleBuildFlagsInChromeFile(input_api, f))

  if not apple_buildflags:
    return []

  return [output_api.PresubmitError(
      'IS_APPLE is not used in chrome/ but found in:\n', apple_buildflags)]


def _CheckNoIsIOSBuildFlagsInChromeFile(input_api, f):
  """Check for IS_IOS in a given file in chrome/."""
  preprocessor_statement = input_api.re.compile(r'^\s*#')
  ios_buildflag = input_api.re.compile(r'BUILDFLAG\(IS_IOS\)')
  results = []
  for lnum, line in f.ChangedContents():
    if preprocessor_statement.search(line) and ios_buildflag.search(line):
      results.append('    %s:%d' % (f.LocalPath(), lnum))

  return results


def _CheckNoIsIOSBuildFlagsInChrome(input_api, output_api):
  """Check for IS_IOS which isn't used in chrome/."""
  ios_buildflags = []
  def SourceFilter(affected_file):
    return input_api.FilterSourceFile(affected_file, INCLUDE_SOURCE_FILES_ONLY,
                                      input_api.DEFAULT_FILES_TO_SKIP)
  for f in input_api.AffectedSourceFiles(SourceFilter):
    ios_buildflags.extend(_CheckNoIsIOSBuildFlagsInChromeFile(input_api, f))

  if not ios_buildflags:
    return []

  return [output_api.PresubmitError(
      'IS_IOS is not used in chrome/ but found in:\n', ios_buildflags)]


def _CommonChecks(input_api, output_api):
  """Checks common to both upload and commit."""
  results = []
  results.extend(_CheckNoContentUnitTestsInChrome(input_api, output_api))
  results.extend(_CheckNoIsAppleBuildFlagsInChrome(input_api, output_api))
  results.extend(_CheckNoIsIOSBuildFlagsInChrome(input_api, output_api))
  return results


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


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