#!/usr/bin/env python

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

"""Aggregates Jacoco coverage files to produce output."""

from __future__ import print_function

import argparse
import fnmatch
import json
import os
import sys

import devil_chromium
from devil.utils import cmd_helper
from pylib.constants import host_paths

# Source paths should be passed to Jacoco in a way that the relative file paths
# reflect the class package name.
_PARTIAL_PACKAGE_NAMES = ['com/google', 'org/chromium']

# The sources_json_file is generated by jacoco_instr.py with source directories
# and input path to non-instrumented jars.
# e.g.
# 'source_dirs': [
#   "chrome/android/java/src/org/chromium/chrome/browser/toolbar/bottom",
#   "chrome/android/java/src/org/chromium/chrome/browser/ui/system",
# ...]
# 'input_path':
#   '$CHROMIUM_OUTPUT_DIR/\
#    obj/chrome/android/features/tab_ui/java__process_prebuilt-filtered.jar'
_SOURCES_JSON_FILES_SUFFIX = '__jacoco_sources.json'


def _GetFilesWithSuffix(root_dir, suffix):
  """Gets all files with a given suffix.

  Args:
    root_dir: Directory in which to search for files.
    suffix: Suffix to look for.

  Returns:
    A list of absolute paths to files that match.
  """
  files = []
  for root, _, filenames in os.walk(root_dir):
    basenames = fnmatch.filter(filenames, '*' + suffix)
    files.extend([os.path.join(root, basename) for basename in basenames])

  return files


def _ParseArguments(parser):
  """Parses the command line arguments.

  Args:
    parser: ArgumentParser object.

  Returns:
    The parsed arguments.
  """
  parser.add_argument(
      '--format',
      required=True,
      choices=['html', 'xml', 'csv'],
      help='Output report format. Choose one from html, xml and csv.')
  parser.add_argument('--output-dir', help='html report output directory.')
  parser.add_argument('--output-file', help='xml or csv report output file.')
  parser.add_argument(
      '--coverage-dir',
      required=True,
      help='Root of the directory in which to search for '
      'coverage data (.exec) files.')
  parser.add_argument(
      '--sources-json-dir',
      help='Root of the directory in which to search for '
      '*__jacoco_sources.json files.')
  parser.add_argument(
      '--class-files',
      nargs='+',
      help='Location of Java non-instrumented class files. '
      'Use non-instrumented jars instead of instrumented jars. '
      'e.g. use chrome_java__process_prebuilt-filtered.jar instead of'
      'chrome_java__process_prebuilt-instrumented.jar')
  parser.add_argument(
      '--sources',
      nargs='+',
      help='Location of the source files. '
      'Specified source folders must be the direct parent of the folders '
      'that define the Java packages.'
      'e.g. <src_dir>/chrome/android/java/src/')
  parser.add_argument(
      '--cleanup',
      action='store_true',
      help='If set, removes coverage files generated at '
      'runtime.')
  args = parser.parse_args()

  if args.format == 'html':
    if not args.output_dir:
      parser.error('--output-dir needed for html report.')
  elif not args.output_file:
    parser.error('--output-file needed for xml or csv report.')

  if not (args.sources_json_dir or args.class_files):
    parser.error('At least either --sources-json-dir or --class-files needed.')

  return args


def main():
  parser = argparse.ArgumentParser()
  args = _ParseArguments(parser)

  devil_chromium.Initialize()

  coverage_files = _GetFilesWithSuffix(args.coverage_dir, '.exec')
  if not coverage_files:
    parser.error('No coverage file found under %s' % args.coverage_dir)
  print('Found coverage files: %s' % str(coverage_files))

  class_files = []
  source_dirs = []
  if args.sources_json_dir:
    sources_json_files = _GetFilesWithSuffix(args.sources_json_dir,
                                             _SOURCES_JSON_FILES_SUFFIX)
    for f in sources_json_files:
      with open(f, 'r') as json_file:
        data = json.load(json_file)
        class_files.append(data['input_path'])
        source_dirs.extend(data['source_dirs'])

  # Fix source directories as direct parent of Java packages.
  fixed_source_dirs = set()
  for path in source_dirs:
    for partial in _PARTIAL_PACKAGE_NAMES:
      if partial in path:
        fixed_dir = os.path.join(host_paths.DIR_SOURCE_ROOT,
                                 path[:path.index(partial)])
        fixed_source_dirs.add(fixed_dir)
        break

  if args.class_files:
    class_files += args.class_files
  if args.sources:
    fixed_source_dirs.update(args.sources)

  cmd = [
      'java', '-jar',
      os.path.join(host_paths.DIR_SOURCE_ROOT, 'third_party', 'jacoco', 'lib',
                   'jacococli.jar'), 'report'
  ] + coverage_files

  for f in class_files:
    cmd += ['--classfiles', f]
  for source in fixed_source_dirs:
    cmd += ['--sourcefiles', source]

  if args.format == 'html':
    out_cmd = ['--html', args.output_dir]
  elif args.format == 'xml':
    out_cmd = ['--xml', args.output_file]
  else:
    out_cmd = ['--csv', args.output_file]

  cmd += out_cmd

  exit_code = cmd_helper.RunCmd(cmd)

  if args.cleanup:
    for f in coverage_files:
      os.remove(f)

  # Command tends to exit with status 0 when it actually failed.
  if not exit_code:
    if args.format == 'html':
      if not os.path.isdir(args.output_dir) or not os.listdir(args.output_dir):
        print('No report generated at %s' % args.output_dir)
        exit_code = 1
    elif not os.path.isfile(args.output_file):
      print('No report generated at %s' % args.output_file)
      exit_code = 1

  return exit_code


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