#!/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 hashlib
import os
import shutil
import sys
import time
import zipfile
from datetime import datetime

import adb
import apk_masseur
import as_utils
import compiledump
import gradle
import jdk
import thread_utils
from thread_utils import print_thread
import update_prebuilds_in_android
import utils

GOLEM_BUILD_TARGETS = [utils.GRADLE_TASK_R8LIB]
SHRINKERS = ['r8', 'r8-full', 'r8-nolib', 'r8-nolib-full']


class AttrDict(dict):

    def __getattr__(self, name):
        return self.get(name, None)


# To generate the files for a new app, navigate to the app source folder and
# run:
# ./gradlew clean :app:assembleRelease -Dcom.android.tools.r8.dumpinputtodirectory=<path>
# and store the dump and the apk.
# If the app has instrumented tests, adding `testBuildType "release"` and
# running:
# ./gradlew assembleAndroidTest -Dcom.android.tools.r8.dumpinputtodirectory=<path>
# will also generate dumps and apk for tests.


class App(object):

    def __init__(self, fields):
        defaults = {
            'id': None,
            'name': None,
            'collections': [],
            'dump_app': None,
            'apk_app': None,
            'dump_test': None,
            'apk_test': None,
            'skip': False,
            'url': None,  # url is not used but nice to have for updating apps
            'revision': None,
            'folder': None,
            'skip_recompilation': False,
            'compiler_properties': [],
            'internal': False,
            'golem_duration': None,
        }
        # This below does not work in python3
        defaults.update(fields.items())
        self.__dict__ = defaults


class AppCollection(object):

    def __init__(self, fields):
        defaults = {'name': None}
        # This below does not work in python3
        defaults.update(fields.items())
        self.__dict__ = defaults


