#!/usr/bin/python

#
# Copyright 2015, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

"""Script that is used by developers to run style checks on Java files."""

import argparse
import errno
import os
import shutil
import subprocess
import sys
import tempfile
import xml.dom.minidom
import gitlint.git as git


def _FindFoldersContaining(root, wanted):
  """Recursively finds directories that have a file with the given name.

  Args:
    root: Root folder to start the search from.
    wanted: The filename that we are looking for.

  Returns:
    List of folders that has a file with the given name
  """

  if not root:
    return []
  if os.path.islink(root):
    return []
  result = []
  for file_name in os.listdir(root):
    file_path = os.path.join(root, file_name)
    if os.path.isdir(file_path):
      sub_result = _FindFoldersContaining(file_path, wanted)
      result.extend(sub_result)
    else:
      if file_name == wanted:
        result.append(root)
  return result

MAIN_DIRECTORY = os.path.normpath(os.path.dirname(__file__))
CHECKSTYLE_JAR = os.path.join(MAIN_DIRECTORY, 'checkstyle.jar')
CHECKSTYLE_STYLE = os.path.join(MAIN_DIRECTORY, 'android-style.xml')
FORCED_RULES = ['com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck',
                'com.puppycrawl.tools.checkstyle.checks.imports.UnusedImportsCheck']
SKIPPED_RULES_FOR_TEST_FILES = ['com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck',
                                'com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck']
SUBPATH_FOR_TEST_FILES = ['/tests/', '/test/', '/androidTest/']
SUBPATH_FOR_TEST_DATA_FILES = _FindFoldersContaining(git.repository_root(),
                                                     'IGNORE_CHECKSTYLE')
ERROR_UNCOMMITTED = 'You need to commit all modified files before running Checkstyle\n'
ERROR_UNTRACKED = 'You have untracked java files that are not being checked:\n'


def RunCheckstyleOnFiles(java_files, classpath=CHECKSTYLE_JAR, config_xml=CHECKSTYLE_STYLE):
  """Runs Checkstyle checks on a given set of java_files.

  Args:
    java_files: A list of files to check.
    classpath: The colon-delimited list of JARs in the classpath.
    config_xml: Path of the checkstyle XML configuration file.

  Returns:
    A tuple of errors and warnings.
  """
  print 'Running Checkstyle on inputted files'
  java_files = map(os.path.abspath, java_files)
  stdout = _ExecuteCheckstyle(java_files, classpath, config_xml)
  (errors, warnings) = _ParseAndFilterOutput(stdout)
  _PrintErrorsAndWarnings(errors, warnings)
  return errors, warnings


def RunCheckstyleOnACommit(commit,
                           classpath=CHECKSTYLE_JAR,
                           config_xml=CHECKSTYLE_STYLE,
                           file_whitelist=None):
  """Runs Checkstyle checks on a given commit.

  It will run Checkstyle on the changed Java files in a specified commit SHA-1
  and if that is None it will fallback to check the latest commit of the
  currently checked out branch.

  Args:
    commit: A full 40 character SHA-1 of a commit to check.
    classpath: The colon-delimited list of JARs in the classpath.
    config_xml: Path of the checkstyle XML configuration file.
    file_whitelist: A list of whitelisted file paths that should be checked.

  Returns:
    A tuple of errors and warnings.
  """
  if not git.repository_root():
    print 'FAILURE: not inside a git repository'
    sys.exit(1)
  explicit_commit = commit is not None
  if not explicit_commit:
    _WarnIfUntrackedFiles()
    commit = git.last_commit()
  print 'Running Checkstyle on %s commit' % commit
  commit_modified_files = _GetModifiedFiles(commit, explicit_commit)
  commit_modified_files = _FilterFiles(commit_modified_files, file_whitelist)
  if not commit_modified_files.keys():
    print 'No Java files to check'
    return [], []

  (tmp_dir, tmp_file_map) = _GetTempFilesForCommit(
      commit_modified_files.keys(), commit)

  java_files = tmp_file_map.keys()
  stdout = _ExecuteCheckstyle(java_files, classpath, config_xml)

  # Remove all the temporary files.
  shutil.rmtree(tmp_dir)

  (errors, warnings) = _ParseAndFilterOutput(stdout,
                                             commit,
                                             commit_modified_files,
                                             tmp_file_map)
  _PrintErrorsAndWarnings(errors, warnings)
  return errors, warnings


