# Copyright 2011 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os

USE_PYTHON3 = True

PRESUBMIT_VERSION = '2.0.0'

ANDROID_ALLOWED_LICENSES = [
  'A(pple )?PSL 2(\.0)?',
  'Android Software Development Kit License',
  'Apache( License)?,?( Version)? 2(\.0)?',
  '(New )?([23]-Clause )?BSD( [23]-Clause)?( with advertising clause)?',
  'GNU Lesser Public License',
  'L?GPL ?v?2(\.[01])?( or later)?( with the classpath exception)?',
  '(The )?MIT(/X11)?(-like)?( License)?',
  'MPL 1\.1 ?/ ?GPL 2(\.0)? ?/ ?LGPL 2\.1',
  'MPL 2(\.0)?',
  'Microsoft Limited Public License',
  'Microsoft Permissive License',
  'Public Domain',
  'Python',
  'SIL Open Font License, Version 1.1',
  'SGI Free Software License B',
  'Unicode, Inc. License',
  'University of Illinois\/NCSA Open Source',
  'X11',
  'Zlib',
]

def LicenseIsCompatibleWithAndroid(input_api, license):
  regex = '^(%s)$' % '|'.join(ANDROID_ALLOWED_LICENSES)
  tokens = \
    [x.strip() for x in input_api.re.split(' and |,', license) if len(x) > 0]
  has_compatible_license = False
  for token in tokens:
    if input_api.re.match(regex, token, input_api.re.IGNORECASE):
      has_compatible_license = True
      break
  return has_compatible_license

def CheckThirdPartyReadmesUpdated(input_api, output_api):
  """
  Checks to make sure that README.chromium files are properly updated
  when dependencies in third_party are modified.
  """
  readmes = []
  files = []
  errors = []
  for f in input_api.AffectedFiles():
    local_path = f.LocalPath()
    if input_api.os_path.dirname(local_path) == 'third_party':
      continue
    if (local_path.startswith('third_party' + input_api.os_path.sep) and
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'blink' + input_api.os_path.sep) and
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'boringssl' + input_api.os_path.sep) and
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'closure_compiler' + input_api.os_path.sep +
                                  'externs' + input_api.os_path.sep) and
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'closure_compiler' + input_api.os_path.sep +
                                  'interfaces' + input_api.os_path.sep) and
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'feed_library' + input_api.os_path.sep) and
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'ipcz' + input_api.os_path.sep) and
        # TODO(danakj): We should look for the README.chromium file in
        # third_party/rust/CRATE_NAME/vVERSION/.
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'rust' + input_api.os_path.sep) and
        not local_path.startswith('third_party' + input_api.os_path.sep +
                                  'webxr_test_pages' + input_api.os_path.sep)):
      files.append(f)
      if local_path.endswith("README.chromium"):
        readmes.append(f)
  if files and not readmes:
    errors.append(output_api.PresubmitPromptWarning(
       'When updating or adding third party code the appropriate\n'
       '\'README.chromium\' file should also be updated with the correct\n'
       'version and package information.', files))
  if not readmes:
    return errors

  name_pattern = input_api.re.compile(
    r'^Name: [a-zA-Z0-9_\-\. \(\)]+\r?$',
    input_api.re.IGNORECASE | input_api.re.MULTILINE)
  shortname_pattern = input_api.re.compile(
    r'^Short Name: [a-zA-Z0-9_\-\.]+\r?$',
    input_api.re.IGNORECASE | input_api.re.MULTILINE)
  version_pattern = input_api.re.compile(
    r'^Version: [a-zA-Z0-9_\-\+\.:/]+\r?$',
    input_api.re.IGNORECASE | input_api.re.MULTILINE)
  release_pattern = input_api.re.compile(
    r'^Security Critical: (yes|no)\r?$',
    input_api.re.IGNORECASE | input_api.re.MULTILINE)
  license_pattern = input_api.re.compile(
    r'^License: (.+)\r?$',
    input_api.re.IGNORECASE | input_api.re.MULTILINE)
  not_shipped_pattern = input_api.re.compile(
    r'^License File: NOT_SHIPPED\r?$',
    input_api.re.IGNORECASE | input_api.re.MULTILINE)
  license_android_compatible_pattern = input_api.re.compile(
    r'^License Android Compatible: (yes|no)\r?$',
    input_api.re.IGNORECASE | input_api.re.MULTILINE)

  for f in readmes:
    if 'D' in f.Action():
      _IgnoreIfDeleting(input_api, output_api, f, errors)
      continue

    contents = input_api.ReadFile(f)
    if (not shortname_pattern.search(contents)
        and not name_pattern.search(contents)):
      errors.append(output_api.PresubmitError(
        'Third party README files should contain either a \'Short Name\' or\n'
        'a \'Name\' which is the name under which the package is\n'
        'distributed. Check README.chromium.template for details.',
        [f]))
    if not version_pattern.search(contents):
      errors.append(output_api.PresubmitError(
        'Third party README files should contain a \'Version\' field.\n'
        'If the package is not versioned or the version is not known\n'
        'list the version as \'unknown\'.\n'
        'Check README.chromium.template for details.',
        [f]))
    if not release_pattern.search(contents):
      errors.append(output_api.PresubmitError(
        'Third party README files should contain a \'Security Critical\'\n'
        'field. This field specifies whether the package is built with\n'
        'Chromium. Check README.chromium.template for details.',
        [f]))
    license_match = license_pattern.search(contents)
    if not license_match:
      errors.append(output_api.PresubmitError(
        'Third party README files should contain a \'License\' field.\n'
        'This field specifies the license used by the package. Check\n'
        'README.chromium.template for details.',
        [f]))
    not_shipped_match = not_shipped_pattern.search(contents)
    android_compatible_match = (
        license_android_compatible_pattern.search(contents))
    if (not not_shipped_match and not android_compatible_match and
        not LicenseIsCompatibleWithAndroid(input_api, license_match.group(1))):
      errors.append(output_api.PresubmitPromptWarning(
        'Cannot determine whether specified license is compatible with\n' +
        'the Android licensing requirements. Please check that the license\n' +
        'name is spelled according to third_party/PRESUBMIT.py. Please see\n' +
        'README.chromium.template for details.',
        [f]))
  return errors


def _IgnoreIfDeleting(input_api, output_api, affected_file, errors):
  third_party_dir = input_api.os_path.dirname(affected_file.LocalPath()) + \
    os.path.sep
  for f in input_api.AffectedFiles():
    if f.LocalPath().startswith(third_party_dir):
      if 'D' not in f.Action():
        errors.append(output_api.PresubmitError(
          'Third party README should only be removed when the whole\n'
          'directory is being removed.\n', [f, affected_file]))