APPS = [
    App({
        'id':
            'com.numix.calculator',
        'name':
            'Calculator',
        'dump_app':
            'dump_app.zip',
        'apk_app':
            'app-release.apk',
        # Compiling tests fail: Library class android.content.res.XmlResourceParser
        # implements program class org.xmlpull.v1.XmlPullParser. Nothing to really
        # do about that.
        'id_test':
            'com.numix.calculator.test',
        'dump_test':
            'dump_test.zip',
        'apk_test':
            'app-release-androidTest.apk',
        'url':
            'https://github.com/numixproject/android-suite/tree/master/Calculator',
        'revision':
            'f58e1b53f7278c9b675d5855842c6d8a44cccb1f',
        'folder':
            'android-suite-calculator',
    }),
    App({
        'id': 'dev.dworks.apps.anexplorer.pro',
        'name': 'AnExplorer',
        'dump_app': 'dump_app.zip',
        'apk_app': 'AnExplorer-googleMobileProRelease-4.0.3.apk',
        'url': 'https://github.com/christofferqa/AnExplorer',
        'revision': '365927477b8eab4052a1882d5e358057ae3dee4d',
        'folder': 'anexplorer',
    }),
    App({
        'id': 'de.danoeh.antennapod',
        'name': 'AntennaPod',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-free-release.apk',
        # TODO(b/172452102): Tests and monkey do not work
        'id_test': 'de.danoeh.antennapod.test',
        'dump_test': 'dump_test.zip',
        'apk_test': 'app-free-release-androidTest.apk',
        'url': 'https://github.com/christofferqa/AntennaPod.git',
        'revision': '77e94f4783a16abe9cc5b78dc2d2b2b1867d8c06',
        'folder': 'antennapod',
    }),
    App({
        'id': 'com.example.applymapping',
        'name': 'applymapping',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release.apk',
        'id_test': 'com.example.applymapping.test',
        'dump_test': 'dump_test.zip',
        'apk_test': 'app-release-androidTest.apk',
        'url': 'https://github.com/mkj-gram/applymapping',
        'revision': 'e3ae14b8c16fa4718e5dea8f7ad00937701b3c48',
        'folder': 'applymapping',
    }),
    App({
        'id':
            'com.chanapps.four.activity',
        'name':
            'chanu',
        'dump_app':
            'dump_app.zip',
        'apk_app':
            'app-release.apk',
        'url':
            'https://github.com/mkj-gram/chanu.git',
        'revision':
            '6e53458f167b6d78398da60c20fd0da01a232617',
        'folder':
            'chanu',
        # The app depends on a class file that has access flags interface but
        # not abstract
        'compiler_properties': [
            '-Dcom.android.tools.r8.allowInvalidCfAccessFlags=true'
        ]
    }),
    App({
        'id': 'com.example.myapplication',
        'name': 'empty-activity',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release.apk',
        'url': 'https://github.com/christofferqa/empty_android_activity.git',
        'revision': '2d297ec3373dadb03cbae916b9feba4792563156',
        'folder': 'empty-activity',
    }),
    App({
        'id':
            'com.example.emptycomposeactivity',
        'name':
            'empty-compose-activity',
        'dump_app':
            'dump_app.zip',
        'apk_app':
            'app-release.apk',
        'url':
            'https://github.com/christofferqa/empty_android_compose_activity.git',
        'revision':
            '3c8111b8b7d6e9184049a07e2b96702d7b33d03e',
        'folder':
            'empty-compose-activity',
    }),
    # TODO(b/172539375): Monkey runner fails on recompilation.
    App({
        'id': 'com.google.firebase.example.fireeats',
        'name': 'FriendlyEats',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release-unsigned.apk',
        'url': 'https://github.com/firebase/friendlyeats-android',
        'revision': '7c6dd016fc31ea5ecb948d5166b8479efc3775cc',
        'folder': 'friendlyeats',
    }),
    App({
        'id': 'com.google.samples.apps.sunflower',
        'name': 'Sunflower',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-debug.apk',
        # TODO(b/172549283): Compiling tests fails
        'id_test': 'com.google.samples.apps.sunflower.test',
        'dump_test': 'dump_test.zip',
        'apk_test': 'app-debug-androidTest.apk',
        'url': 'https://github.com/android/sunflower',
        'revision': '0c4c88fdad2a74791199dffd1a6559559b1dbd4a',
        'folder': 'sunflower',
    }),
    # TODO(b/172565385): Monkey runner fails on recompilation
    App({
        'id': 'com.google.samples.apps.iosched',
        'name': 'iosched',
        'dump_app': 'dump_app.zip',
        'apk_app': 'mobile-release.apk',
        'url': 'https://github.com/christofferqa/iosched.git',
        'revision': '581cbbe2253711775dbccb753cdb53e7e506cb02',
        'folder': 'iosched',
    }),
    App({
        'id': 'fr.neamar.kiss',
        'name': 'KISS',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release.apk',
        # TODO(b/172569220): Running tests fails due to missing keep rules
        'id_test': 'fr.neamar.kiss.test',
        'dump_test': 'dump_test.zip',
        'apk_test': 'app-release-androidTest.apk',
        'url': 'https://github.com/Neamar/KISS',
        'revision': '8ccffaadaf0d0b8fc4418ed2b4281a0935d3d971',
        'folder': 'kiss',
    }),
    # TODO(b/172577344): Monkey runner not working.
    App({
        'id': 'io.github.hidroh.materialistic',
        'name': 'materialistic',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release.apk',
        'url': 'https://github.com/christofferqa/materialistic.git',
        'revision': '2b2b2ee25ce9e672d5aab1dc90a354af1522b1d9',
        'folder': 'materialistic',
    }),
    App({
        'id': 'com.avjindersinghsekhon.minimaltodo',
        'name': 'MinimalTodo',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release.apk',
        'url': 'https://github.com/christofferqa/Minimal-Todo',
        'revision': '9d8c73746762cd376b718858ec1e8783ca07ba7c',
        'folder': 'minimal-todo',
    }),
    App({
        'id': 'net.nurik.roman.muzei',
        'name': 'muzei',
        'dump_app': 'dump_app.zip',
        'apk_app': 'muzei-release.apk',
        'url': 'https://github.com/romannurik/muzei',
        'revision': '9eac6e98aebeaf0ae40bdcd85f16dd2886551138',
        'folder': 'muzei',
    }),
    # TODO(b/172806281): Monkey runner does not work.
    App({
        'id': 'org.schabi.newpipe',
        'name': 'NewPipe',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release-unsigned.apk',
        'url': 'https://github.com/TeamNewPipe/NewPipe',
        'revision': 'f4435f90313281beece70c544032f784418d85fa',
        'folder': 'newpipe',
    }),
    # TODO(b/172806808): Monkey runner does not work.
    App({
        'id': 'io.rover.app.debug',
        'name': 'Rover',
        'dump_app': 'dump_app.zip',
        'apk_app': 'example-app-release-unsigned.apk',
        'url': 'https://github.com/RoverPlatform/rover-android',
        'revision': '94342117097770ea3ca2c6df6ab496a1a55c3ce7',
        'folder': 'rover-android',
    }),
    # TODO(b/172808159): Monkey runner does not work
    App({
        'id': 'com.google.android.apps.santatracker',
        'name': 'SantaTracker',
        'dump_app': 'dump_app.zip',
        'apk_app': 'santa-tracker-release.apk',
        'url': 'https://github.com/christofferqa/santa-tracker-android',
        'revision': '8dee74be7d9ee33c69465a07088c53087d24a6dd',
        'folder': 'santa-tracker',
    }),
    App({
        'id': 'org.thoughtcrime.securesms',
        'name': 'Signal',
        'dump_app': 'dump_app.zip',
        'apk_app': 'Signal-Android-play-prod-universal-release-4.76.2.apk',
        # TODO(b/172812839): Instrumentation test fails.
        'id_test': 'org.thoughtcrime.securesms.test',
        'dump_test': 'dump_test.zip',
        'apk_test': 'Signal-Android-play-prod-release-androidTest.apk',
        'url': 'https://github.com/signalapp/Signal-Android',
        'revision': '91ca19f294362ccee2c2b43c247eba228e2b30a1',
        'folder': 'signal-android',
        'golem_duration': 300
    }),
    # TODO(b/172815827): Monkey runner does not work
    App({
        'id': 'com.simplemobiletools.calendar.pro',
        'name': 'Simple-Calendar',
        'dump_app': 'dump_app.zip',
        'apk_app': 'calendar-release.apk',
        'url': 'https://github.com/SimpleMobileTools/Simple-Calendar',
        'revision': '906209874d0a091c7fce5a57972472f272d6b068',
        'folder': 'simple-calendar',
    }),
    # TODO(b/172815534): Monkey runner does not work
    App({
        'id': 'com.simplemobiletools.camera.pro',
        'name': 'Simple-Camera',
        'dump_app': 'dump_app.zip',
        'apk_app': 'camera-release.apk',
        'url': 'https://github.com/SimpleMobileTools/Simple-Camera',
        'revision': 'ebf9820c51e960912b3238287e30a131244fdee6',
        'folder': 'simple-camera',
    }),
    App({
        'id': 'com.simplemobiletools.filemanager.pro',
        'name': 'Simple-File-Manager',
        'dump_app': 'dump_app.zip',
        'apk_app': 'file-manager-release.apk',
        'url': 'https://github.com/SimpleMobileTools/Simple-File-Manager',
        'revision': '2b7fa68ea251222cc40cf6d62ad1de260a6f54d9',
        'folder': 'simple-file-manager',
    }),
    App({
        'id': 'com.simplemobiletools.gallery.pro',
        'name': 'Simple-Gallery',
        'dump_app': 'dump_app.zip',
        'apk_app': 'gallery-326-foss-release.apk',
        'url': 'https://github.com/SimpleMobileTools/Simple-Gallery',
        'revision': '564e56b20d33b28d0018c8087ec705beeb60785e',
        'folder': 'simple-gallery',
    }),
    App({
        'id': 'com.example.sqldelight.hockey',
        'name': 'SQLDelight',
        'dump_app': 'dump_app.zip',
        'apk_app': 'android-release.apk',
        'url': 'https://github.com/christofferqa/sqldelight',
        'revision': '2e67a1126b6df05e4119d1e3a432fde51d76cdc8',
        'folder': 'sqldelight',
    }),
    # TODO(b/172824096): Monkey runner does not work.
    App({
        'id': 'eu.kanade.tachiyomi',
        'name': 'Tachiyomi',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-dev-release.apk',
        'url': 'https://github.com/inorichi/tachiyomi',
        'revision': '8aa6486bf76ab9a61a5494bee284b1a5e9180bf3',
        'folder': 'tachiyomi',
    }),
    # TODO(b/172862042): Monkey runner does not work.
    App({
        'id': 'app.tivi',
        'name': 'Tivi',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-release.apk',
        'url': 'https://github.com/chrisbanes/tivi',
        'revision': '5c6d9ed338885c59b1fc64050d92d056417bb4de',
        'folder': 'tivi',
        'golem_duration': 300
    }),
    App({
        'id': 'com.keylesspalace.tusky',
        'name': 'Tusky',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-blue-release.apk',
        'url': 'https://github.com/tuskyapp/Tusky',
        'revision': '814a9b8f9bacf8d26f712b06a0313a3534a2be95',
        'folder': 'tusky',
    }),
    App({
        'id': 'org.wikipedia',
        'name': 'Wikipedia',
        'dump_app': 'dump_app.zip',
        'apk_app': 'app-prod-release.apk',
        'url': 'https://github.com/wikimedia/apps-android-wikipedia',
        'revision': '0fa7cad843c66313be8e25790ef084cf1a1fa67e',
        'folder': 'wikipedia',
    })
]

