#!/usr/bin/env python3
# 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.

# Script for running kotlin based benchmarks

import optparse
import os
import subprocess
import sys
import toolhelper
import utils


BENCHMARK_ROOT = os.path.join(utils.REPO_ROOT, 'third_party', 'benchmarks',
                              'kotlin-benches')

BENCHMARK_PATTERN = '{benchmark}/kotlin/perf/build/libs/perf-1.0-BENCH.jar'
BENCHMARK_MAIN_CLASS = 'com.android.kt.bms.cli.Runner'
ART = os.path.join(utils.TOOLS_DIR, 'linux', 'art', 'bin', 'art')

PROGUARD_CONF = """
# From Android rules
-keepclasseswithmembers public class * {
  public static void main(java.lang.String[]);
}
# Disable obfuscation to only focus on shrinking
-dontobfuscate
# Once we're ready for optimization, we might want to relax access modifiers.
-allowaccessmodification
"""

DEVICE_TEMP='/data/local/temp/bench'


def parse_options():
  result = optparse.OptionParser()
  result.add_option('--api',
                    help='Android api level',
                    default='26',
                    choices=['21', '22', '23', '24', '25', '26'])
  result.add_option('--benchmark',
                    help='The benchmark to run',
                    default='rgx',
                    choices=['rgx', 'deltablue', 'sta', 'empty'])
  result.add_option('--use-device',
                    help='Run the benchmark on an attaced device',
                    default=False, action='store_true')
  return result.parse_args()


def get_jar_for_benchmark(benchmark):
  return os.path.join(BENCHMARK_ROOT,
                      BENCHMARK_PATTERN.format(benchmark=benchmark))

def run_art(dex):
  command = ['bash', ART, '-cp', dex, BENCHMARK_MAIN_CLASS]
  utils.PrintCmd(command)
  benchmark_output = subprocess.check_output(command)
  return get_result(benchmark_output)

def adb(args):
  command = ['adb'] + args
  utils.PrintCmd(command)
  return subprocess.check_output(['adb'] + args)

def get_result(output):
  # There is a lot of debug output, with the actual results being in the line with:
  # RESULTS,KtBench,KtBench,15719
  # structure.
  for result in [s for s in output.splitlines() if s.startswith('RESULTS')]:
    return s.split('RESULTS,KtBench,KtBench,')[1]

def run_art_device(dex):
  adb(['wait-for-device', 'root'])
  device_dst = os.path.join(DEVICE_TEMP, os.path.basename(dex))
  adb(['push', dex, device_dst])
  benchmark_output = adb(['shell', 'dalvikvm', '-cp', device_dst, BENCHMARK_MAIN_CLASS])
  return get_result(benchmark_output)

def Main():
  (options, args) = parse_options()
  with utils.TempDir() as temp:
    dex_path = os.path.join(temp, "classes.jar")
    proguard_conf = os.path.join(temp, 'proguard.conf')
    with open(proguard_conf, 'w') as f:
      f.write(PROGUARD_CONF)
    benchmark_jar = get_jar_for_benchmark(options.benchmark)
    r8_args = [
        '--lib', utils.get_android_jar(26), # Only works with api 26
        '--output', dex_path,
        '--pg-conf', proguard_conf,
        '--min-api', str(options.api),
        benchmark_jar
    ]
    toolhelper.run('r8', r8_args, True)
    if options.use_device:
      result = run_art_device(dex_path)
    else:
      result = run_art(dex_path)
    print('Kotlin_{}(RunTimeRaw): {} ms'.format(options.benchmark, result))

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