# Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

"""Top-level presubmit script for Dart.

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

import imp
import os
import os.path
import scm
import subprocess
import tempfile


def _CheckFormat(input_api, identification, extension, windows,
    hasFormatErrors):
  local_root = input_api.change.RepositoryRoot()
  upstream = input_api.change._upstream
  unformatted_files = []
  for git_file in input_api.AffectedTextFiles():
    filename = git_file.AbsoluteLocalPath()
    if filename.endswith(extension) and hasFormatErrors(filename=filename):
      old_version_has_errors = False
      try:
        path = git_file.LocalPath()
        if windows:
          # Git expects a linux style path.
          path = path.replace(os.sep, '/')
        old_contents = scm.GIT.Capture(
          ['show', upstream + ':' + path],
          cwd=local_root,
          strip_out=False)
        if hasFormatErrors(contents=old_contents):
          old_version_has_errors = True
      except subprocess.CalledProcessError as e:
        old_version_has_errors = False

      if old_version_has_errors:
        print("WARNING: %s has existing and possibly new %s issues" %
          (git_file.LocalPath(), identification))
      else:
        unformatted_files.append(filename)

  return unformatted_files


def _CheckBuildStatus(input_api, output_api):
  results = []
  status_check = input_api.canned_checks.CheckTreeIsOpen(
      input_api,
      output_api,
      json_url='http://dart-status.appspot.com/current?format=json')
  results.extend(status_check)
  return results


def _CheckDartFormat(input_api, output_api):
  local_root = input_api.change.RepositoryRoot()
  upstream = input_api.change._upstream
  utils = imp.load_source('utils',
      os.path.join(local_root, 'tools', 'utils.py'))

  prebuilt_dartfmt = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dartfmt')

  windows = utils.GuessOS() == 'win32'
  if windows:
    prebuilt_dartfmt += '.bat'

  if not os.path.isfile(prebuilt_dartfmt):
    print('WARNING: dartfmt not found: %s' % (prebuilt_dartfmt))
    return []

  def HasFormatErrors(filename=None, contents=None):
    args = [prebuilt_dartfmt, '--set-exit-if-changed']
    if not contents:
      args += [filename, '-n']

    process = subprocess.Popen(args,
                               stdout=subprocess.PIPE,
                               stdin=subprocess.PIPE
                               )
    process.communicate(input=contents)

    # Check for exit code 1 explicitly to distinguish it from a syntax error
    # in the file (exit code 65). The repo contains many Dart files that are
    # known to have syntax errors for testing purposes and which can't be
    # parsed and formatted. Don't treat those as errors.
    return process.returncode == 1

  unformatted_files = _CheckFormat(input_api, "dartfmt", ".dart", windows,
      HasFormatErrors)

  if unformatted_files:
    lineSep = " \\\n"
    if windows:
      lineSep = " ^\n";
    return [output_api.PresubmitError(
        'File output does not match dartfmt.\n'
        'Fix these issues with:\n'
        '%s -w%s%s' % (prebuilt_dartfmt, lineSep,
            lineSep.join(unformatted_files)))]

  return []


def _CheckNewTests(input_api, output_api):
  testsDirectories = [
      #    Dart 1 tests              Dart 2.0 tests
      # =================       ==========================
      ("tests/language/",       "tests/language_2/"),
      ("tests/corelib/",        "tests/corelib_2/"),
      ("tests/lib/",            "tests/lib_2/"),
      ("tests/html/",           "tests/lib_2/html/"),
      ("tests/isolate/",        "tests/lib_2/isolate/")
  ]

  result = []
  # Tuples of (new Dart 1 test path, expected Dart 2.0 test path)
  dart1TestsAdded = []
  # Tuples of (original Dart test path, expected Dart 2.0 test path)
  dart2TestsExists = []
  for f in input_api.AffectedTextFiles():
    localpath = f.LocalPath()
    if not(localpath.endswith('.status')):
      for oldPath, newPath in testsDirectories:
        if localpath.startswith(oldPath):
          if f.Action() == 'A':
            # Compute where the new test should live.
            dart2TestPath = localpath.replace(oldPath, newPath)
            dart1TestsAdded.append((localpath, dart2TestPath))
          elif f.Action() == 'M':
            # Find all modified tests in Dart 1.0
            for oldPath, newPath in testsDirectories:
              if localpath.find(oldPath) == 0:
                dart2TestFilePathAbs = "%s" % \
                    f.AbsoluteLocalPath().replace(oldPath, newPath)
                if os.path.isfile(dart2TestFilePathAbs):
                  #originalDart1Test.append(localpath)
                  dart2TestsExists.append((localpath,
                      localpath.replace(oldPath, newPath)))

  # Does a Dart 2.0 test exist if so it must be changed too.
  missingDart2TestsChange = []
  for (dartTest, dart2Test) in dart2TestsExists:
    foundDart2TestModified = False
    for f in input_api.AffectedFiles():
      if f.LocalPath() == dart2Test:
        # Found corresponding Dart 2 test - great.
        foundDart2TestModified = True
        break
    if not foundDart2TestModified:
      # Add the tuple (dart 1 test path, Dart 2.0 test path)
      missingDart2TestsChange.append((dartTest, dart2Test))

  if missingDart2TestsChange:
    errorList = []
    for idx, (orginalTest, dart2Test) in enumerate(missingDart2TestsChange):
      errorList.append(
          '%s. Dart 1.0 test changed: %s\n%s. Only the Dart 2.0 test can '\
          'change: %s\n' % (idx + 1, orginalTest, idx + 1, dart2Test))
    result.append(output_api.PresubmitError(
        'Error: Changed Dart 1.0 test detected - only 1.0 status files can '\
        'change. Migrate test to Dart 2.0 tests:\n%s' % ''.join(errorList)))

  if dart1TestsAdded:
    errorList = []
    for idx, (oldTestPath, newTestPath) in enumerate(dart1TestsAdded):
      errorList.append('%s. New Dart 1.0  test: %s\n'
          '%s. Should be Dart 2.0 test: %s\n' % \
          (idx + 1, oldTestPath, idx + 1, newTestPath))
    result.append(output_api.PresubmitError(
        'Error: New Dart 1.0 test can not be added the test must be added '\
        'as a Dart 2.0 test:\nFix tests:\n%s' % ''.join(errorList)))

  return result


def _CheckStatusFiles(input_api, output_api):
  local_root = input_api.change.RepositoryRoot()
  upstream = input_api.change._upstream
  utils = imp.load_source('utils',
      os.path.join(local_root, 'tools', 'utils.py'))

  dart = os.path.join(utils.CheckedInSdkPath(), 'bin', 'dart')
  lint = os.path.join(local_root, 'pkg', 'status_file', 'bin', 'lint.dart')

  windows = utils.GuessOS() == 'win32'
  if windows:
    dart += '.bat'

  if not os.path.isfile(dart):
    print('WARNING: dart not found: %s' % dart)
    return []

  if not os.path.isfile(lint):
    print('WARNING: Status file linter not found: %s' % lint)
    return []

  def HasFormatErrors(filename=None, contents=None):
    args = [dart, lint] + (['-t'] if contents else [filename])
    process = subprocess.Popen(args,
                               stdout=subprocess.PIPE,
                               stdin=subprocess.PIPE)
    process.communicate(input=contents)
    return process.returncode != 0

  unformatted_files = _CheckFormat(input_api, "status file", ".status",
      windows, HasFormatErrors)

  if unformatted_files:
    normalize = os.path.join(local_root, 'pkg', 'status_file', 'bin',
        'normalize.dart')
    lineSep = " \\\n"
    if windows:
      lineSep = " ^\n";
    return [output_api.PresubmitError(
        'Status files are not normalized.\n'
        'Fix these issues with:\n'
        '%s %s -w%s%s' % (dart, normalize, lineSep,
            lineSep.join(unformatted_files)))]

  return []


def _CheckValidHostsInDEPS(input_api, output_api):
  """Checks that DEPS file deps are from allowed_hosts."""
  # Run only if DEPS file has been modified to annoy fewer bystanders.
  if all(f.LocalPath() != 'DEPS' for f in input_api.AffectedFiles()):
    return []
  # Outsource work to gclient verify
  try:
    input_api.subprocess.check_output(['gclient', 'verify'])
    return []
  except input_api.subprocess.CalledProcessError, error:
    return [output_api.PresubmitError(
        'DEPS file must have only dependencies from allowed hosts.',
        long_text=error.output)]


def CheckChangeOnCommit(input_api, output_api):
  return (_CheckValidHostsInDEPS(input_api, output_api) +
          _CheckBuildStatus(input_api, output_api) +
          _CheckNewTests(input_api, output_api) +
          _CheckDartFormat(input_api, output_api) +
          _CheckStatusFiles(input_api, output_api))


def CheckChangeOnUpload(input_api, output_api):
  return (_CheckValidHostsInDEPS(input_api, output_api) +
          _CheckNewTests(input_api, output_api) +
          _CheckDartFormat(input_api, output_api) +
          _CheckStatusFiles(input_api, output_api))