APP_COLLECTIONS = []


def remove_print_lines(file):
    with open(file) as f:
        lines = f.readlines()
    with open(file, 'w') as f:
        for line in lines:
            if '-printconfiguration' not in line:
                f.write(line)


def download_sha(app_sha, internal, quiet=False):
    if internal:
        utils.DownloadFromX20(app_sha)
    else:
        utils.DownloadFromGoogleCloudStorage(app_sha, quiet=quiet)


def is_logging_enabled_for(app, options):
    if options.no_logging:
        return False
    if options.app_logging_filter and app.name not in options.app_logging_filter:
        return False
    return True


def is_minified_r8(shrinker):
    return '-nolib' not in shrinker


def is_full_r8(shrinker):
    return '-full' in shrinker


def version_is_built_jar(version):
    return version != 'main' and version != 'source'


def compute_size_of_dex_files_in_package(path):
    dex_size = 0
    z = zipfile.ZipFile(path, 'r')
    for filename in z.namelist():
        if filename.endswith('.dex'):
            dex_size += z.getinfo(filename).file_size
    return dex_size


def dump_for_app(app_dir, app):
    return os.path.join(app_dir, app.dump_app)


def dump_test_for_app(app_dir, app):
    return os.path.join(app_dir, app.dump_test)


def get_r8_jar(options, temp_dir, shrinker):
    if (options.version == 'source'):
        return None
    jar = os.path.abspath(
        os.path.join(temp_dir, '..',
                     'r8lib.jar' if is_minified_r8(shrinker) else 'r8.jar'))
    return jar


def get_results_for_app(app, options, temp_dir, worker_id):
    app_folder = app.folder if app.folder else app.name + "_" + app.revision
    # Golem extraction will extract to the basename under the benchmarks dir.
    app_location = os.path.basename(app_folder) if options.golem else app_folder
    opensource_basedir = (os.path.join('benchmarks', app.name)
                          if options.golem else utils.OPENSOURCE_DUMPS_DIR)
    app_dir = (os.path.join(utils.INTERNAL_DUMPS_DIR, app_location) if
               app.internal else os.path.join(opensource_basedir, app_location))
    if not os.path.exists(app_dir) and not options.golem:
        # Download the app from google storage.
        download_sha(app_dir + ".tar.gz.sha1", app.internal)

    # Ensure that the dumps are in place
    assert os.path.isfile(dump_for_app(app_dir, app)), "Could not find dump " \
                                                       "for app " + app.name

    result = {}
    result['status'] = 'success'
    result_per_shrinker = build_app_with_shrinkers(app,
                                                   options,
                                                   temp_dir,
                                                   app_dir,
                                                   worker_id=worker_id)
    for shrinker, shrinker_result in result_per_shrinker.items():
        result[shrinker] = shrinker_result
    return result


def build_app_with_shrinkers(app, options, temp_dir, app_dir, worker_id):
    result_per_shrinker = {}
    for shrinker in options.shrinker:
        results = []
        build_app_and_run_with_shrinker(app,
                                        options,
                                        temp_dir,
                                        app_dir,
                                        shrinker,
                                        results,
                                        worker_id=worker_id)
        result_per_shrinker[shrinker] = results
    if len(options.apps) > 1:
        print_thread('', worker_id)
        log_results_for_app(app,
                            result_per_shrinker,
                            options,
                            worker_id=worker_id)
        print_thread('', worker_id)

    return result_per_shrinker


