# 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.

import optparse
import os
import re
import shlex
import subprocess
import sys

from pylib import cmd_helper
from pylib import constants


def _PrintMessage(warnings, title, action, known_bugs_file):
  if warnings:
    print
    print '*' * 80
    print '%s warnings.' % title
    print '%s %s' % (action, known_bugs_file)
    print '-' * 80
    for warning in warnings:
      print warning
    print '-' * 80
    print


def _StripLineNumbers(current_warnings):
  re_line = r':\[line.*?\]$'
  return [re.sub(re_line, '', x) for x in current_warnings]


def _DiffKnownWarnings(current_warnings_set, known_bugs_file):
  with open(known_bugs_file, 'r') as known_bugs:
    known_bugs_set = set(known_bugs.read().splitlines())

  new_warnings = current_warnings_set - known_bugs_set
  _PrintMessage(sorted(new_warnings), 'New', 'Please fix, or perhaps add to',
                known_bugs_file)

  obsolete_warnings = known_bugs_set - current_warnings_set
  _PrintMessage(sorted(obsolete_warnings), 'Obsolete', 'Please remove from',
                known_bugs_file)

  count = len(new_warnings) + len(obsolete_warnings)
  if count:
    print '*** %d FindBugs warning%s! ***' % (count, 's' * (count > 1))
    if len(new_warnings):
      print '*** %d: new ***' % len(new_warnings)
    if len(obsolete_warnings):
      print '*** %d: obsolete ***' % len(obsolete_warnings)
    print
    print 'Alternatively,  rebaseline with --rebaseline command option'
    print
  else:
    print 'No new FindBugs warnings.'
  print
  return count


def _Rebaseline(current_warnings_set, known_bugs_file):
  with file(known_bugs_file, 'w') as known_bugs:
    for warning in sorted(current_warnings_set):
      print >> known_bugs, warning
  return 0


def _GetChromeJars(release_version):
  version = 'Debug'
  if release_version:
    version = 'Release'
  path = os.path.join(constants.DIR_SOURCE_ROOT,
                      os.environ.get('CHROMIUM_OUT_DIR', 'out'),
                      version,
                      'lib.java')
  cmd = 'find %s -name "*.jar"' % path
  out = cmd_helper.GetCmdOutput(shlex.split(cmd))
  out = [p for p in out.splitlines() if not p.endswith('.dex.jar')]
  if not out:
    print 'No classes found in %s' % path
  return ' '.join(out)