def _WarnIfUntrackedFiles(out=sys.stdout):
  """Prints a warning and a list of untracked files if needed."""
  root = git.repository_root()
  untracked_files = git.modified_files(root, False)
  untracked_files = {f for f in untracked_files if f.endswith('.java')}
  if untracked_files:
    out.write(ERROR_UNTRACKED)
    for untracked_file in untracked_files:
      out.write(untracked_file + '\n')
    out.write('\n')


def _PrintErrorsAndWarnings(errors, warnings):
  """Prints given errors and warnings."""
  if errors:
    print 'ERRORS:'
    print '\n'.join(errors)
  if warnings:
    print 'WARNINGS:'
    print '\n'.join(warnings)


def _ExecuteCheckstyle(java_files, classpath, config_xml):
  """Runs Checkstyle to check give Java files for style errors.

  Args:
    java_files: A list of Java files that needs to be checked.
    classpath: The colon-delimited list of JARs in the classpath.
    config_xml: Path of the checkstyle XML configuration file.

  Returns:
    Checkstyle output in XML format.
  """
  # Run checkstyle
  checkstyle_env = os.environ.copy()
  checkstyle_env['JAVA_CMD'] = 'java'
  try:
    check = subprocess.Popen(['java', '-cp', classpath,
                              'com.puppycrawl.tools.checkstyle.Main', '-c',
                              config_xml, '-f', 'xml'] + java_files,
                             stdout=subprocess.PIPE, env=checkstyle_env)
    stdout, _ = check.communicate()
  except OSError as e:
    if e.errno == errno.ENOENT:
      print 'Error running Checkstyle!'
      sys.exit(1)

  # A work-around for Checkstyle printing error count to stdio.
  if 'Checkstyle ends with' in stdout.splitlines()[-1]:
    stdout = '\n'.join(stdout.splitlines()[:-1])
  return stdout


def _ParseAndFilterOutput(stdout,
                          sha=None,
                          commit_modified_files=None,
                          tmp_file_map=None):
  result_errors = []
  result_warnings = []
  root = xml.dom.minidom.parseString(stdout)
  for file_element in root.getElementsByTagName('file'):
    file_name = file_element.attributes['name'].value
    if tmp_file_map:
      file_name = tmp_file_map[file_name]
    modified_lines = None
    if commit_modified_files:
      modified_lines = git.modified_lines(file_name,
                                          commit_modified_files[file_name],
                                          sha)
    test_class = any(substring in file_name for substring
                     in SUBPATH_FOR_TEST_FILES)
    test_data_class = any(substring in file_name for substring
                          in SUBPATH_FOR_TEST_DATA_FILES)
    file_name = os.path.relpath(file_name)
    errors = file_element.getElementsByTagName('error')
    for error in errors:
      line = int(error.attributes['line'].value)
      rule = error.attributes['source'].value
      if _ShouldSkip(commit_modified_files, modified_lines, line, rule,
                     test_class, test_data_class):
        continue

      column = ''
      if error.hasAttribute('column'):
        column = '%s:' % error.attributes['column'].value
      message = error.attributes['message'].value
      project = ''
      if os.environ.get('REPO_PROJECT'):
        project = '[' + os.environ.get('REPO_PROJECT') + '] '

      result = '  %s%s:%s:%s %s' % (project, file_name, line, column, message)

      severity = error.attributes['severity'].value
      if severity == 'error':
        result_errors.append(result)
      elif severity == 'warning':
        result_warnings.append(result)
  return result_errors, result_warnings