def is_last_build(index, compilation_steps):
    return index == compilation_steps - 1


def build_app_and_run_with_shrinker(app, options, temp_dir, app_dir, shrinker,
                                    results, worker_id):
    print_thread(
        '[{}] Building {} with {}'.format(datetime.now().strftime("%H:%M:%S"),
                                          app.name, shrinker), worker_id)
    print_thread(
        'To compile locally: '
        'tools/run_on_app_dump.py --shrinker {} --r8-compilation-steps {} '
        '--app {} --minify {} --optimize {} --shrink {}'.format(
            shrinker, options.r8_compilation_steps, app.name, options.minify,
            options.optimize, options.shrink), worker_id)
    print_thread(
        'HINT: use --shrinker r8-nolib --no-build if you have a local R8.jar',
        worker_id)
    recomp_jar = None
    status = 'success'
    if options.r8_compilation_steps < 1:
        return
    compilation_steps = 1 if app.skip_recompilation else options.r8_compilation_steps
    for compilation_step in range(0, compilation_steps):
        if status != 'success':
            break
        print_thread(
            'Compiling {} of {}'.format(compilation_step + 1,
                                        compilation_steps), worker_id)
        result = {}
        try:
            start = time.time()
            (app_jar, mapping, new_recomp_jar) = \
              build_app_with_shrinker(
                app, options, temp_dir, app_dir, shrinker, compilation_step,
                compilation_steps, recomp_jar, worker_id=worker_id)
            end = time.time()
            dex_size = compute_size_of_dex_files_in_package(app_jar)
            result['build_status'] = 'success'
            result['recompilation_status'] = 'success'
            result['output_jar'] = app_jar
            result['output_mapping'] = mapping
            result['dex_size'] = dex_size
            result['duration'] = int((end - start) * 1000)  # Wall time
            if (new_recomp_jar is None and
                    not is_last_build(compilation_step, compilation_steps)):
                result['recompilation_status'] = 'failed'
                warn('Failed to build {} with {}'.format(app.name, shrinker))
            recomp_jar = new_recomp_jar
        except Exception as e:
            warn('Failed to build {} with {}'.format(app.name, shrinker))
            if e:
                print_thread('Error: ' + str(e), worker_id)
            result['build_status'] = 'failed'
            status = 'failed'

        original_app_apk = os.path.join(app_dir, app.apk_app)
        app_apk_destination = os.path.join(
            temp_dir, "{}_{}.apk".format(app.id, compilation_step))

        if result.get('build_status') == 'success' and options.monkey:
            # Make a copy of the given APK, move the newly generated dex files into the
            # copied APK, and then sign the APK.
            apk_masseur.masseur(original_app_apk,
                                dex=app_jar,
                                resources='META-INF/services/*',
                                out=app_apk_destination,
                                quiet=options.quiet,
                                logging=is_logging_enabled_for(app, options),
                                keystore=options.keystore)

            result['monkey_status'] = 'success' if adb.run_monkey(
                app.id, options.emulator_id, app_apk_destination,
                options.monkey_events, options.quiet,
                is_logging_enabled_for(app, options)) else 'failed'

        if (result.get('build_status') == 'success' and options.run_tests and
                app.dump_test):
            if not os.path.isfile(app_apk_destination):
                apk_masseur.masseur(original_app_apk,
                                    dex=app_jar,
                                    resources='META-INF/services/*',
                                    out=app_apk_destination,
                                    quiet=options.quiet,
                                    logging=is_logging_enabled_for(
                                        app, options),
                                    keystore=options.keystore)

            # Compile the tests with the mapping file.
            test_jar = build_test_with_shrinker(app, options, temp_dir, app_dir,
                                                shrinker, compilation_step,
                                                result['output_mapping'])
            if not test_jar:
                result['instrumentation_test_status'] = 'compilation_failed'
            else:
                original_test_apk = os.path.join(app_dir, app.apk_test)
                test_apk_destination = os.path.join(
                    temp_dir, "{}_{}.test.apk".format(app.id_test,
                                                      compilation_step))
                apk_masseur.masseur(original_test_apk,
                                    dex=test_jar,
                                    resources='META-INF/services/*',
                                    out=test_apk_destination,
                                    quiet=options.quiet,
                                    logging=is_logging_enabled_for(
                                        app, options),
                                    keystore=options.keystore)
                result[
                    'instrumentation_test_status'] = 'success' if adb.run_instrumented(
                        app.id, app.id_test, options.emulator_id,
                        app_apk_destination,
                        test_apk_destination, options.quiet,
                        is_logging_enabled_for(app, options)) else 'failed'

        results.append(result)
        if result.get('recompilation_status') != 'success':
            break


def get_jdk_home(options, app):
    if options.golem:
        return os.path.join('benchmarks', app.name, 'linux')
    return None


