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

"""Checks protobuf files for illegal imports."""



import codecs
import os
import re

import results
from rules import Rule, MessageRule


class ProtoChecker(object):

  EXTENSIONS = [
      '.proto',
  ]

  # The maximum number of non-import lines we can see before giving up.
  _MAX_UNINTERESTING_LINES = 50

  # The maximum line length, this is to be efficient in the case of very long
  # lines (which can't be import).
  _MAX_LINE_LENGTH = 128

  # This regular expression will be used to extract filenames from import
  # statements.
  _EXTRACT_IMPORT_PATH = re.compile(
      r'[ \t]*[ \t]*import[ \t]+"(.*)"')

  def __init__(self, verbose, resolve_dotdot=False, root_dir=''):
    self._verbose = verbose
    self._resolve_dotdot = resolve_dotdot
    self._root_dir = root_dir

  def IsFullPath(self, import_path):
    """Checks if the given path is a valid path starting from |_root_dir|."""
    match = re.match(r'(.*)/([^/]*\.proto)', import_path)
    if not match:
      return False
    return os.path.isdir(self._root_dir + "/" + match.group(1))

  def CheckLine(self, rules, line, dependee_path, fail_on_temp_allow=False):
    """Checks the given line with the given rule set.

    Returns a tuple (is_import, dependency_violation) where
    is_import is True only if the line is an import
    statement, and dependency_violation is an instance of
    results.DependencyViolation if the line violates a rule, or None
    if it does not.
    """
    found_item = self._EXTRACT_IMPORT_PATH.match(line)
    if not found_item:
      return False, None  # Not a match

    import_path = found_item.group(1)

    if '\\' in import_path:
      return True, results.DependencyViolation(
          import_path,
          MessageRule('Import paths may not include backslashes.'),
          rules)

    if '/' not in import_path:
      # Don't fail when no directory is specified. We may want to be more
      # strict about this in the future.
      if self._verbose:
        print(' WARNING: import specified with no directory: ' + import_path)
      return True, None

    if self._resolve_dotdot and '../' in import_path:
      dependee_dir = os.path.dirname(dependee_path)
      import_path = os.path.join(dependee_dir, import_path)
      import_path = os.path.relpath(import_path, self._root_dir)

    if not self.IsFullPath(import_path):
      return True, None

    rule = rules.RuleApplyingTo(import_path, dependee_path)

    if (rule.allow == Rule.DISALLOW or
        (fail_on_temp_allow and rule.allow == Rule.TEMP_ALLOW)):
      return True, results.DependencyViolation(import_path, rule, rules)
    return True, None

  def CheckFile(self, rules, filepath):
    if self._verbose:
      print('Checking: ' + filepath)

    dependee_status = results.DependeeStatus(filepath)
    last_import = 0
    with codecs.open(filepath, encoding='utf-8') as f:
      for line_num, line in enumerate(f):
        if line_num - last_import > self._MAX_UNINTERESTING_LINES:
          break

        line = line.strip()

        is_import, violation = self.CheckLine(rules, line, filepath)
        if is_import:
          last_import = line_num
        if violation:
          dependee_status.AddViolation(violation)

    return dependee_status

  @staticmethod
  def IsProtoFile(file_path):
    """Returns True iff the given path ends in one of the extensions
    handled by this checker.
    """
    return os.path.splitext(file_path)[1] in ProtoChecker.EXTENSIONS

  def ShouldCheck(self, file_path):
    """Check if the new #include file path should be presubmit checked.

    Args:
      file_path: file path to be checked

    Return:
      bool: True if the file should be checked; False otherwise.
    """
    return self.IsProtoFile(file_path)
