#!/usr/bin/env python3
# Copyright (c) 2020, 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.

import argparse
import os
import subprocess
import sys
import time

import jdk
import proguard
import toolhelper
import utils

SHRINKERS = ['r8'] + proguard.getVersions()

INPUT_PROGRAM = utils.PINNED_R8_JAR

ANNO = 'com.android.tools.r8.com.google.common.annotations.VisibleForTesting'

R8_OPTIONS = [
  'printTimes',
  'passthroughDexCode',
  'enableClassMerging',
  'enableDevirtualization',
  'enableNonNullTracking',
  'enableInlining',
  'enableSwitchMapRemoval',
  'enableValuePropagation',
  'useSmaliSyntax',
  'verbose',
  'quiet',
  'invalidDebugInfoFatal',
  'intermediate',
  'enableLambdaMerging',
  'enableDesugaring',
  'enableMainDexListCheck',
  'enableTreeShaking',
  'printCfg',
  'ignoreMissingClasses',
  'forceProguardCompatibility',
  'enableMinification',
  'disableAssertions',
  'debugKeepRules',
  'debug',
  'minimalMainDex',
  'skipReadingDexCode',
]

R8_CLASSES = [
  'com.android.tools.r8.code.Format11x',
  'com.android.tools.r8.code.MoveFrom16',
  'com.android.tools.r8.code.AddLong2Addr',
  'com.android.tools.r8.code.AgetByte',
  'com.android.tools.r8.code.SubDouble',
  'com.android.tools.r8.code.Sput',
  'com.android.tools.r8.code.Format10x',
  'com.android.tools.r8.code.RemInt',
  'com.android.tools.r8.code.ConstWide',
  'com.android.tools.r8.code.SgetWide',
  'com.android.tools.r8.code.OrInt2Addr',
  'com.android.tools.r8.code.Iget',
  'com.android.tools.r8.code.Instruction',
  'com.android.tools.r8.code.SubInt2Addr',
  'com.android.tools.r8.code.SwitchPayload',
  'com.android.tools.r8.code.Const4',
  'com.android.tools.r8.code.ShrIntLit8',
  'com.android.tools.r8.code.ConstWide16',
  'com.android.tools.r8.code.NegInt',
  'com.android.tools.r8.code.SgetBoolean',
  'com.android.tools.r8.code.Format22x',
  'com.android.tools.r8.code.InvokeVirtualRange',
  'com.android.tools.r8.code.Format45cc',
  'com.android.tools.r8.code.DivFloat2Addr',
  'com.android.tools.r8.code.MulIntLit16',
  'com.android.tools.r8.code.BytecodeStream',
]

KEEP_MAIN = \
  '-keep class com.android.tools.r8.R8 { void main(java.lang.String[]); }'

BENCHMARKS = [
  # Baseline compile just keeps R8.main (implicitly kept for all benchmarks).
  ('KeepBaseline', ''),

  # Mirror default keep getters/setters, but independent of hierarchy.
  ('KeepGetters',
    '-keepclassmembers class * { *** get*(); }'),
  ('KeepGettersIf',
    '-if class * { *** get*(); } -keep class <1> { *** get<2>(); }'),

  # Mirror default keep getters/setters below View (here a class with a B).
  ('KeepSubGetters',
    '-keepclassmembers class * extends **.*B* { *** get*(); }'),
  ('KeepSubGettersIf',
    '-if class * extends **.*B* -keep class <1> { *** get*(); }'),

  # General keep rule to keep annotated members.
  ('KeepAnnoMethod',
    '-keepclasseswithmembers class * { @%s *** *(...); }' % ANNO),
  ('KeepAnnoMethodCond',
    '-keepclassmembers class * { @%s *** *(...); }' % ANNO),
  ('KeepAnnoMethodIf',
    '-if class * { @%s *** *(...); } -keep class <1> { @%s *** <2>(...); }' \
        % (ANNO, ANNO)),

  # Large collection of rules mirroring AAPT conditional rules on R fields.
  ('KeepAaptFieldIf',
   '\n'.join([
     '-if class **.InternalOptions { boolean %s; }'
     ' -keep class %s { <init>(...); }' % (f, c)
     for (f, c) in zip(R8_OPTIONS, R8_CLASSES) * 1 #100
   ])),

  # If rules with predicates that will never by true, but will need
  # consideration. The CodeSize of these should be equal to the baseline run.
  ('KeepIfNonExistingClass',
   '-if class **.*A*B*C*D*E*F* -keep class %s' % ANNO),
  ('KeepIfNonExistingMember',
   '-if class **.*A* { *** *a*b*c*d*e*f*(...); } -keep class %s' % ANNO)
]