def _Run(exclude, known_bugs, classes_to_analyze, auxiliary_classes,
        rebaseline, release_version, findbug_args):
  """Run the FindBugs.

  Args:
    exclude: the exclude xml file, refer to FindBugs's -exclude command option.
    known_bugs: the text file of known bugs. The bugs in it will not be
                reported.
    classes_to_analyze: the list of classes need to analyze, refer to FindBug's
                        -onlyAnalyze command line option.
    auxiliary_classes: the classes help to analyze, refer to FindBug's
                       -auxclasspath command line option.
    rebaseline: True if the known_bugs file needs rebaseline.
    release_version: True if the release version needs check, otherwise check
                     debug version.
    findbug_args: addtional command line options needs pass to Findbugs.
  """

  chrome_src = constants.DIR_SOURCE_ROOT
  sdk_root = constants.ANDROID_SDK_ROOT
  sdk_version = constants.ANDROID_SDK_VERSION

  system_classes = []
  system_classes.append(os.path.join(sdk_root, 'platforms',
                                     'android-%s' % sdk_version, 'android.jar'))
  if auxiliary_classes:
    for classes in auxiliary_classes:
      system_classes.append(os.path.abspath(classes))

  findbugs_javacmd = 'java'
  findbugs_home = os.path.join(chrome_src, 'third_party', 'findbugs')
  findbugs_jar = os.path.join(findbugs_home, 'lib', 'findbugs.jar')
  findbugs_pathsep = ':'
  findbugs_maxheap = '768'

  cmd = '%s ' % findbugs_javacmd
  cmd = '%s -classpath %s%s' % (cmd, findbugs_jar, findbugs_pathsep)
  cmd = '%s -Xmx%sm ' % (cmd, findbugs_maxheap)
  cmd = '%s -Dfindbugs.home="%s" ' % (cmd, findbugs_home)
  cmd = '%s -jar %s ' % (cmd, findbugs_jar)

  cmd = '%s -textui -sortByClass ' % cmd
  cmd = '%s -pluginList %s' % (cmd, os.path.join(chrome_src, 'tools', 'android',
                                                 'findbugs_plugin', 'lib',
                                                 'chromiumPlugin.jar'))
  if len(system_classes):
    cmd = '%s -auxclasspath %s ' % (cmd, ':'.join(system_classes))

  if classes_to_analyze:
    cmd = '%s -onlyAnalyze %s ' % (cmd, classes_to_analyze)

  if exclude:
    cmd = '%s -exclude %s ' % (cmd, os.path.abspath(exclude))

  if findbug_args:
    cmd = '%s %s ' % (cmd, findbug_args)

  chrome_classes = _GetChromeJars(release_version)
  if not chrome_classes:
    return 1
  cmd = '%s %s ' % (cmd, chrome_classes)

  print
  print '*' * 80
  print 'Command used to run findbugs:'
  print cmd
  print '*' * 80
  print

  proc = subprocess.Popen(shlex.split(cmd),
                          stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  out, _err = proc.communicate()
  current_warnings_set = set(_StripLineNumbers(filter(None, out.splitlines())))

  if rebaseline:
    return _Rebaseline(current_warnings_set, known_bugs)
  else:
    return _DiffKnownWarnings(current_warnings_set, known_bugs)

def Run(options):
  exclude_file = None
  known_bugs_file = None

  if options.exclude:
    exclude_file = options.exclude
  elif options.base_dir:
    exclude_file = os.path.join(options.base_dir, 'findbugs_exclude.xml')

  if options.known_bugs:
    known_bugs_file = options.known_bugs
  elif options.base_dir:
    known_bugs_file = os.path.join(options.base_dir, 'findbugs_known_bugs.txt')

  auxclasspath = None
  if options.auxclasspath:
    auxclasspath = options.auxclasspath.split(':')
  return _Run(exclude_file, known_bugs_file, options.only_analyze, auxclasspath,
              options.rebaseline, options.release_build, options.findbug_args)


def GetCommonParser():
  parser = optparse.OptionParser()
  parser.add_option('-r',
                    '--rebaseline',
                    action='store_true',
                    dest='rebaseline',
                    help='Rebaseline known findbugs issues.')

  parser.add_option('-a',
                    '--auxclasspath',
                    action='store',
                    default=None,
                    dest='auxclasspath',
                    help='Set aux classpath for analysis.')

  parser.add_option('-o',
                    '--only-analyze',
                    action='store',
                    default=None,
                    dest='only_analyze',
                    help='Only analyze the given classes and packages.')

  parser.add_option('-e',
                    '--exclude',
                    action='store',
                    default=None,
                    dest='exclude',
                    help='Exclude bugs matching given filter.')

  parser.add_option('-k',
                    '--known-bugs',
                    action='store',
                    default=None,
                    dest='known_bugs',
                    help='Not report the bugs in the given file.')

  parser.add_option('-l',
                    '--release-build',
                    action='store_true',
                    dest='release_build',
                    help='Analyze release build instead of debug.')

  parser.add_option('-f',
                    '--findbug-args',
                    action='store',
                    default=None,
                    dest='findbug_args',
                    help='Additional findbug arguments.')

  parser.add_option('-b',
                    '--base-dir',
                    action='store',
                    default=None,
                    dest='base_dir',
                    help='Base directory for configuration file.')

  return parser


def main():
  parser = GetCommonParser()
  options, _ = parser.parse_args()

  return Run(options)


if __name__ == '__main__':
  sys.exit(main())
