# 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 _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 = []
  for git_file in input_api.AffectedTextFiles():
    filename = git_file.AbsoluteLocalPath()
    if filename.endswith('.dart'):
      if 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:
          # TODO(jacobr): verify that the error really is that the file was
          # added for this CL.
          old_version_has_errors = False

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

  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                DDC tests
      # =================       ==========================
      ("tests/language/",       "tests/language_2/"),
      ("tests/corelib/",        "tests/corelib_2/"),
      ("tests/lib/",            "tests/lib_2/"),
      ("tests/html/",           "tests/lib_2/html/"),
  ]

  result = []
  # Tuples of (new Dart 1 test path, expected DDC test path)
  dart1TestsAdded = []
  # Tuples of (original Dart test path, expected DDC test path)
  ddcTestsExists = []
  for f in input_api.AffectedFiles():
    for oldPath, newPath in testsDirectories:
      if f.LocalPath().startswith(oldPath):
        if f.Action() == 'A':
          # Compute where the new test should live.
          ddcTestPath = f.LocalPath().replace(oldPath, newPath)
          dart1TestsAdded.append((f.LocalPath(), ddcTestPath))
        elif f.Action() == 'M':
          # Find all modified tests in Dart 1.0
          filename = f.LocalPath()
          for oldPath, newPath in testsDirectories:
            if filename.find(oldPath) == 0:
              ddcTestFilePathAbs = "%s" % \
                  f.AbsoluteLocalPath().replace(oldPath, newPath)
              if os.path.isfile(ddcTestFilePathAbs):
                #originalDart1Test.append(f.LocalPath())
                ddcTestsExists.append((f.LocalPath(),
                    f.LocalPath().replace(oldPath, newPath)))

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

  if missingDDCTestsChange:
    errorList = []
    for idx, (orginalTest, ddcTest) in enumerate(missingDDCTestsChange):
      errorList.append(
          '%s. Dart 1.0 test changed: %s\n%s. DDC  test must change: ' \
          '%s\n' % (idx + 1, orginalTest, idx + 1, ddcTest))
    result.append(output_api.PresubmitError(
        'Error: If you change a Dart 1.0 test, you must also update the DDC '
        'test:\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 DDC 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 DDC test:\n'
        'Fix tests:\n%s' % ''.join(errorList)))

  return result

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

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