# Copyright 2017 The LUCI Authors.
#
# 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.

"""Top-level presubmit script.

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

import os
import re
import sys


def PreCommitGo(input_api, output_api, pcg_mode):
  """Run go-specific checks via pre-commit-go (pcg) if it's in PATH."""
  if input_api.is_committing:
    error_type = output_api.PresubmitError
  else:
    error_type = output_api.PresubmitPromptWarning

  exe = 'pcg.exe' if sys.platform == 'win32' else 'pcg'
  pcg = None
  for p in os.environ['PATH'].split(os.pathsep):
    pcg = os.path.join(p, exe)
    if os.access(pcg, os.X_OK):
      break
  else:
    return [
      error_type(
        'pre-commit-go executable (pcg) could not be found in PATH. All Go '
        'checks are skipped. See https://github.com/maruel/pre-commit-go.')
    ]

  cpus = max(1, input_api.cpu_count/2)
  cmd = [pcg, 'run', '-C', str(cpus), '-m', ','.join(pcg_mode)]
  if input_api.verbose:
    cmd.append('-v')
  # pcg can figure out what files to check on its own based on upstream ref,
  # but on PRESUBMIT try builder upsteram isn't set, and it's just 1 commit.
  if os.getenv('PRESUBMIT_BUILDER', ''):
    cmd.extend(['-r', 'HEAD~1'])
  return input_api.RunTests([
    input_api.Command(
      name='pre-commit-go: %s' % ', '.join(pcg_mode),
      cmd=cmd,
      kwargs={},
      message=error_type),
  ])


def WebChecks(input_api, output_api):
  """Run checks on the web/ directory."""
  if input_api.is_committing:
    error_type = output_api.PresubmitError
  else:
    error_type = output_api.PresubmitPromptWarning

  output = []
  output += input_api.RunTests([input_api.Command(
      name='web presubmit',
      cmd=[
          input_api.python_executable,
          input_api.os_path.join('web', 'web.py'),
          'presubmit',
      ],
      kwargs={},
      message=error_type,
  )])
  return output


COPYRIGHT_TEMPLATE = """
Copyright YEARPATTERN The LUCI Authors.

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.
""".strip()

def header(input_api):
  """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(2011, current_year + 1)))
  years_re = '(' + '|'.join(allowed_years) + ')'
  lines = [
    ('.*? ' + re.escape(line)) if line else '.*?'
    for line in COPYRIGHT_TEMPLATE.splitlines()
  ]
  lines[0] = lines[0].replace('YEARPATTERN', years_re)
  return '\n'.join(lines) + '(?: \*/)?\n'


def source_file_filter(input_api):
  """Returns filter that selects source code files only."""
  bl = list(input_api.DEFAULT_BLACK_LIST) + [
    r'.+/bootstrap/.*',  # third party
    r'.+/jquery/.*',  # third party
    r'.+/pb\.discovery\.go$',
    r'.+/pb\.discovery_test\.go$',
    r'.+\.pb\.go$',
    r'.+\.pb_test\.go$',
    r'.+_dec\.go$',
    r'.+_mux\.go$',
    r'.+_string\.go$',
    r'.+gae\.py$',  # symlinks from outside
    r'common/goroutine/goroutine_id.go',
    r'common/prpc/talk/.*',
    r'common/terminal/.*', # third party
    r'server/static/bower_components/.*',  # third party
    r'server/static/upload/bower_components/.*',  # third party
  ]
  wl = list(input_api.DEFAULT_WHITE_LIST) + [
    r'.+\.go$',
  ]
  return lambda x: input_api.FilterSourceFile(x, white_list=wl, black_list=bl)


def CommonChecks(input_api, output_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)))
  # currently broken: crbug.com/794670
  #results.extend(WebChecks(input_api, output_api))
  return results


def CheckChangeOnUpload(input_api, output_api):
  results = CommonChecks(input_api, output_api)
  results.extend(PreCommitGo(input_api, output_api, ['lint', 'pre-commit']))
  return results


def CheckChangeOnCommit(input_api, output_api):
  results = CommonChecks(input_api, output_api)
  results.extend(input_api.canned_checks.CheckChangeHasDescription(
      input_api, output_api))
  results.extend(input_api.canned_checks.CheckDoNotSubmitInDescription(
      input_api, output_api))
  results.extend(input_api.canned_checks.CheckDoNotSubmitInFiles(
      input_api, output_api))
  results.extend(PreCommitGo(
      input_api, output_api, ['continuous-integration']))
  return results