def parse_arguments(argv):
  parser = argparse.ArgumentParser(
                    description = 'Run keep-rule benchmarks.')
  parser.add_argument('--ignore-java-version',
                    help='Do not check java version',
                    default=False,
                    action='store_true')
  parser.add_argument('--shrinker',
                    help='The shrinker to use',
                    choices=SHRINKERS,
                    default=SHRINKERS[0])
  parser.add_argument('--runs',
                      help='Number of runs to average out time on',
                      type=int,
                      default=3)
  parser.add_argument('--benchmark',
                      help='Benchmark to run (default all)',
                      choices=map(lambda (x,y): x, BENCHMARKS),
                      default=None)
  options = parser.parse_args(argv)
  return options

class BenchmarkResult:
  def __init__(self, name, size, runs):
    self.name = name
    self.size = size
    self.runs = runs

def isPG(shrinker):
  return proguard.isValidVersion(shrinker)

def shrinker_args(shrinker, keepfile, output):
  if shrinker == 'r8':
    return [
      jdk.GetJavaExecutable(),
      '-cp', utils.R8LIB_JAR,
      'com.android.tools.r8.R8',
      INPUT_PROGRAM,
      '--lib', utils.RT_JAR,
      '--output', output,
      '--min-api', '10000',
      '--pg-conf', keepfile,
      ]
  elif isPG(shrinker):
    return proguard.getCmd([
      '-injars', INPUT_PROGRAM,
      '-libraryjars', utils.RT_JAR,
      '-outjars', output,
      '-dontwarn', '**',
      '-optimizationpasses', '2',
      '@' + keepfile,
    ],
    version=shrinker)
  else:
    assert False, "Unexpected shrinker " + shrinker

def dex(input, output):
  toolhelper.run(
      'd8',
      [
        input,
        '--lib', utils.RT_JAR,
        '--min-api', '10000',
        '--output', output
      ],
      build=False,
      debug=False)

def run_shrinker(options, temp):
  benchmarks = BENCHMARKS
  if options.benchmark:
    for (name, rules) in BENCHMARKS:
      if name == options.benchmark:
        benchmarks = [(name, rules)]
        break
    assert len(benchmarks) == 1, "Unexpected benchmark " + options.benchmark

  run_count = options.runs
  benchmark_results = []
  for (name, rule) in benchmarks:
    benchmark_keep = os.path.join(temp, '%s-keep.txt' % name)
    with open(benchmark_keep, 'w') as fp:
      fp.write(KEEP_MAIN)
      fp.write('\n')
      fp.write(rule)

    benchmark_runs = []
    benchmark_size = 0
    for i in range(run_count):
      out = os.path.join(temp, '%s-out%d.jar' % (name, i))
      cmd = shrinker_args(options.shrinker, benchmark_keep, out)
      utils.PrintCmd(cmd)
      t0 = time.time()
      subprocess.check_output(cmd)
      t1 = time.time()
      benchmark_runs.append(t1 - t0)
      if isPG(options.shrinker):
        dexout = os.path.join(temp, '%s-out%d-dex.jar' % (name, i))
        dex(out, dexout)
        benchmark_size = utils.uncompressed_size(dexout)
      else:
        benchmark_size = utils.uncompressed_size(out)
    benchmark_results.append(
        BenchmarkResult(name, benchmark_size, benchmark_runs))

  print 'Runs:', options.runs
  for result in benchmark_results:
    benchmark_avg = sum(result.runs) / run_count
    print '%s(CodeSize): %d' % (result.name, result.size)
    print '%s(RunTimeRaw): %d ms' % (result.name, 1000.0 * benchmark_avg)

if __name__ == '__main__':
  options = parse_arguments(sys.argv[1:])
  if not options.ignore_java_version:
    utils.check_java_version()
  with utils.TempDir() as temp:
    run_shrinker(options, temp)