def build_app_with_shrinker(app, options, temp_dir, app_dir, shrinker,
                            compilation_step_index, compilation_steps,
                            prev_recomp_jar, worker_id):

    def config_files_consumer(files):
        for file in files:
            compiledump.clean_config(file, options)
            remove_print_lines(file)

    properties = app.compiler_properties
    if options.dump_input_to_directory:
        properties.append(
            '-Dcom.android.tools.r8.dumpinputtodirectory=%s'
                % options.dump_input_to_directory)
    args = AttrDict({
        'dump': dump_for_app(app_dir, app),
        'r8_jar': get_r8_jar(options, temp_dir, shrinker),
        'r8_flags': options.r8_flags,
        'disable_assertions': options.disable_assertions,
        'version': options.version,
        'compiler': 'r8full' if is_full_r8(shrinker) else 'r8',
        'debug_agent': options.debug_agent,
        'program_jar': prev_recomp_jar,
        'nolib': not is_minified_r8(shrinker),
        'config_files_consumer': config_files_consumer,
        'properties': properties,
        'disable_desugared_lib': False,
        'print_times': options.print_times,
        'java_opts': [],
    })

    app_jar = os.path.join(
        temp_dir, '{}_{}_{}_dex_out.jar'.format(app.name, shrinker,
                                                compilation_step_index))
    app_mapping = os.path.join(
        temp_dir, '{}_{}_{}_dex_out.jar.map'.format(app.name, shrinker,
                                                    compilation_step_index))
    recomp_jar = None
    jdkhome = get_jdk_home(options, app)
    with utils.TempDir() as compile_temp_dir:
        compile_result = compiledump.run1(compile_temp_dir,
                                          args, [],
                                          jdkhome,
                                          worker_id=worker_id)
        out_jar = os.path.join(compile_temp_dir, "out.jar")
        out_mapping = os.path.join(compile_temp_dir, "out.jar.map")

        if compile_result != 0 or not os.path.isfile(out_jar):
            assert False, 'Compilation of {} failed'.format(
                dump_for_app(app_dir, app))
        shutil.move(out_jar, app_jar)
        shutil.move(out_mapping, app_mapping)

        if compilation_step_index < compilation_steps - 1:
            args['classfile'] = True
            args['min_api'] = "10000"
            args['disable_desugared_lib'] = True
            compile_result = compiledump.run1(compile_temp_dir, args, [],
                                              jdkhome)
            if compile_result == 0:
                recomp_jar = os.path.join(
                    temp_dir,
                    '{}_{}_{}_cf_out.jar'.format(app.name, shrinker,
                                                 compilation_step_index))
                shutil.move(out_jar, recomp_jar)

    return (app_jar, app_mapping, recomp_jar)


def build_test_with_shrinker(app, options, temp_dir, app_dir, shrinker,
                             compilation_step_index, mapping):

    def rewrite_files(files):
        add_applymapping = True
        for file in files:
            compiledump.clean_config(file, options)
            remove_print_lines(file)
            with open(file) as f:
                lines = f.readlines()
            with open(file, 'w') as f:
                for line in lines:
                    if '-applymapping' not in line:
                        f.write(line + '\n')
                if add_applymapping:
                    f.write("-applymapping " + mapping + '\n')
                    add_applymapping = False

    args = AttrDict({
        'dump': dump_test_for_app(app_dir, app),
        'r8_jar': get_r8_jar(options, temp_dir, shrinker),
        'disable_assertions': options.disable_assertions,
        'version': options.version,
        'compiler': 'r8full' if is_full_r8(shrinker) else 'r8',
        'debug_agent': options.debug_agent,
        'nolib': not is_minified_r8(shrinker),
        # The config file will have an -applymapping reference to an old map.
        # Update it to point to mapping file build in the compilation of the app.
        'config_files_consumer': rewrite_files,
    })

    test_jar = os.path.join(
        temp_dir, '{}_{}_{}_test_out.jar'.format(app.name, shrinker,
                                                 compilation_step_index))

    with utils.TempDir() as compile_temp_dir:
        jdkhome = get_jdk_home(options, app)
        compile_result = compiledump.run1(compile_temp_dir, args, [], jdkhome)
        out_jar = os.path.join(compile_temp_dir, "out.jar")
        if compile_result != 0 or not os.path.isfile(out_jar):
            return None
        shutil.move(out_jar, test_jar)

    return test_jar


def log_results_for_apps(result_per_shrinker_per_app, options):
    print('')
    app_errors = 0
    for (app, result_per_shrinker) in result_per_shrinker_per_app:
        app_errors += (1 if log_results_for_app(app, result_per_shrinker,
                                                options) else 0)
    return app_errors


def log_results_for_app(app, result_per_shrinker, options, worker_id=None):
    if options.print_dexsegments:
        log_segments_for_app(app,
                             result_per_shrinker,
                             options,
                             worker_id=worker_id)
        return False
    else:
        return log_comparison_results_for_app(app,
                                              result_per_shrinker,
                                              options,
                                              worker_id=worker_id)


def log_segments_for_app(app, result_per_shrinker, options, worker_id):
    for shrinker in SHRINKERS:
        if shrinker not in result_per_shrinker:
            continue
        for result in result_per_shrinker.get(shrinker):
            benchmark_name = '{}-{}'.format(options.print_dexsegments, app.name)
            utils.print_dexsegments(benchmark_name, [result.get('output_jar')],
                                    worker_id=worker_id)
            duration = result.get('duration')
            print_thread(
                '%s-Total(RunTimeRaw): %s ms' % (benchmark_name, duration),
                worker_id)
            print_thread(
                '%s-Total(CodeSize): %s' %
                (benchmark_name, result.get('dex_size')), worker_id)


def percentage_diff_as_string(before, after):
    if after < before:
        return '-' + str(round((1.0 - after / before) * 100)) + '%'
    else:
        return '+' + str(round((after - before) / before * 100)) + '%'


