#!/usr/bin/env python
# Copyright (c) 2018, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

'''
Build r8lib.jar with both R8 and ProGuard and print a size comparison.

By default, inlining is disabled in both R8 and ProGuard to make
method-by-method comparison much easier. Pass --inlining to enable inlining.

By default, only shows methods where R8's DEX output is 5 or more instructions
larger than ProGuard+D8's output. Pass --threshold 0 to display all methods.
'''

import argparse
import build_r8lib
import os
import subprocess
import toolhelper
import utils


parser = argparse.ArgumentParser(description=__doc__.strip(),
                                 formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-t', '--tmpdir',
                    help='Store auxiliary files in given directory')
parser.add_argument('-i', '--inlining', action='store_true',
                    help='Enable inlining')
parser.add_argument('--threshold')

R8_RELOCATIONS = [
  ('com.google.common', 'com.android.tools.r8.com.google.common'),
  ('com.google.gson', 'com.android.tools.r8.com.google.gson'),
  ('com.google.thirdparty', 'com.android.tools.r8.com.google.thirdparty'),
  ('joptsimple', 'com.android.tools.r8.joptsimple'),
  ('org.apache.commons', 'com.android.tools.r8.org.apache.commons'),
  ('org.objectweb.asm', 'com.android.tools.r8.org.objectweb.asm'),
  ('it.unimi.dsi.fastutil', 'com.android.tools.r8.it.unimi.dsi.fastutil'),
]


def is_output_newer(input, output):
  if not os.path.exists(output):
    return False
  return os.stat(input).st_mtime < os.stat(output).st_mtime


def check_call(args, **kwargs):
  utils.PrintCmd(args)
  return subprocess.check_call(args, **kwargs)


def main(tmpdir=None, inlining=True,
         run_jarsizecompare=True, threshold=None):
  if tmpdir is None:
    with utils.TempDir() as tmpdir:
      return main(tmpdir, inlining)

  inline_suffix = '-inline' if inlining else '-noinline'

  pg_config = utils.R8LIB_KEEP_RULES
  r8lib_jar = os.path.join(utils.LIBS, 'r8lib%s.jar' % inline_suffix)
  r8lib_map = os.path.join(utils.LIBS, 'r8lib%s-map.txt' % inline_suffix)
  r8lib_args = None
  if not inlining:
    r8lib_args = ['-Dcom.android.tools.r8.disableinlining=1']
    pg_config = os.path.join(tmpdir, 'keep-noinline.txt')
    with open(pg_config, 'w') as new_config:
      with open(utils.R8LIB_KEEP_RULES) as old_config:
        new_config.write(old_config.read().rstrip('\n') +
                         '\n-optimizations !method/inlining/*\n')

  if not is_output_newer(utils.R8_JAR, r8lib_jar):
    r8lib_memory = os.path.join(tmpdir, 'r8lib%s-memory.txt' % inline_suffix)
    # TODO(b/160420801): The signature of build_r8lib has changed.
    build_r8lib.build_r8lib(
        output_path=r8lib_jar,
        output_map=r8lib_map,
        extra_args=r8lib_args,
        track_memory_file=r8lib_memory)

  pg_output = os.path.join(tmpdir, 'r8lib-pg%s.jar' % inline_suffix)
  pg_memory = os.path.join(tmpdir, 'r8lib-pg%s-memory.txt' % inline_suffix)
  pg_map = os.path.join(tmpdir, 'r8lib-pg%s-map.txt' % inline_suffix)
  # TODO(b/160420801): This must use proguard.* utils once working again.
  pg_args = ['tools/track_memory.sh', pg_memory,
             'third_party/proguard/proguard6.0.2/bin/proguard.sh',
             '@' + pg_config,
             '-lib', utils.RT_JAR,
             '-injar', utils.R8_JAR,
             '-printmapping', pg_map,
             '-outjar', pg_output]
  for library_name, relocated_package in R8_RELOCATIONS:
    pg_args.extend(['-dontwarn', relocated_package + '.**',
                    '-dontnote', relocated_package + '.**'])
  check_call(pg_args)
  if threshold is None:
    threshold = 5
  toolhelper.run('jarsizecompare',
                 ['--threshold', str(threshold),
                  '--lib', utils.RT_JAR,
                  '--input', 'input', utils.R8_JAR,
                  '--input', 'r8', r8lib_jar, r8lib_map,
                  '--input', 'pg', pg_output, pg_map])


if __name__ == '__main__':
  main(**vars(parser.parse_args()))
