# Copyright 2017 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 ios.

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

import os

NULLABILITY_PATTERN = r'(nonnull|nullable|_Nullable|_Nonnull)'
TODO_PATTERN = r'TO[D]O\(([^\)]*)\)'
CRBUG_PATTERN = r'crbug\.com/\d+$'
ARC_COMPILE_GUARD = [
    '#if !defined(__has_feature) || !__has_feature(objc_arc)',
    '#error "This file requires ARC support."',
    '#endif',
]

def IsSubListOf(needle, hay):
  """Returns whether there is a slice of |hay| equal to |needle|."""
  for i, line in enumerate(hay):
    if line == needle[0]:
      if needle == hay[i:i+len(needle)]:
        return True
  return False

def _CheckARCCompilationGuard(input_api, output_api):
  """ Checks whether new objc files have proper ARC compile guards."""
  files_without_headers = []
  for f in input_api.AffectedFiles():
    if f.Action() != 'A':
      continue

    _, ext = os.path.splitext(f.LocalPath())
    if ext not in ('.m', '.mm'):
      continue

    if not IsSubListOf(ARC_COMPILE_GUARD, f.NewContents()):
      files_without_headers.append(f.LocalPath())

  if not files_without_headers:
    return []

  plural_suffix = '' if len(files_without_headers) == 1 else 's'
  error_message = '\n'.join([
      'Found new Objective-C implementation file%(plural)s without compile'
      ' guard%(plural)s. Please use the following compile guard'
      ':' % {'plural': plural_suffix}
  ] + ARC_COMPILE_GUARD + files_without_headers) + '\n'

  return [output_api.PresubmitError(error_message)]


def _CheckNullabilityAnnotations(input_api, output_api):
  """ Checks whether there are nullability annotations in ios code."""
  nullability_regex = input_api.re.compile(NULLABILITY_PATTERN)

  errors = []
  for f in input_api.AffectedFiles():
    for line_num, line in f.ChangedContents():
      if nullability_regex.search(line):
        errors.append('%s:%s' % (f.LocalPath(), line_num))
  if not errors:
    return []

  plural_suffix = '' if len(errors) == 1 else 's'
  error_message = ('Found Nullability annotation%(plural)s. '
      'Prefer DCHECKs in ios code to check for nullness:'
       % {'plural': plural_suffix})

  return [output_api.PresubmitPromptWarning(error_message, items=errors)]


def _CheckBugInToDo(input_api, output_api):
  """ Checks whether TODOs in ios code are identified by a bug number."""
  errors = []
  for f in input_api.AffectedFiles():
    for line_num, line in f.ChangedContents():
      if _HasToDoWithNoBug(input_api, line):
        errors.append('%s:%s' % (f.LocalPath(), line_num))
  if not errors:
    return []

  plural_suffix = '' if len(errors) == 1 else 's'
  error_message = '\n'.join([
      'Found TO''DO%(plural)s without bug number%(plural)s (expected format is '
      '\"TO''DO(crbug.com/######)\":' % {'plural': plural_suffix}
  ] + errors) + '\n'

  return [output_api.PresubmitError(error_message)]


def _HasToDoWithNoBug(input_api, line):
  """ Returns True if TODO is not identified by a bug number."""
  todo_regex = input_api.re.compile(TODO_PATTERN)
  crbug_regex = input_api.re.compile(CRBUG_PATTERN)

  todo_match = todo_regex.search(line)
  if not todo_match:
    return False
  crbug_match = crbug_regex.match(todo_match.group(1))
  return not crbug_match


def CheckChangeOnUpload(input_api, output_api):
  results = []
  results.extend(_CheckBugInToDo(input_api, output_api))
  results.extend(_CheckNullabilityAnnotations(input_api, output_api))
  results.extend(_CheckARCCompilationGuard(input_api, output_api))
  return results
