#!/usr/bin/env python
#
# This is a tool that works like debug location coverage calculator.
# It parses the llvm-dwarfdump --statistics output by reporting it
# in a more human readable way.
#

from __future__ import print_function
import argparse
import os
import sys
from json import loads
from math import ceil
from subprocess import Popen, PIPE

def coverage_buckets():
  yield '0%'
  yield '1-9%'
  for start in range(10, 91, 10):
    yield '{0}-{1}%'.format(start, start + 9)
  yield '100%'

def locstats_output(
  variables_total,
  variables_total_locstats,
  variables_with_loc,
  scope_bytes_covered,
  scope_bytes_from_first_def,
  variables_coverage_map
  ):

  pc_ranges_covered = int(ceil(scope_bytes_covered * 100.0)
              / scope_bytes_from_first_def)
  variables_coverage_per_map = {}
  for cov_bucket in coverage_buckets():
    variables_coverage_per_map[cov_bucket] = \
      int(ceil(variables_coverage_map[cov_bucket] * 100.0) \
               / variables_total_locstats)

  print (' =================================================')
  print ('            Debug Location Statistics       ')
  print (' =================================================')
  print ('     cov%          samples          percentage(~)  ')
  print (' -------------------------------------------------')
  for cov_bucket in coverage_buckets():
    print ('   {0:6}        {1:8d}             {2:3d}%'. \
      format(cov_bucket, variables_coverage_map[cov_bucket], \
             variables_coverage_per_map[cov_bucket]))
  print (' =================================================')
  print (' -the number of debug variables processed: ' \
    + str(variables_total_locstats))
  print (' -PC ranges covered: ' + str(pc_ranges_covered) + '%')

  # Only if we are processing all the variables output the total
  # availability.
  if variables_total and variables_with_loc:
    total_availability = int(ceil(variables_with_loc * 100.0) \
                                  / variables_total)
    print (' -------------------------------------------------')
    print (' -total availability: ' + str(total_availability) + '%')
  print (' =================================================')

def parse_program_args(parser):
  parser.add_argument('-only-variables', action='store_true',
            default=False,
            help='calculate the location statistics only for '
               'local variables'
            )
  parser.add_argument('-only-formal-parameters', action='store_true',
            default=False,
            help='calculate the location statistics only for '
               'formal parameters'
            )
  parser.add_argument('-ignore-debug-entry-values', action='store_true',
            default=False,
            help='ignore the location statistics on locations with '
               'entry values'
            )
  parser.add_argument('file_name', type=str, help='file to process')
  return parser.parse_args()


def Main():
  parser = argparse.ArgumentParser()
  results = parse_program_args(parser)

  if len(sys.argv) < 2:
    print ('error: Too few arguments.')
    parser.print_help()
    sys.exit(1)

  if results.only_variables and results.only_formal_parameters:
    print ('error: Please use just one only* option.')
    parser.print_help()
    sys.exit(1)

  # These will be different due to different options enabled.
  variables_total = None
  variables_total_locstats = None
  variables_with_loc = None
  variables_scope_bytes_covered = None
  variables_scope_bytes_from_first_def = None
  variables_scope_bytes_entry_values = None
  variables_coverage_map = {}
  binary = results.file_name

  # Get the directory of the LLVM tools.
  llvm_dwarfdump_cmd = os.path.join(os.path.dirname(__file__), \
                                    "llvm-dwarfdump")
  # The statistics llvm-dwarfdump option.
  llvm_dwarfdump_stats_opt = "--statistics"

  subproc = Popen([llvm_dwarfdump_cmd, llvm_dwarfdump_stats_opt, binary], \
                  stdin=PIPE, stdout=PIPE, stderr=PIPE, \
                  universal_newlines = True)
  cmd_stdout, cmd_stderr = subproc.communicate()

  # Get the JSON and parse it.
  json_parsed = None

  try:
    json_parsed = loads(cmd_stdout)
  except:
    print ('error: No valid llvm-dwarfdump statistics found.')
    sys.exit(1)

  if results.only_variables:
    # Read the JSON only for local variables.
    variables_total_locstats = \
      json_parsed['total vars procesed by location statistics']
    variables_scope_bytes_covered = \
      json_parsed['vars scope bytes covered']
    variables_scope_bytes_from_first_def = \
      json_parsed['vars scope bytes total']
    if not results.ignore_debug_entry_values:
      for cov_bucket in coverage_buckets():
        cov_category = "vars with {} of its scope covered".format(cov_bucket)
        variables_coverage_map[cov_bucket] = json_parsed[cov_category]
    else:
      variables_scope_bytes_entry_values = \
        json_parsed['vars entry value scope bytes covered']
      variables_scope_bytes_covered = variables_scope_bytes_covered \
         - variables_scope_bytes_entry_values
      for cov_bucket in coverage_buckets():
        cov_category = \
          "vars (excluding the debug entry values) " \
          "with {} of its scope covered".format(cov_bucket)
        variables_coverage_map[cov_bucket] = json_parsed[cov_category]
  elif results.only_formal_parameters:
    # Read the JSON only for formal parameters.
    variables_total_locstats = \
      json_parsed['total params procesed by location statistics']
    variables_scope_bytes_covered = \
      json_parsed['formal params scope bytes covered']
    variables_scope_bytes_from_first_def = \
      json_parsed['formal params scope bytes total']
    if not results.ignore_debug_entry_values:
      for cov_bucket in coverage_buckets():
        cov_category = "params with {} of its scope covered".format(cov_bucket)
        variables_coverage_map[cov_bucket] = json_parsed[cov_category]
    else:
      variables_scope_bytes_entry_values = \
        json_parsed['formal params entry value scope bytes covered']
      variables_scope_bytes_covered = variables_scope_bytes_covered \
        - variables_scope_bytes_entry_values
      for cov_bucket in coverage_buckets():
        cov_category = \
          "params (excluding the debug entry values) " \
          "with {} of its scope covered".format(cov_bucket)
        variables_coverage_map[cov_bucket] = json_parsed[cov_category]
  else:
    # Read the JSON for both local variables and formal parameters.
    variables_total = \
      json_parsed['source variables']
    variables_with_loc = json_parsed['variables with location']
    variables_total_locstats = \
      json_parsed['total variables procesed by location statistics']
    variables_scope_bytes_covered = \
      json_parsed['scope bytes covered']
    variables_scope_bytes_from_first_def = \
      json_parsed['scope bytes total']
    if not results.ignore_debug_entry_values:
      for cov_bucket in coverage_buckets():
        cov_category = "variables with {} of its scope covered". \
                       format(cov_bucket)
        variables_coverage_map[cov_bucket] = json_parsed[cov_category]
    else:
      variables_scope_bytes_entry_values = \
        json_parsed['entry value scope bytes covered']
      variables_scope_bytes_covered = variables_scope_bytes_covered \
        - variables_scope_bytes_entry_values
      for cov_bucket in coverage_buckets():
        cov_category = "variables (excluding the debug entry values) " \
                       "with {} of its scope covered". format(cov_bucket)
        variables_coverage_map[cov_bucket] = json_parsed[cov_category]

  # Pretty print collected info.
  locstats_output(
    variables_total,
    variables_total_locstats,
    variables_with_loc,
    variables_scope_bytes_covered,
    variables_scope_bytes_from_first_def,
    variables_coverage_map
    )

if __name__ == '__main__':
  Main()
  sys.exit(0)
