# Copyright 2014 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 mojo

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

import os.path
import re

# NOTE: The EDK allows all external paths, so doesn't need a whitelist.
_PACKAGE_WHITELISTED_EXTERNAL_PATHS = {
    "SDK": ["//build/module_args/mojo.gni",
            "//build/module_args/dart.gni",
            "//testing/gtest",
            "//third_party/cython",
            "//third_party/khronos"],
    "services": ["//build/module_args/mojo.gni",
                 "//testing/gtest"],
}

# These files are not part of the exported package.
_PACKAGE_IGNORED_BUILD_FILES = {
    "SDK": {},
    "EDK": {},
    "services": {"mojo/services/BUILD.gn"},
}


_PACKAGE_PATH_PREFIXES = {"SDK": "mojo/public/",
                          "EDK": "mojo/edk/",
                          "services": "mojo/services"}

# TODO(etiennej): python_binary_source_set added due to crbug.com/443147
_PACKAGE_SOURCE_SET_TYPES = {"SDK": ["mojo_sdk_source_set",
                                     "python_binary_source_set"],
                             "EDK": ["mojo_edk_source_set"],
                             "services": ["mojo_sdk_source_set"]}

_ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE = \
    "Found disallowed external paths within SDK buildfiles."

_ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE = \
    "Found references to services' public buildfiles via absolute paths " \
    "within services' public buildfiles."

_ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE = \
    "Found references to the EDK via absolute paths within EDK buildfiles."

_ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE = \
    "Found references to the SDK via absolute paths within %s buildfiles."

_ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES = {
  "SDK": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE % "SDK",
  "EDK": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE % "EDK",
  "services": _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGE_TEMPLATE
      % "services' public",
}

_INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE = \
    "All source sets in %s must be constructed via %s."

_INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES = {
  "SDK": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE
      % ("the SDK", _PACKAGE_SOURCE_SET_TYPES["SDK"]),
  "EDK": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE
      % ("the EDK", _PACKAGE_SOURCE_SET_TYPES["EDK"]),
  "services": _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGE_TEMPLATE
      % ("services' client libs", _PACKAGE_SOURCE_SET_TYPES["services"]),
}

def _IsBuildFileWithinPackage(f, package):
  """Returns whether |f| specifies a GN build file within |package|."""
  assert package in _PACKAGE_PATH_PREFIXES
  package_path_prefix = _PACKAGE_PATH_PREFIXES[package]

  if not f.LocalPath().startswith(package_path_prefix):
    return False
  if (not f.LocalPath().endswith("/BUILD.gn") and
      not f.LocalPath().endswith(".gni")):
    return False
  if f.LocalPath() in _PACKAGE_IGNORED_BUILD_FILES[package]:
    return False
  return True

def _AffectedBuildFilesWithinPackage(input_api, package):
  """Returns all the affected build files within |package|."""
  return [f for f in input_api.AffectedFiles()
      if _IsBuildFileWithinPackage(f, package)]

def _FindIllegalAbsolutePathsInBuildFiles(input_api, package):
  """Finds illegal absolute paths within the build files in
  |input_api.AffectedFiles()| that are within |package|.
  An illegal absolute path within the SDK or a service's SDK is one that is to
  the SDK itself or a non-whitelisted external path. An illegal absolute path
  within the EDK is one that is to the SDK or the EDK.
  Returns any such references in a list of (file_path, line_number,
  referenced_path) tuples."""
  illegal_references = []
  for f in _AffectedBuildFilesWithinPackage(input_api, package):
    for line_num, line in f.ChangedContents():
      # Determine if this is a reference to an absolute path.
      m = re.search(r'"(//[^"]*)"', line)
      if not m:
        continue
      referenced_path = m.group(1)

      if not referenced_path.startswith("//mojo"):
        # In the EDK, all external absolute paths are allowed.
        if package == "EDK":
          continue

        # Determine if this is a whitelisted external path.
        if referenced_path in _PACKAGE_WHITELISTED_EXTERNAL_PATHS[package]:
          continue

      illegal_references.append((f.LocalPath(), line_num, referenced_path))

  return illegal_references

def _PathReferenceInBuildFileWarningItem(build_file, line_num, referenced_path):
  """Returns a string expressing a warning item that |referenced_path| is
  referenced at |line_num| in |build_file|."""
  return "%s, line %d (%s)" % (build_file, line_num, referenced_path)

def _IncorrectSourceSetTypeWarningItem(build_file, line_num):
  """Returns a string expressing that the error occurs at |line_num| in
  |build_file|."""
  return "%s, line %d" % (build_file, line_num)

