# 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.
"""

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 _CheckNoOSAPPLEMacrosInChromeFile(input_api, f):
  """Check for OS_APPLE in a given file in chrome/."""
  preprocessor_statement = input_api.re.compile(r'^\s*#')
  apple_macro = input_api.re.compile(r'defined\(OS_APPLE\)')
  results = []
  for lnum, line in f.ChangedContents():
    if preprocessor_statement.search(line) and apple_macro.search(line):
      results.append('    %s:%d' % (f.LocalPath(), lnum))

  return results


def _CheckNoOSAPPLEMacrosInChrome(input_api, output_api):
  """Check for OS_APPLE which isn't used in chrome/."""
  apple_macros = []
  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_macros.extend(_CheckNoOSAPPLEMacrosInChromeFile(input_api, f))

  if not apple_macros:
    return []

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


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

  return results


def _CheckNoOSIOSMacrosInChrome(input_api, output_api):
  """Check for OS_IOS which isn't used in chrome/."""
  ios_macros = []
  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_macros.extend(_CheckNoOSIOSMacrosInChromeFile(input_api, f))

  if not ios_macros:
    return []

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


def _CommonChecks(input_api, output_api):
  """Checks common to both upload and commit."""
  results = []
  results.extend(_CheckNoContentUnitTestsInChrome(input_api, output_api))
  results.extend(_CheckNoOSAPPLEMacrosInChrome(input_api, output_api))
  results.extend(_CheckNoOSIOSMacrosInChrome(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
