#!/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())