def _ShouldSkip(commit_check, modified_lines, line, rule, test_class=False,
                test_data_class=False):
  """Returns whether an error on a given line should be skipped.

  Args:
    commit_check: Whether Checkstyle is being run on a specific commit.
    modified_lines: A list of lines that has been modified.
    line: The line that has a rule violation.
    rule: The type of rule that a given line is violating.
    test_class: Whether the file being checked is a test class.
    test_data_class: Whether the file being check is a class used as test data.

  Returns:
    A boolean whether a given line should be skipped in the reporting.
  """
  # None modified_lines means checked file is new and nothing should be skipped.
  if test_data_class:
    return True
  if test_class and rule in SKIPPED_RULES_FOR_TEST_FILES:
    return True
  if not commit_check:
    return False
  if modified_lines is None:
    return False
  return line not in modified_lines and rule not in FORCED_RULES


def _GetModifiedFiles(commit, explicit_commit=False, out=sys.stdout):
  root = git.repository_root()
  pending_files = git.modified_files(root, True)
  if pending_files and not explicit_commit:
    out.write(ERROR_UNCOMMITTED)
    sys.exit(1)

  modified_files = git.modified_files(root, True, commit)
  modified_files = {f: modified_files[f] for f
                    in modified_files if f.endswith('.java')}
  return modified_files


def _FilterFiles(files, file_whitelist):
  if not file_whitelist:
    return files
  return {f: files[f] for f in files
          for whitelist in file_whitelist if whitelist in f}


def _GetTempFilesForCommit(file_names, commit):
  """Creates a temporary snapshot of the files in at a commit.

  Retrieves the state of every file in file_names at a given commit and writes
  them all out to a temporary directory.

  Args:
    file_names: A list of files that need to be retrieved.
    commit: A full 40 character SHA-1 of a commit.

  Returns:
    A tuple of temprorary directory name and a directionary of
    temp_file_name: filename. For example:

    ('/tmp/random/', {'/tmp/random/blarg.java': 'real/path/to/file.java' }
  """
  tmp_dir_name = tempfile.mkdtemp()
  tmp_file_names = {}
  for file_name in file_names:
    rel_path = os.path.relpath(file_name)
    content = subprocess.check_output(
        ['git', 'show', commit + ':' + rel_path])

    tmp_file_name = os.path.join(tmp_dir_name, rel_path)
    # create directory for the file if it doesn't exist
    if not os.path.exists(os.path.dirname(tmp_file_name)):
      os.makedirs(os.path.dirname(tmp_file_name))

    tmp_file = open(tmp_file_name, 'w')
    tmp_file.write(content)
    tmp_file.close()
    tmp_file_names[tmp_file_name] = file_name
  return tmp_dir_name, tmp_file_names


def main(args=None):
  """Runs Checkstyle checks on a given set of java files or a commit.

  It will run Checkstyle on the list of java files first, if unspecified,
  then the check will be run on a specified commit SHA-1 and if that
  is None it will fallback to check the latest commit of the currently checked
  out branch.
  """
  parser = argparse.ArgumentParser()
  parser.add_argument('--file', '-f', nargs='+')
  parser.add_argument('--sha', '-s')
  parser.add_argument('--config_xml', '-c')
  parser.add_argument('--file_whitelist', '-fw', nargs='+')
  parser.add_argument('--add_classpath', '-p')
  args = parser.parse_args()

  config_xml = args.config_xml or CHECKSTYLE_STYLE

  if not os.path.exists(config_xml):
    print 'Java checkstyle configuration file is missing'
    sys.exit(1)

  classpath = CHECKSTYLE_JAR

  if args.add_classpath:
    classpath = args.add_classpath + ':' + classpath

  if args.file:
    # Files to check were specified via command line.
    (errors, warnings) = RunCheckstyleOnFiles(args.file, classpath, config_xml)
  else:
    (errors, warnings) = RunCheckstyleOnACommit(args.sha, classpath, config_xml,
                                                args.file_whitelist)

  if errors or warnings:
    sys.exit(1)

  print 'SUCCESS! NO ISSUES FOUND'
  sys.exit(0)


if __name__ == '__main__':
  main()
