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

"""Checks Java files for illegal imports."""

import codecs
import os
import re

import results
from rules import Rule


class JavaChecker(object):
  """Import checker for Java files.

  The CheckFile method uses real filesystem paths, but Java imports work in
  terms of package names. To deal with this, we have an extra "prescan" pass
  that reads all the .java files and builds a mapping of class name -> filepath.
  In CheckFile, we convert each import statement into a real filepath, and check
  that against the rules in the DEPS files.

  Note that in Java you can always use classes in the same directory without an
  explicit import statement, so these imports can't be blocked with DEPS files.
  But that shouldn't be a problem, because same-package imports are pretty much
  always correct by definition. (If we find a case where this is *not* correct,
  it probably means the package is too big and needs to be split up.)

  Properties:
    _classmap: dict of fully-qualified Java class name -> filepath
  """

  EXTENSIONS = ['.java']

  # This regular expression will be used to extract filenames from import
  # statements.
  _EXTRACT_IMPORT_PATH = re.compile('^import\s+(?:static\s+)?([\w\.]+)\s*;')

  def __init__(self, base_directory, verbose, added_imports=None,
               allow_multiple_definitions=None):
    self._base_directory = base_directory
    self._verbose = verbose
    self._classmap = {}
    self._allow_multiple_definitions = allow_multiple_definitions or []
    if added_imports:
      added_classset = self._PrescanImportFiles(added_imports)
      self._PrescanFiles(added_classset)

  def _GetClassFullName(self, filepath):
    """Get the full class name of a file with package name."""
    if not os.path.isfile(filepath):
      return None
    with codecs.open(filepath, encoding='utf-8') as f:
      short_class_name, _ = os.path.splitext(os.path.basename(filepath))
      for line in f:
        for package in re.findall('^package\s+([\w\.]+);', line):
          return package + '.' + short_class_name

  def _IgnoreDir(self, d):
    # Skip hidden directories.
    if d.startswith('.'):
      return True
    # Skip the "out" directory, as dealing with generated files is awkward.
    # We don't want paths like "out/Release/lib.java" in our DEPS files.
    # TODO(husky): We need some way of determining the "real" path to
    # a generated file -- i.e., where it would be in source control if
    # it weren't generated.
    if d.startswith('out') or d in ('xcodebuild',):
      return True
    # Skip third-party directories.
    if d in ('third_party', 'ThirdParty'):
      return True
    return False

  def _PrescanFiles(self, added_classset):
    for root, dirs, files in os.walk(self._base_directory.encode('utf-8')):
      # Skip unwanted subdirectories. TODO(husky): it would be better to do
      # this via the skip_child_includes flag in DEPS files. Maybe hoist this
      # prescan logic into checkdeps.py itself?
      dirs[:] = [d for d in dirs if not self._IgnoreDir(d)]
      for f in files:
        if f.endswith('.java'):
          self._PrescanFile(os.path.join(root, f), added_classset)

  def _PrescanImportFiles(self, added_imports):
    """Build a set of fully-qualified class affected by this patch.

    Prescan imported files and build classset to collect full class names
    with package name. This includes both changed files as well as changed imports.

    Args:
      added_imports : ((file_path, (import_line, import_line, ...), ...)

    Return:
      A set of full class names with package name of imported files.
    """
    classset = set()
    for filepath, changed_lines in (added_imports or []):
      if not self.ShouldCheck(filepath):
        continue
      full_class_name = self._GetClassFullName(filepath)
      if full_class_name:
        classset.add(full_class_name)
      for line in changed_lines:
        found_item = self._EXTRACT_IMPORT_PATH.match(line)
        if found_item:
          classset.add(found_item.group(1))
    return classset

  def _PrescanFile(self, filepath, added_classset):
    if self._verbose:
      print 'Prescanning: ' + filepath
    full_class_name = self._GetClassFullName(filepath)
    if full_class_name:
      if full_class_name in self._classmap:
        if self._verbose or full_class_name in added_classset:
          if not any((re.match(i, filepath) for i in self._allow_multiple_definitions)):
            print 'WARNING: multiple definitions of %s:' % full_class_name
            print '    ' + filepath
            print '    ' + self._classmap[full_class_name]
            print
      else:
        self._classmap[full_class_name] = filepath
    elif self._verbose:
      print 'WARNING: no package definition found in %s' % filepath

  def CheckLine(self, rules, line, filepath, 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
    clazz = found_item.group(1)
    if clazz not in self._classmap:
      # Importing a class from outside the Chromium tree. That's fine --
      # it's probably a Java or Android system class.
      return True, None
    import_path = os.path.relpath(
        self._classmap[clazz], self._base_directory)
    # Convert Windows paths to Unix style, as used in DEPS files.
    import_path = import_path.replace(os.path.sep, '/')
    rule = rules.RuleApplyingTo(import_path, filepath)
    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)
    with codecs.open(filepath, encoding='utf-8') as f:
      for line in f:
        is_import, violation = self.CheckLine(rules, line, filepath)
        if violation:
          dependee_status.AddViolation(violation)
        if '{' in line:
          # This is code, so we're finished reading imports for this file.
          break

    return dependee_status

  @staticmethod
  def IsJavaFile(filepath):
    """Returns True if the given path ends in the extensions
    handled by this checker.
    """
    return os.path.splitext(filepath)[1] in JavaChecker.EXTENSIONS

  def ShouldCheck(self, file_path):
    """Check if the new import 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.IsJavaFile(file_path)