def log_comparison_results_for_app(app, result_per_shrinker, options,
                                   worker_id):
    print_thread(app.name + ':', worker_id)
    app_error = False
    if result_per_shrinker.get('status', 'success') != 'success':
        error_message = result_per_shrinker.get('error_message')
        print_thread('  skipped ({})'.format(error_message), worker_id)
        return

    proguard_result = result_per_shrinker.get('pg', {})
    proguard_dex_size = float(proguard_result.get('dex_size', -1))

    for shrinker in SHRINKERS:
        if shrinker not in result_per_shrinker:
            continue
        compilation_index = 1
        for result in result_per_shrinker.get(shrinker):
            build_status = result.get('build_status')
            if build_status != 'success' and build_status is not None:
                app_error = True
                warn('  {}-#{}: {}'.format(shrinker, compilation_index,
                                           build_status))
                continue

            if options.golem:
                print_thread(
                    '%s(RunTimeRaw): %s ms' %
                    (app.name, result.get('duration')), worker_id)
                print_thread(
                    '%s(CodeSize): %s' % (app.name, result.get('dex_size')),
                    worker_id)
                continue

            print_thread('  {}-#{}:'.format(shrinker, compilation_index),
                         worker_id)
            dex_size = result.get('dex_size')
            msg = '    dex size: {}'.format(dex_size)
            if options.print_runtimeraw:
                print_thread(
                    '    run time raw: {} ms'.format(result.get('duration')),
                    worker_id)
            if dex_size != proguard_dex_size and proguard_dex_size >= 0:
                msg = '{} ({}, {})'.format(
                    msg, dex_size - proguard_dex_size,
                    percentage_diff_as_string(proguard_dex_size, dex_size))
                success(msg) if dex_size < proguard_dex_size else warn(msg)
            else:
                print_thread(msg, worker_id)

            if options.monkey:
                monkey_status = result.get('monkey_status')
                if monkey_status != 'success':
                    app_error = True
                    warn('    monkey: {}'.format(monkey_status))
                else:
                    success('    monkey: {}'.format(monkey_status))

            if options.run_tests and 'instrumentation_test_status' in result:
                test_status = result.get('instrumentation_test_status')
                if test_status != 'success':
                    warn('    instrumentation_tests: {}'.format(test_status))
                else:
                    success('    instrumentation_tests: {}'.format(test_status))

            recompilation_status = result.get('recompilation_status', '')
            if recompilation_status == 'failed':
                app_error = True
                warn('    recompilation {}-#{}: failed'.format(
                    shrinker, compilation_index))
                continue

            compilation_index += 1

    return app_error


def parse_options(argv):
    result = argparse.ArgumentParser(description='Run/compile dump artifacts.')
    result.add_argument('--app',
                        help='What app to run on',
                        choices=[app.name for app in APPS],
                        action='append')
    result.add_argument(
        '--app-collection',
        '--app_collection',
        help='What app collection to run',
        choices=[collection.name for collection in APP_COLLECTIONS],
        action='append')
    result.add_argument('--app-logging-filter',
                        '--app_logging_filter',
                        help='The apps for which to turn on logging',
                        action='append')
    result.add_argument('--bot',
                        help='Running on bot, use third_party dependency.',
                        default=False,
                        action='store_true')
    result.add_argument('--generate-golem-config',
                        '--generate_golem_config',
                        help='Generate a new config for golem.',
                        default=False,
                        action='store_true')
    result.add_argument('--debug-agent',
                        help='Enable Java debug agent and suspend compilation '
                        '(default disabled)',
                        default=False,
                        action='store_true')
    result.add_argument(
        '--disable-assertions',
        '--disable_assertions',
        '-da',
        help='Disable Java assertions when running the compiler '
        '(default enabled)',
        default=False,
        action='store_true')
    result.add_argument(
        '--dump-input-to-directory',
        '--dump_input_to_directory',
        help='Dump all compilations to directory',
        default=None)
    result.add_argument('--emulator-id',
                        '--emulator_id',
                        help='Id of the emulator to use',
                        default='emulator-5554')
    result.add_argument('--golem',
                        help='Running on golem, do not download',
                        default=False,
                        action='store_true')
    result.add_argument('--hash', help='The commit of R8 to use')
    result.add_argument(
        '--internal',
        help='Run internal apps if set, otherwise run opensource',
        default=False,
        action='store_true')
    result.add_argument('--keystore',
                        help='Path to app.keystore',
                        default=os.path.join(utils.TOOLS_DIR, 'debug.keystore'))
    result.add_argument('--keystore-password',
                        '--keystore_password',
                        help='Password for app.keystore',
                        default='android')
    result.add_argument('--minify',
                        help='Force enable/disable minification' +
                        ' (defaults to app proguard config)',
                        choices=['default', 'force-enable', 'force-disable'],
                        default='default')
    result.add_argument('--monkey',
                        help='Whether to install and run app(s) with monkey',
                        default=False,
                        action='store_true')
    result.add_argument('--monkey-events',
                        '--monkey_events',
                        help='Number of events that the monkey should trigger',
                        default=250,
                        type=int)
    result.add_argument('--no-build',
                        '--no_build',
                        help='Run without building first (only when using ToT)',
                        default=False,
                        action='store_true')
    result.add_argument('--no-logging',
                        '--no_logging',
                        help='Disable logging except for errors',
                        default=False,
                        action='store_true')
    result.add_argument('--optimize',
                        help='Force enable/disable optimizations' +
                        ' (defaults to app proguard config)',
                        choices=['default', 'force-enable', 'force-disable'],
                        default='default')
    result.add_argument('--print-times',
                        help='Print timing information from r8',
                        default=False,
                        action='store_true')
    result.add_argument('--print-dexsegments',
                        metavar='BENCHMARKNAME',
                        help='Print the sizes of individual dex segments as ' +
                        '\'<BENCHMARKNAME>-<APP>-<segment>(CodeSize): '
                        '<bytes>\'')
    result.add_argument('--print-runtimeraw',
                        metavar='BENCHMARKNAME',
                        help='Print the line \'<BENCHMARKNAME>(RunTimeRaw):' +
                        ' <elapsed> ms\' at the end where <elapsed> is' +
                        ' the elapsed time in milliseconds.')
    result.add_argument('--quiet',
                        help='Disable verbose logging',
                        default=False,
                        action='store_true')
    result.add_argument('--r8-compilation-steps',
                        '--r8_compilation_steps',
                        help='Number of times R8 should be run on each app',
                        default=2,
                        type=int)
    result.add_argument('--r8-flags',
                        '--r8_flags',
                        help='Additional option(s) for the compiler.')
    result.add_argument('--run-tests',
                        '--run_tests',
                        help='Whether to run instrumentation tests',
                        default=False,
                        action='store_true')
    result.add_argument('--shrink',
                        help='Force enable/disable shrinking' +
                        ' (defaults to app proguard config)',
                        choices=['default', 'force-enable', 'force-disable'],
                        default='default')
    result.add_argument('--sign-apks',
                        '--sign_apks',
                        help='Whether the APKs should be signed',
                        default=False,
                        action='store_true')
    result.add_argument('--shrinker',
                        help='The shrinkers to use (by default, all are run)',
                        action='append')
    result.add_argument('--temp',
                        help='A directory to use for temporaries and outputs.',
                        default=None)
    result.add_argument('--version',
                        default='main',
                        help='The version of R8 to use (e.g., 1.4.51)')
    result.add_argument('--workers',
                        help='Number of workers to use',
                        default=1,
                        type=int)
    (options, args) = result.parse_known_args(argv)

    if options.app or options.app_collection:
        if not options.app:
            options.app = []
        if not options.app_collection:
            options.app_collection = []
        options.apps = [
            app for app in APPS if app.name in options.app or any(
                collection in options.app_collection
                for collection in app.collections)
        ]
        del options.app
        del options.app_collection
    else:
        options.apps = [app for app in APPS if app.internal == options.internal]

    if options.app_logging_filter:
        for app_name in options.app_logging_filter:
            assert any(app.name == app_name for app in options.apps)
    if options.shrinker:
        for shrinker in options.shrinker:
            assert shrinker in SHRINKERS, ('Shrinker must be one of %s' %
                                           ', '.join(SHRINKERS))
    else:
        options.shrinker = [shrinker for shrinker in SHRINKERS]

    if options.hash or version_is_built_jar(options.version):
        # No need to build R8 if a specific version should be used.
        options.no_build = True
        if 'r8-nolib' in options.shrinker:
            warn('Skipping shrinker r8-nolib because a specific version ' +
                 'of r8 was specified')
            options.shrinker.remove('r8-nolib')
        if 'r8-nolib-full' in options.shrinker:
            warn('Skipping shrinker r8-nolib-full because a specific version ' +
                 'of r8 was specified')
            options.shrinker.remove('r8-nolib-full')
    return (options, args)


