# 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):
      # 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)
