# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

from collections import defaultdict
import fnmatch
import json
import os
import re
import subprocess
import sys

# TODO(dcheng): It's kind of horrible that this is copy and pasted from
# presubmit_canned_checks.py, but it's far easier than any of the alternatives.
def _ReportErrorFileAndLine(filename, line_num, dummy_line):
  """Default error formatter for _FindNewViolationsOfRule."""
  return '%s:%s' % (filename, line_num)


class MockCannedChecks(object):
  def _FindNewViolationsOfRule(self, callable_rule, input_api,
                               source_file_filter=None,
                               error_formatter=_ReportErrorFileAndLine):
    """Find all newly introduced violations of a per-line rule (a callable).

    Arguments:
      callable_rule: a callable taking a file extension and line of input and
        returning True if the rule is satisfied and False if there was a
        problem.
      input_api: object to enumerate the affected files.
      source_file_filter: a filter to be passed to the input api.
      error_formatter: a callable taking (filename, line_number, line) and
        returning a formatted error string.

    Returns:
      A list of the newly-introduced violations reported by the rule.
    """
    errors = []
    for f in input_api.AffectedFiles(include_deletes=False,
                                     file_filter=source_file_filter):
      # For speed, we do two passes, checking first the full file.  Shelling out
      # to the SCM to determine the changed region can be quite expensive on
      # Win32.  Assuming that most files will be kept problem-free, we can
      # skip the SCM operations most of the time.
      extension = str(f.LocalPath()).rsplit('.', 1)[-1]
      if all(callable_rule(extension, line) for line in f.NewContents()):
        continue  # No violation found in full text: can skip considering diff.

      for line_num, line in f.ChangedContents():
        if not callable_rule(extension, line):
          errors.append(error_formatter(f.LocalPath(), line_num, line))

    return errors


class MockInputApi(object):
  """Mock class for the InputApi class.

  This class can be used for unittests for presubmit by initializing the files
  attribute as the list of changed files.
  """

  DEFAULT_FILES_TO_SKIP = ()

  def __init__(self):
    self.canned_checks = MockCannedChecks()
    self.fnmatch = fnmatch
    self.json = json
    self.re = re
    self.os_path = os.path
    self.platform = sys.platform
    self.python_executable = sys.executable
    self.platform = sys.platform
    self.subprocess = subprocess
    self.sys = sys
    self.files = []
    self.is_committing = False
    self.change = MockChange([])
    self.presubmit_local_path = os.path.dirname(__file__)

  def CreateMockFileInPath(self, f_list):
    self.os_path.exists = lambda x: x in f_list

  def AffectedFiles(self, file_filter=None, include_deletes=False):
    for file in self.files:
      if file_filter and not file_filter(file):
        continue
      if not include_deletes and file.Action() == 'D':
        continue
      yield file

  def AffectedSourceFiles(self, file_filter=None):
    return self.AffectedFiles(file_filter=file_filter)

  def FilterSourceFile(self, file,
                       files_to_check=(), files_to_skip=()):
    local_path = file.LocalPath()
    found_in_files_to_check = not files_to_check
    if files_to_check:
      if type(files_to_check) is str:
        raise TypeError('files_to_check should be an iterable of strings')
      for pattern in files_to_check:
        compiled_pattern = re.compile(pattern)
        if compiled_pattern.search(local_path):
          found_in_files_to_check = True
          break
    if files_to_skip:
      if type(files_to_skip) is str:
        raise TypeError('files_to_skip should be an iterable of strings')
      for pattern in files_to_skip:
        compiled_pattern = re.compile(pattern)
        if compiled_pattern.search(local_path):
          return False
    return found_in_files_to_check

  def LocalPaths(self):
    return [file.LocalPath() for file in self.files]

  def PresubmitLocalPath(self):
    return self.presubmit_local_path

  def ReadFile(self, filename, mode='rU'):
    if hasattr(filename, 'AbsoluteLocalPath'):
       filename = filename.AbsoluteLocalPath()
    for file_ in self.files:
      if file_.LocalPath() == filename:
        return '\n'.join(file_.NewContents())
    # Otherwise, file is not in our mock API.
    raise IOError, "No such file or directory: '%s'" % filename


class MockOutputApi(object):
  """Mock class for the OutputApi class.

  An instance of this class can be passed to presubmit unittests for outputing
  various types of results.
  """

  class PresubmitResult(object):
    def __init__(self, message, items=None, long_text=''):
      self.message = message
      self.items = items
      self.long_text = long_text

    def __repr__(self):
      return self.message

  class PresubmitError(PresubmitResult):
    def __init__(self, message, items=None, long_text=''):
      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
      self.type = 'error'

  class PresubmitPromptWarning(PresubmitResult):
    def __init__(self, message, items=None, long_text=''):
      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
      self.type = 'warning'

  class PresubmitNotifyResult(PresubmitResult):
    def __init__(self, message, items=None, long_text=''):
      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
      self.type = 'notify'

  class PresubmitPromptOrNotify(PresubmitResult):
    def __init__(self, message, items=None, long_text=''):
      MockOutputApi.PresubmitResult.__init__(self, message, items, long_text)
      self.type = 'promptOrNotify'

  def __init__(self):
    self.more_cc = []

  def AppendCC(self, more_cc):
    self.more_cc.extend(more_cc)


class MockFile(object):
  """Mock class for the File class.

  This class can be used to form the mock list of changed files in
  MockInputApi for presubmit unittests.
  """

  def __init__(self, local_path, new_contents, old_contents=None, action='A',
               scm_diff=None):
    self._local_path = local_path
    self._new_contents = new_contents
    self._changed_contents = [(i + 1, l) for i, l in enumerate(new_contents)]
    self._action = action
    if scm_diff:
      self._scm_diff = scm_diff
    else:
      self._scm_diff = (
        "--- /dev/null\n+++ %s\n@@ -0,0 +1,%d @@\n" %
            (local_path, len(new_contents)))
      for l in new_contents:
        self._scm_diff += "+%s\n" % l
    self._old_contents = old_contents

  def Action(self):
    return self._action

  def ChangedContents(self):
    return self._changed_contents

  def NewContents(self):
    return self._new_contents

  def LocalPath(self):
    return self._local_path

  def AbsoluteLocalPath(self):
    return self._local_path

  def GenerateScmDiff(self):
    return self._scm_diff

  def OldContents(self):
    return self._old_contents

  def rfind(self, p):
    """os.path.basename is called on MockFile so we need an rfind method."""
    return self._local_path.rfind(p)

  def __getitem__(self, i):
    """os.path.basename is called on MockFile so we need a get method."""
    return self._local_path[i]

  def __len__(self):
    """os.path.basename is called on MockFile so we need a len method."""
    return len(self._local_path)

  def replace(self, altsep, sep):
    """os.path.basename is called on MockFile so we need a replace method."""
    return self._local_path.replace(altsep, sep)


class MockAffectedFile(MockFile):
  def AbsoluteLocalPath(self):
    return self._local_path


class MockChange(object):
  """Mock class for Change class.

  This class can be used in presubmit unittests to mock the query of the
  current change.
  """

  def __init__(self, changed_files):
    self._changed_files = changed_files
    self.footers = defaultdict(list)

  def LocalPaths(self):
    return self._changed_files

  def AffectedFiles(self, include_dirs=False, include_deletes=True,
                    file_filter=None):
    return self._changed_files

  def GitFootersFromDescription(self):
    return self.footers