def _CheckNoIllegalAbsolutePathsInBuildFiles(input_api, output_api, package):
  """Makes sure that the BUILD.gn files within |package| do not reference the
  SDK/EDK via absolute paths, and do not reference disallowed external
  dependencies."""
  sdk_references = []
  edk_references = []
  external_deps_references = []
  services_references = []

  # Categorize any illegal references.
  illegal_references = _FindIllegalAbsolutePathsInBuildFiles(input_api, package)
  for build_file, line_num, referenced_path in illegal_references:
    reference_string = _PathReferenceInBuildFileWarningItem(build_file,
                                                            line_num,
                                                            referenced_path)
    if referenced_path.startswith("//mojo/public"):
      sdk_references.append(reference_string)
    elif package == "SDK":
      external_deps_references.append(reference_string)
    elif package == "services":
      if referenced_path.startswith("//mojo/services"):
        services_references.append(reference_string)
      else:
        external_deps_references.append(reference_string)
    elif referenced_path.startswith("//mojo/edk"):
      edk_references.append(reference_string)

  # Package up categorized illegal references into results.
  results = []
  if sdk_references:
    results.extend([output_api.PresubmitError(
        _ILLEGAL_SDK_ABSOLUTE_PATH_WARNING_MESSAGES[package],
        items=sdk_references)])

  if external_deps_references:
    assert package == "SDK" or package == "services"
    results.extend([output_api.PresubmitError(
        _ILLEGAL_EXTERNAL_PATH_WARNING_MESSAGE,
        items=external_deps_references)])

  if services_references:
    assert package == "services"
    results.extend([output_api.PresubmitError(
        _ILLEGAL_SERVICES_ABSOLUTE_PATH_WARNING_MESSAGE,
        items=services_references)])

  if edk_references:
    assert package == "EDK"
    results.extend([output_api.PresubmitError(
        _ILLEGAL_EDK_ABSOLUTE_PATH_WARNING_MESSAGE,
        items=edk_references)])

  return results

def _CheckSourceSetsAreOfCorrectType(input_api, output_api, package):
  """Makes sure that the BUILD.gn files always use the correct wrapper type for
  |package|, which can be one of ["SDK", "EDK"], to construct source_set
  targets."""
  assert package in _PACKAGE_SOURCE_SET_TYPES
  required_source_set_type = _PACKAGE_SOURCE_SET_TYPES[package]

  problems = []
  for f in _AffectedBuildFilesWithinPackage(input_api, package):
    for line_num, line in f.ChangedContents():
      m = re.search(r"[a-z_]*source_set\(", line)
      if not m:
        continue
      source_set_type = m.group(0)[:-1]
      if source_set_type in required_source_set_type:
        continue
      problems.append(_IncorrectSourceSetTypeWarningItem(f.LocalPath(),
                                                         line_num))

  if not problems:
    return []
  return [output_api.PresubmitError(
      _INCORRECT_SOURCE_SET_TYPE_WARNING_MESSAGES[package],
      items=problems)]

def _CheckChangePylintsClean(input_api, output_api):
  # Additional python module paths (we're in src/mojo/); not everyone needs
  # them, but it's easiest to add them to everyone's path.
  # For ply and jinja2:
  third_party_path = os.path.join(
      input_api.PresubmitLocalPath(), "..", "third_party")
  # For the bindings generator:
  mojo_public_bindings_pylib_path = os.path.join(
      input_api.PresubmitLocalPath(), "public", "tools", "bindings", "pylib")
  # For the python bindings:
  mojo_python_bindings_path = os.path.join(
      input_api.PresubmitLocalPath(), "public", "python")
  # For the python bindings tests:
  mojo_python_bindings_tests_path = os.path.join(
      input_api.PresubmitLocalPath(), "python", "tests")
  # For the roll tools scripts:
  mojo_roll_tools_path = os.path.join(
      input_api.PresubmitLocalPath(), "tools", "roll")
  # For all mojo/tools scripts:
  mopy_path = os.path.join(input_api.PresubmitLocalPath(), "tools")
  # For all mojo/devtools scripts:
  devtools_path = os.path.join(input_api.PresubmitLocalPath(), "devtools")
  # TODO(vtl): Don't lint these files until the (many) problems are fixed
  # (possibly by deleting/rewriting some files).
  temporary_black_list = (
      r".*\bpublic[\\\/]tools[\\\/]bindings[\\\/]pylib[\\\/]mojom[\\\/]"
          r"generate[\\\/].+\.py$",
      r".*\bpublic[\\\/]tools[\\\/]bindings[\\\/]generators[\\\/].+\.py$")
  black_list = input_api.DEFAULT_BLACK_LIST + temporary_black_list + (
      # Imported from Android tools, we might want not to fix the warnings
      # raised for it to make it easier to compare the code with the original.
      r".*\bdevtools[\\\/]common[\\\/]android_stack_parser[\\\/].+\.py$",)

  results = []
  pylint_extra_paths = [
      third_party_path,
      mojo_public_bindings_pylib_path,
      mojo_python_bindings_path,
      mojo_python_bindings_tests_path,
      mojo_roll_tools_path,
      mopy_path,
      devtools_path
  ]
  results.extend(input_api.canned_checks.RunPylint(
      input_api, output_api, extra_paths_list=pylint_extra_paths,
      black_list=black_list))
  return results

def _BuildFileChecks(input_api, output_api):
  """Performs checks on SDK, EDK, and services' public buildfiles."""
  results = []
  for package in ["SDK", "EDK", "services"]:
    results.extend(_CheckNoIllegalAbsolutePathsInBuildFiles(input_api,
                                                            output_api,
                                                            package))
    results.extend(_CheckSourceSetsAreOfCorrectType(input_api,
                                                    output_api,
                                                    package))
  return results

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

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

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