def print_indented(s, indent):
    print(' ' * indent + s)


def get_sha256(gz_file):
    with open(gz_file, 'rb') as f:
        bytes = f.read()  # read entire file as bytes
        return hashlib.sha256(bytes).hexdigest()


def get_sha_from_file(sha_file):
    with open(sha_file, 'r') as f:
        return f.readlines()[0]


def print_golem_config(options):
    print('// AUTOGENERATED FILE from tools/run_on_app_dump.py in R8 repo')
    print('part of r8_config;')
    print('')
    print('final Suite dumpsSuite = Suite("OpenSourceAppDumps");')
    print('')
    print('createOpenSourceAppBenchmarks() {')
    print_indented('final cpus = ["Lenovo M90"];', 2)
    print_indented('final targetsCompat = ["R8"];', 2)
    print_indented('final targetsFull = ["R8-full-minify-optimize-shrink"];', 2)
    # Avoid calculating this for every app
    jdk_gz = jdk.GetJdkHome() + '.tar.gz'
    add_golem_resource(2, jdk_gz, 'openjdk')
    for app in options.apps:
        if app.folder and not app.internal:
            indentation = 2
            print_indented('{', indentation)
            indentation = 4
            print_indented('final name = "%s";' % app.name, indentation)
            print_indented('final benchmark =', indentation)
            print_indented(
                'StandardBenchmark(name, [Metric.RunTimeRaw, Metric.CodeSize]);',
                indentation + 4)
            if app.golem_duration != None:
                print_indented(
                    'final timeout = const Duration(seconds: %s);' %
                    app.golem_duration, indentation)
                print_indented(
                    'ExecutionManagement.addTimeoutConstraint'
                    '(timeout, benchmark: benchmark);', indentation)
            app_gz = os.path.join(utils.OPENSOURCE_DUMPS_DIR,
                                  app.folder + '.tar.gz')
            name = 'appResource'
            add_golem_resource(indentation, app_gz, name)
            print_golem_config_target('Compat', 'r8', app, indentation)
            print_golem_config_target('Full',
                                      'r8-full',
                                      app,
                                      indentation,
                                      minify='force-enable',
                                      optimize='force-enable',
                                      shrink='force-enable')
            print_indented('dumpsSuite.addBenchmark(name);', indentation)
            indentation = 2
            print_indented('}', indentation)
    print('}')


