# Copyright (c) 2011, 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.

import os
import cpplint
import re


class PathHackException(Exception):
  def __init__(self, error_msg):
    self.error_msg = error_msg

  def __str__(self):
    return repr(self.error_msg)


def TrySvnPathHack(parent_path):
  orig_path = os.path.join(parent_path, '.svn')
  renamed_path = os.path.join(parent_path, '.svn_orig')
  if os.path.exists(renamed_path):
    error_msg = '".svn_orig" exists in presubmit parent directory('
    error_msg += parent_path
    error_msg += '). Consider renaming it manually to ".svn".'
    raise PathHackException(error_msg)
  if os.path.exists(orig_path):
    # Make the parent SVN directory non-discoverable by cpplint to get
    # the correct header guard checks. This is needed if using all Dart
    # checkout.
    os.rename(orig_path, renamed_path)
    return lambda: os.rename(renamed_path, orig_path)


def TryGitPathHack(filename, parent_path):
  def CommonSubdirectory(parent, child):
    while len(child) > len(parent):
      child, tail = os.path.split(child)
      if child == parent:
        return os.path.join(parent, tail)
  if os.path.exists(os.path.join(parent_path, '.git')):
    runtime_path = CommonSubdirectory(parent_path, filename)
    if runtime_path is not None:
      fake_svn_path = os.path.join(runtime_path, '.svn')
      if os.path.exists(fake_svn_path):
        error_msg = '".svn" exists in presubmit parent subdirectory('
        error_msg += fake_svn_path
        error_msg += '). Consider removing it manually.'
        raise PathHackException(error_msg)
      # Deposit a file named ".svn" in the runtime directory to fool
      # cpplint into thinking it is the source root.
      open(fake_svn_path, 'w').close()
      return lambda: os.remove(fake_svn_path)


def RunLint(input_api, output_api):
  result = []
  cpplint._cpplint_state.ResetErrorCounts()
  memcpy_match_count = 0
  # Find all .cc and .h files in the change list.
  for svn_file in input_api.AffectedTextFiles():
    filename = svn_file.AbsoluteLocalPath()
    if filename.endswith('.cc') or filename.endswith('.h'):
      cleanup = None
      parent_path = os.path.dirname(input_api.PresubmitLocalPath())
      try:
        if filename.endswith('.h'):
          cleanup = TrySvnPathHack(parent_path)
          if cleanup is None:
            cleanup = TryGitPathHack(filename, parent_path)
      except PathHackException, exception:
        return [output_api.PresubmitError(str(exception))]
      # Run cpplint on the file.
      cpplint.ProcessFile(filename, 1)
      if cleanup is not None:
        cleanup()
      # memcpy does not handle overlapping memory regions. Even though this
      # is well documented it seems to be used in error quite often. To avoid
      # problems we disallow the direct use of memcpy.  The exceptions are in
      # third-party code and in platform/globals.h which uses it to implement
      # bit_cast and bit_copy.
      if not filename.endswith(os.path.join('platform', 'globals.h')) and \
         filename.find('third_party') == -1:
        fh = open(filename, 'r')
        content = fh.read()
        match = re.search('\\bmemcpy\\b', content)
        if match:
          line_number = content[0:match.start()].count('\n') + 1
          print "%s:%d: use of memcpy is forbidden" % (filename, line_number)
          memcpy_match_count += 1

  # Report a presubmit error if any of the files had an error.
  if cpplint._cpplint_state.error_count > 0 or memcpy_match_count > 0:
    result = [output_api.PresubmitError('Failed cpplint check.')]
  return result


def CheckChangeOnUpload(input_api, output_api):
  return RunLint(input_api, output_api)


def CheckChangeOnCommit(input_api, output_api):
  return RunLint(input_api, output_api)
