# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


def white_list(input_api):
  return input_api.DEFAULT_WHITE_LIST


def black_list(input_api):
  return list(input_api.DEFAULT_BLACK_LIST) + [
      'build/.*',
      'dist/.*',
      '.*[.]recipe_deps/.*',
  ]


def header(input_api):  # pragma: no cover
  """Returns the expected license header regexp for this project."""
  current_year = int(input_api.time.strftime('%Y'))
  allowed_years = (str(s) for s in reversed(xrange(2017, current_year + 1)))
  years_re = '(' + '|'.join(allowed_years) + ')'
  license_header = (
    r'.*Copyright %(year)s Google Inc\.\n.*\n'
    r'.*Licensed under the Apache License, Version 2.0 \(the "License"\);\n'
    r'.*you may not use this file except in compliance with the License\.\n'
    r'.*You may obtain a copy of the License at\n.*\n'
    r'.*http://www.apache.org/licenses/LICENSE-2.0\n.*\n'
    r'.*Unless required by applicable law or agreed to in writing, software\n'
    r'.*distributed under the License is distributed on an "AS IS" BASIS,\n'
    r'.*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or '
      r'implied\.\n'
    r'.*See the License for the specific language governing permissions and\n'
    r'.*limitations under the License\.'
  ) % {
    'year': years_re,
  }
  return license_header


def source_file_filter(input_api):  # pragma: no cover
  """Returns filter that selects source code files only."""
  return lambda x: input_api.FilterSourceFile(
      x, white_list=white_list(input_api), black_list=black_list(input_api))


def CommonChecks(input_api, output_api):  # pragma: no cover
  bl = black_list(input_api)
  wl = white_list(input_api)
  results = []
  results.extend(
    input_api.canned_checks.CheckChangeHasNoStrayWhitespace(
      input_api, output_api,
      source_file_filter=source_file_filter(input_api)))
  results.extend(
    input_api.canned_checks.CheckLicense(
      input_api, output_api, header(input_api),
      source_file_filter=source_file_filter(input_api)))

  disabled_warnings = [
      'cyclic-import', # TODO(sergeyberezin): get rid of this warning.
      'no-value-for-parameter',
      'redefined-builtin',  # TODO(sergeyberezin): rename 'input.py'
      'relative-import',
  ]
  results.extend(input_api.RunTests(input_api.canned_checks.RunPylint(
      input_api, output_api, white_list=wl, black_list=bl,
      disabled_warnings=disabled_warnings,
  )))
  return results


def CheckChangeOnUpload(input_api, output_api):  # pragma: no cover
  results = CommonChecks(input_api, output_api)
  return results


def CheckChangeOnCommit(input_api, output_api):  # pragma: no cover
  results = CommonChecks(input_api, output_api)
  results.extend(input_api.canned_checks.CheckOwners(input_api, output_api))
  results.extend(
      input_api.canned_checks.CheckDoNotSubmit(input_api, output_api))
  return results