def print_golem_config_target(target,
                              shrinker,
                              app,
                              indentation,
                              minify='default',
                              optimize='default',
                              shrink='default'):
    options = "options" + target
    print_indented(
        'final %s = benchmark.addTargets(noImplementation, targets%s);' %
        (options, target), indentation)
    print_indented('%s.cpus = cpus;' % options, indentation)
    print_indented('%s.isScript = true;' % options, indentation)
    print_indented('%s.fromRevision = 9700;' % options, indentation)
    print_indented('%s.mainFile = "tools/run_on_app_dump.py "' % options,
                   indentation)
    print_indented(
        '"--golem --disable-assertions --quiet --shrinker %s --app %s "' %
        (shrinker, app.name), indentation + 4)
    print_indented(
        '"--minify %s --optimize %s --shrink %s";' % (minify, optimize, shrink),
        indentation + 4)
    print_indented('%s.resources.add(appResource);' % options, indentation)
    print_indented('%s.resources.add(openjdk);' % options, indentation)


def add_golem_resource(indentation, gz, name, sha256=None):
    sha = gz + '.sha1'
    if not sha256:
        # Golem uses a sha256 of the file in the cache, and you need to specify that.
        download_sha(sha, False, quiet=True)
        sha256 = get_sha256(gz)
    sha = get_sha_from_file(sha)
    print_indented('final %s = BenchmarkResource("",' % name, indentation)
    print_indented('type: BenchmarkResourceType.storage,', indentation + 4)
    print_indented('uri: "gs://r8-deps/%s",' % sha, indentation + 4)
    # Make dart formatter happy.
    if indentation > 2:
        print_indented('hash:', indentation + 4)
        print_indented('"%s",' % sha256, indentation + 8)
    else:
        print_indented('hash: "%s",' % sha256, indentation + 4)
    print_indented('extract: "gz");', indentation + 4)


def main(argv):
    (options, args) = parse_options(argv)

    if options.bot:
        options.no_logging = True
        options.shrinker = ['r8', 'r8-full']
        print(options.shrinker)

    if options.golem:
        options.disable_assertions = True
        options.no_build = True
        options.r8_compilation_steps = 1
        options.quiet = True
        options.no_logging = True

    if options.generate_golem_config:
        print_golem_config(options)
        return 0

    with utils.TempDir() as temp_dir:
        if options.temp:
            temp_dir = options.temp
            os.makedirs(temp_dir, exist_ok=True)
        if options.hash:
            # Download r8-<hash>.jar from
            # https://storage.googleapis.com/r8-releases/raw/.
            target = 'r8-{}.jar'.format(options.hash)
            update_prebuilds_in_android.download_hash(
                temp_dir, 'com/android/tools/r8/' + options.hash, target)
            as_utils.MoveFile(os.path.join(temp_dir, target),
                              os.path.join(temp_dir, 'r8lib.jar'),
                              quiet=options.quiet)
        elif version_is_built_jar(options.version):
            # Download r8-<version>.jar from
            # https://storage.googleapis.com/r8-releases/raw/.
            target = 'r8-{}.jar'.format(options.version)
            update_prebuilds_in_android.download_version(
                temp_dir, 'com/android/tools/r8/' + options.version, target)
            as_utils.MoveFile(os.path.join(temp_dir, target),
                              os.path.join(temp_dir, 'r8lib.jar'),
                              quiet=options.quiet)
        elif options.version == 'main':
            if not options.no_build:
                gradle.RunGradle([
                    utils.GRADLE_TASK_R8,
                    '-Pno_internal'
                ])
                build_r8lib = False
                for shrinker in options.shrinker:
                    if is_minified_r8(shrinker):
                        build_r8lib = True
                if build_r8lib:
                    gradle.RunGradle([utils.GRADLE_TASK_R8LIB, '-Pno_internal'])
            # Make a copy of r8.jar and r8lib.jar such that they stay the same for
            # the entire execution of this script.
            if 'r8-nolib' in options.shrinker or 'r8-nolib-full' in options.shrinker:
                assert os.path.isfile(
                    utils.R8_JAR), 'Cannot build without r8.jar'
                shutil.copyfile(utils.R8_JAR, os.path.join(temp_dir, 'r8.jar'))
            if 'r8' in options.shrinker or 'r8-full' in options.shrinker:
                assert os.path.isfile(
                    utils.R8LIB_JAR), 'Cannot build without r8lib.jar'
                shutil.copyfile(utils.R8LIB_JAR,
                                os.path.join(temp_dir, 'r8lib.jar'))

        jobs = []
        result_per_shrinker_per_app = []
        for app in options.apps:
            if app.skip:
                continue
            result = {}
            result_per_shrinker_per_app.append((app, result))
            jobs.append(create_job(app, options, result, temp_dir))
        thread_utils.run_in_parallel(jobs,
                                     number_of_workers=options.workers,
                                     stop_on_first_failure=False)
        errors = log_results_for_apps(result_per_shrinker_per_app, options)
        if errors > 0:
            dest = 'gs://r8-test-results/r8-libs/' + str(int(time.time()))
            utils.upload_file_to_cloud_storage(
                os.path.join(temp_dir, 'r8lib.jar'), dest)
            print('R8lib saved to %s' % dest)
        return errors


def create_job(app, options, result, temp_dir):
    return lambda worker_id: run_job(app, options, result, temp_dir, worker_id)


def run_job(app, options, result, temp_dir, worker_id):
    job_temp_dir = os.path.join(temp_dir, str(worker_id or 0))
    os.makedirs(job_temp_dir, exist_ok=True)
    result.update(get_results_for_app(app, options, job_temp_dir, worker_id))
    return 0


def success(message):
    CGREEN = '\033[32m'
    CEND = '\033[0m'
    print(CGREEN + message + CEND)


def warn(message):
    CRED = '\033[91m'
    CEND = '\033[0m'
    print(CRED + message + CEND)


if __name__ == '__main__':
    sys.exit(main(sys.argv[1:]))
