#!/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.

import apk_masseur
import apk_utils
import golem
import gradle
import jdk
import json
import os
import optparse
import shutil
import subprocess
import sys
import time
import utils
import zipfile
from xml.dom import minidom

import as_utils
import update_prebuilds_in_android
import download_all_benchmark_dependencies

SHRINKERS = ['r8', 'r8-full', 'r8-nolib', 'r8-nolib-full', 'pg']
WORKING_DIR = os.path.join(utils.BUILD, 'opensource_apps')

GRADLE_USER_HOME = '.gradle_user_home'

if ('R8_BENCHMARK_DIR' in os.environ
    and os.path.isdir(os.environ['R8_BENCHMARK_DIR'])):
  WORKING_DIR = os.environ['R8_BENCHMARK_DIR']

class Repo(object):
  def __init__(self, fields):
    self.__dict__ = fields

    # If there is only one app in this repository, then give the app the same
    # name as the repository, if it does not already have one.
    if len(self.apps) == 1:
      app = self.apps[0]
      if not app.name:
        app.name = self.name

class App(object):
  def __init__(self, fields):
    module = fields.get('module', 'app')
    defaults = {
      'archives_base_name': module,
      'build_dir': 'build',
      'compile_sdk': None,
      'dir': None,
      'flavor': None,
      'has_instrumentation_tests': False,
      'main_dex_rules': None,
      'module': module,
      'min_sdk': None,
      'name': None,
      'releaseTarget': None,
      'signed_apk_name': None,
      'skip': False
    }
    self.__dict__ = dict(defaults.items() + fields.items())

# For running on Golem all third-party repositories are bundled as an x20-
# dependency and then copied to WORKING_DIR. To update the app-bundle use
# 'run_on_as_app_x20_packager.py'.
# For showing benchmark data, also include the app in appSegmentBenchmarks in
# the file <golem_repo>/config/r8/benchmarks.dart.
APP_REPOSITORIES = [
  # ...
  # Repo({
  #     'name': ...,
  #     'url': ...,
  #     'revision': ...,
  #     'apps': [
  #         {
  #             'id': ...,
  #             'dir': ...,
  #             'module': ... (default app)
  #             'name': ...,
  #             'archives_base_name': ... (default same as module)
  #             'flavor': ... (default no flavor)
  #             'releaseTarget': ... (default <module>:assemble<flavor>Release
  #         },
  #         ...
  #     ]
  # }),
  # ...
  Repo({
      'name': 'android-suite',
      'url': 'https://github.com/christofferqa/android-suite',
      'revision': '46c96f214711cf6cdcb72cc0c94520ef418e3739',
      'apps': [
          App({
              'id': 'com.numix.calculator',
              'dir': 'Calculator',
              'name': 'numix-calculator',
              'has_instrumentation_tests': True
          })
      ]
  }),
  Repo({
      'name': 'AnExplorer',
      'url': 'https://github.com/christofferqa/AnExplorer',
      'revision': '365927477b8eab4052a1882d5e358057ae3dee4d',
      'apps': [
          App({
              'id': 'dev.dworks.apps.anexplorer.pro',
              'flavor': 'googleMobilePro',
              'signed_apk_name': 'AnExplorer-googleMobileProRelease-4.0.3.apk',
              'min_sdk': 17
          })
      ]
  }),
  Repo({
      'name': 'AntennaPod',
      'url': 'https://github.com/christofferqa/AntennaPod.git',
      'revision': '77e94f4783a16abe9cc5b78dc2d2b2b1867d8c06',
      'apps': [
          App({
              'id': 'de.danoeh.antennapod',
              'flavor': 'play',
              'min_sdk': 14,
              'compile_sdk': 26
          })
      ]
  }),
  Repo({
    'name': 'applymapping',
    'url': 'https://github.com/mkj-gram/applymapping',
    'revision': 'e3ae14b8c16fa4718e5dea8f7ad00937701b3c48',
    'apps': [
      App({
        'id': 'com.example.applymapping',
        'has_instrumentation_tests': True
      })
    ]
  }),
  Repo({
      'name': 'apps-android-wikipedia',
      'url': 'https://github.com/christofferqa/apps-android-wikipedia',
      'revision': '686e8aa5682af8e6a905054b935dd2daa57e63ee',
      'apps': [
          App({
              'id': 'org.wikipedia',
              'flavor': 'prod',
              'signed_apk_name': 'app-prod-universal-release.apk'
          })
      ]
  }),
  Repo({
      'name': 'chanu',
      'url': 'https://github.com/mkj-gram/chanu.git',
      'revision': '6e53458f167b6d78398da60c20fd0da01a232617',
      'apps': [
          App({
              'id': 'com.chanapps.four.activity'
          })
      ]
  }),
  Repo({
      'name': 'friendlyeats-android',
      'url': 'https://github.com/christofferqa/friendlyeats-android.git',
      'revision': '10091fa0ec37da12e66286559ad1b6098976b07b',
      'apps': [
          App({
              'id': 'com.google.firebase.example.fireeats'
          })
      ]
  }),
  Repo({
      'name': 'googlesamples',
      'url': 'https://github.com/christofferqa/android-sunflower.git',
      'revision': 'df0a082a0bcbeae253817e13daca3c7a7c54f67a',
      'apps': [
          App({
              'id': 'com.google.samples.apps.sunflower',
              'name': 'android-sunflower',
              'min_sdk': 19,
              'compile_sdk': 28
          })
      ]
  }),
  Repo({
      'name': 'Instabug-Android',
      'url': 'https://github.com/christofferqa/Instabug-Android.git',
      'revision': 'b8df78c96630a6537fbc07787b4990afc030cc0f',
      'apps': [
          App({
             'id': 'com.example.instabug'
          })
      ]
  }),
  Repo({
      'name': 'iosched',
      'url': 'https://github.com/christofferqa/iosched.git',
      'revision': '581cbbe2253711775dbccb753cdb53e7e506cb02',
      'apps': [
          App({
              'id': 'com.google.samples.apps.iosched',
              'module': 'mobile',
              'min_sdk': 21,
              'compile_sdk': 29
          })
      ]
  }),
  Repo({
      'name': 'KISS',
      'url': 'https://github.com/christofferqa/KISS',
      'revision': '093da9ee0512e67192f62951c45a07a616fc3224',
      'apps': [
          App({
              'id': 'fr.neamar.kiss'
          })
      ]
  }),
  Repo({
      'name': 'materialistic',
      'url': 'https://github.com/christofferqa/materialistic',
      'revision': '2b2b2ee25ce9e672d5aab1dc90a354af1522b1d9',
      'apps': [
          App({
              'id': 'io.github.hidroh.materialistic'
          })
      ]
  }),
  Repo({
      'name': 'Minimal-Todo',
      'url': 'https://github.com/christofferqa/Minimal-Todo',
      'revision': '9d8c73746762cd376b718858ec1e8783ca07ba7c',
      'apps': [
          App({
              'id': 'com.avjindersinghsekhon.minimaltodo'
          })
      ]
  }),
  Repo({
      'name': 'muzei',
      'url': 'https://github.com/sgjesse/muzei.git',
      'revision': 'a1f1d9b119faa0db09b6bbffe2318c4ec3679418',
      'apps': [
          App({
              'id': 'net.nurik.roman.muzei',
              'module': 'main',
              'archives_base_name': 'muzei',
              'compile_sdk': 28,
          })
      ]
  }),
  Repo({
      'name': 'NewPipe',
      'url': 'https://github.com/christofferqa/NewPipe',
      'revision': 'ed543099c7823be00f15d9340f94bdb7cb37d1e6',
      'apps': [
          App({
              'id': 'org.schabi.newpipe'
          })
      ]
  }),
  Repo({
      'name': 'rover-android',
      'url': 'https://github.com/mkj-gram/rover-android.git',
      'revision': 'a5e155a1ed7d19b1cecd9a7b075e2852623a06bf',
      'apps': [
          App({
              'id': 'io.rover.app.debug',
              'module': 'debug-app'
          })
      ]
  }),
  Repo({
      'name': 'santa-tracker-android',
      'url': 'https://github.com/christofferqa/santa-tracker-android.git',
      'revision': '8dee74be7d9ee33c69465a07088c53087d24a6dd',
      'apps': [
          App({
              'id': 'com.google.android.apps.santatracker',
              'module': 'santa-tracker',
              'min_sdk': 21,
              'compile_sdk': 28
          })
      ]
  }),
  Repo({
      'name': 'Signal-Android',
      'url': 'https://github.com/mkj-gram/Signal-Android.git',
      'revision': 'cd542cab9bf860e71504ecb1caaf0a8476ba3989',
      'apps': [
          App({
              'id': 'org.thoughtcrime.securesms',
              'module': '',
              'flavor': 'play',
              'main_dex_rules': 'multidex-config.pro',
              'signed_apk_name': 'Signal-play-release-4.32.7.apk'
          })
      ]
  }),
  Repo({
      'name': 'Simple-Calendar',
      'url': 'https://github.com/christofferqa/Simple-Calendar',
      'revision': '82dad8c203eea5a0f0ddb513506d8f1de986ef2b',
      'apps': [
          App({
              'id': 'com.simplemobiletools.calendar.pro',
              'signed_apk_name': 'calendar-release.apk'
          })
      ]
  }),
  Repo({
      'name': 'Simple-Camera',
      'url': 'https://github.com/jsjeon/Simple-Camera',
      'revision': '451fe188ab123e6956413b42e89839b44c05ac14',
      'apps': [
          App({
              'id': 'com.simplemobiletools.camera.pro',
              'signed_apk_name': 'camera-release.apk'
          })
      ]
  }),
  Repo({
      'name': 'Simple-File-Manager',
      'url': 'https://github.com/jsjeon/Simple-File-Manager',
      'revision': '282b57d9e73f4d250cc844d8d73fd223509a141e',
      'apps': [
          App({
              'id': 'com.simplemobiletools.filemanager.pro',
              'signed_apk_name': 'file-manager-release.apk'
          })
      ]
  }),
  Repo({
      'name': 'Simple-Gallery',
      'url': 'https://github.com/jsjeon/Simple-Gallery',
      'revision': '679125601eee7e057dfdfecd7bea6c4a6ac73ef9',
      'apps': [
          App({
              'id': 'com.simplemobiletools.gallery.pro',
              'signed_apk_name': 'gallery-release.apk'
          })
      ]
  }),
  Repo({
      'name': 'sqldelight',
      'url': 'https://github.com/christofferqa/sqldelight.git',
      'revision': '2e67a1126b6df05e4119d1e3a432fde51d76cdc8',
      'apps': [
          App({
              'id': 'com.example.sqldelight.hockey',
              'module': 'sample/android',
              'archives_base_name': 'android',
              'min_sdk': 14,
              'compile_sdk': 28
          })
      ]
  }),
  Repo({
      'name': 'tachiyomi',
      'url': 'https://github.com/sgjesse/tachiyomi.git',
      'revision': 'b15d2fe16864645055af6a745a62cc5566629798',
      'apps': [
          App({
              'id': 'eu.kanade.tachiyomi',
              'flavor': 'dev',
              'min_sdk': 16
          })
      ]
  }),
  Repo({
      'name': 'tivi',
      'url': 'https://github.com/sgjesse/tivi.git',
      'revision': '25c52e3593e7c98da4e537b49b29f6f67f88754d',
      'apps': [
          App({
              'id': 'app.tivi',
              'min_sdk': 23,
              'compile_sdk': 28,
          })
      ]
  }),
  Repo({
      'name': 'Tusky',
      'url': 'https://github.com/mkj-gram/Tusky.git',
      'revision': 'e7fbd190fb53bf9fde72253b816920cb6fe34518',
      'apps': [
          App({
              'id': 'com.keylesspalace.tusky',
              'flavor': 'blue'
          })
      ]
  }),
  Repo({
      'name': 'Vungle-Android-SDK',
      'url': 'https://github.com/mkj-gram/Vungle-Android-SDK.git',
      'revision': '138d3f18c027b61b195c98911f1c5ab7d87ad18b',
      'apps': [
          App({
              'id': 'com.publisher.vungle.sample'
          })
      ]
  })
]

def GetAllApps():
  apps = []
  for repo in APP_REPOSITORIES:
    for app in repo.apps:
      apps.append((app, repo))
  return apps

def GetAllAppNames():
  return [app.name for (app, repo) in GetAllApps()]

def GetAppWithName(query):
  for (app, repo) in GetAllApps():
    if app.name == query:
      return (app, repo)
  assert False

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

def ExtractMarker(apk, temp_dir, options):
  r8_jar = os.path.join(temp_dir, 'r8.jar')
  r8lib_jar = os.path.join(temp_dir, 'r8lib.jar')

  # Use the copy of r8.jar or r8lib.jar if one is there.
  if os.path.isfile(r8_jar):
    cmd = [jdk.GetJavaExecutable(), '-ea', '-jar', r8_jar, 'extractmarker', apk]
  elif os.path.isfile(r8lib_jar):
    cmd = [jdk.GetJavaExecutable(), '-ea', '-cp', r8lib_jar,
        'com.android.tools.r8.ExtractMarker', apk]
  else:
    script = os.path.join(utils.TOOLS_DIR, 'extractmarker.py')
    cmd = ['python', script, apk]

  utils.PrintCmd(cmd, quiet=options.quiet)
  stdout = subprocess.check_output(cmd)

  # Return the last line.
  lines = stdout.strip().splitlines()
  assert len(lines) >= 1
  return lines[-1]

def CheckIsBuiltWithExpectedR8(apk, temp_dir, shrinker, options):
  marker_raw = ExtractMarker(apk, temp_dir, options)

  # Marker should be a string on the following format (no whitespace):
  #   ~~R8{"compilation-mode":"release",
  #        "min-api":16,
  #        "pg-map-id":"767707e",
  #        "sha-1":"7111a35bae6d5185dcfb338d61074aca8426c006",
  #        "version":"1.5.14-dev"}
  if not marker_raw.startswith('~~R8'):
    raise Exception(
        'Expected marker to start with \'~~R8\' (was: {})'.format(marker_raw))

  marker = json.loads(marker_raw[4:])

  if options.hash:
    actual_hash = marker.get('sha-1')
    if actual_hash != options.hash:
      raise Exception(
          'Expected APK to be built with R8 version {} (was: {})'.format(
              expected_hash, marker_raw))
    return True

  expected_version = (
      options.version
      if options.version
      else utils.getR8Version(
          os.path.join(
              temp_dir,
              'r8lib.jar' if IsMinifiedR8(shrinker) else 'r8.jar')))
  actual_version = marker.get('version')
  if actual_version != expected_version:
    raise Exception(
        'Expected APK to be built with R8 version {} (was: {})'.format(
            expected_version, marker_raw))
  return True

def IsR8(shrinker):
  return 'r8' in shrinker

def IsR8FullMode(shrinker):
  return shrinker == 'r8-full' or shrinker == 'r8-nolib-full'

def IsLoggingEnabledFor(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 IsMinifiedR8(shrinker):
  return 'nolib' not in shrinker

def IsTrackedByGit(file):
  return subprocess.check_output(['git', 'ls-files', file]).strip() != ''

def GitClone(repo, checkout_dir, quiet):
  result = subprocess.check_output(
      ['git', 'clone', repo.url, checkout_dir]).strip()
  head_rev = utils.get_HEAD_sha1_for_checkout(checkout_dir)
  if repo.revision == head_rev:
    return result
  warn('Target revision is not head in {}.'.format(checkout_dir))
  with utils.ChangedWorkingDirectory(checkout_dir, quiet=quiet):
    subprocess.check_output(['git', 'reset', '--hard', repo.revision])
  return result

def GitCheckout(file):
  return subprocess.check_output(['git', 'checkout', file]).strip()

def InstallApkOnEmulator(apk_dest, options):
  cmd = ['adb', '-s', options.emulator_id, 'install', '-r', '-d', apk_dest]
  if options.quiet:
    with open(os.devnull, 'w') as devnull:
      subprocess.check_call(cmd, stdout=devnull)
  else:
    subprocess.check_call(cmd)

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

def UninstallApkOnEmulator(app, options):
  process = subprocess.Popen(
      ['adb', '-s', options.emulator_id, 'uninstall', app.id],
      stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  stdout, stderr = process.communicate()

  if stdout.strip() == 'Success':
    # Successfully uninstalled
    return

  if 'Unknown package: {}'.format(app.id) in stderr:
    # Application not installed
    return

  raise Exception(
      'Unexpected result from `adb uninstall {}\nStdout: {}\nStderr: {}'.format(
          app.id, stdout, stderr))

def WaitForEmulator(options):
  stdout = subprocess.check_output(['adb', 'devices'])
  if '{}\tdevice'.format(options.emulator_id) in stdout:
    return True

  print('Emulator \'{}\' not connected; waiting for connection'.format(
      options.emulator_id))

  time_waited = 0
  while True:
    time.sleep(10)
    time_waited += 10
    stdout = subprocess.check_output(['adb', 'devices'])
    if '{}\tdevice'.format(options.emulator_id) not in stdout:
      print('... still waiting for connection')
      if time_waited >= 5 * 60:
        return False
    else:
      return True

def GetResultsForApp(app, repo, options, temp_dir):
  # Checkout and build in the build directory.
  repo_name = repo.name
  repo_checkout_dir = os.path.join(WORKING_DIR, repo_name)

  result = {}

  if not os.path.exists(repo_checkout_dir) and not options.golem:
    with utils.ChangedWorkingDirectory(WORKING_DIR, quiet=options.quiet):
      GitClone(repo, repo_checkout_dir, options.quiet)

  checkout_rev = utils.get_HEAD_sha1_for_checkout(repo_checkout_dir)
  if repo.revision != checkout_rev:
    msg = 'Checkout is not target revision for {} in {}.'.format(
        app.name, repo_checkout_dir)
    if options.ignore_versions:
      warn(msg)
    else:
      raise Exception(msg)

  result['status'] = 'success'

  app_checkout_dir = (os.path.join(repo_checkout_dir, app.dir)
                      if app.dir else repo_checkout_dir)

  result_per_shrinker = BuildAppWithSelectedShrinkers(
      app, repo, options, app_checkout_dir, temp_dir)
  for shrinker, shrinker_result in result_per_shrinker.iteritems():
    result[shrinker] = shrinker_result

  return result

def BuildAppWithSelectedShrinkers(
    app, repo, options, checkout_dir, temp_dir):
  result_per_shrinker = {}

  with utils.ChangedWorkingDirectory(checkout_dir, quiet=options.quiet):
    for shrinker in options.shrinker:
      apk_dest = None

      result = {}
      try:
        out_dir = os.path.join(checkout_dir, 'out', shrinker)
        (apk_dest, profile_dest_dir, proguard_config_file) = \
            BuildAppWithShrinker(
                app, repo, shrinker, checkout_dir, out_dir, temp_dir,
                options)
        dex_size = ComputeSizeOfDexFilesInApk(apk_dest)
        result['apk_dest'] = apk_dest
        result['build_status'] = 'success'
        result['dex_size'] = dex_size
        result['profile_dest_dir'] = profile_dest_dir

        profile = as_utils.ParseProfileReport(profile_dest_dir)
        result['profile'] = {
            task_name:duration for task_name, duration in profile.iteritems()
            if as_utils.IsGradleCompilerTask(task_name, shrinker)}
      except Exception as e:
        warn('Failed to build {} with {}'.format(app.name, shrinker))
        if e:
          print('Error: ' + str(e))
        result['build_status'] = 'failed'

      if result.get('build_status') == 'success':
        if options.monkey:
          result['monkey_status'] = 'success' if RunMonkey(
              app, options, apk_dest) else 'failed'

        if 'r8' in shrinker and options.r8_compilation_steps > 1:
          result['recompilation_results'] = \
              ComputeRecompilationResults(
                  app, repo, options, checkout_dir, temp_dir, shrinker,
                  proguard_config_file)

        if options.run_tests and app.has_instrumentation_tests:
          result['instrumentation_test_results'] = \
              ComputeInstrumentationTestResults(
                  app, options, checkout_dir, out_dir, shrinker)

      result_per_shrinker[shrinker] = result

  if len(options.apps) > 1:
    print('')
    LogResultsForApp(app, result_per_shrinker, options)
    print('')

  return result_per_shrinker

def BuildAppWithShrinker(
    app, repo, shrinker, checkout_dir, out_dir, temp_dir, options,
    keepRuleSynthesisForRecompilation=False):
  print('Building {} with {}{}'.format(
      app.name,
      shrinker,
      ' for recompilation' if keepRuleSynthesisForRecompilation else ''))

  # Add settings.gradle file if it is not present to prevent gradle from finding
  # the settings.gradle file in the r8 root when apps are placed under
  # $R8/build.
  as_utils.add_settings_gradle(checkout_dir, app.name)

  # Add 'r8.jar' to top-level build.gradle.
  as_utils.add_r8_dependency(checkout_dir, temp_dir, IsMinifiedR8(shrinker))

  archives_base_name = app.archives_base_name

  if not os.path.exists(out_dir):
    os.makedirs(out_dir)

  # Set -printconfiguration in Proguard rules.
  proguard_config_dest = os.path.abspath(
      os.path.join(out_dir, 'proguard-rules.pro'))
  as_utils.SetPrintConfigurationDirective(
      app, checkout_dir, proguard_config_dest)

  env_vars = {}
  env_vars['ANDROID_HOME'] = utils.getAndroidHome()
  if not options.disable_assertions:
    env_vars['JAVA_OPTS'] = '-ea:com.android.tools.r8...'

  release_target = app.releaseTarget
  if not release_target:
    release_target = app.module.replace('/', ':') + ':' + 'assemble' + (
        app.flavor.capitalize() if app.flavor else '') + 'Release'

  # Build using gradle.
  args = [release_target,
          '-g=' + os.path.join(checkout_dir, GRADLE_USER_HOME),
          '-Pandroid.enableR8=' + str(IsR8(shrinker)).lower(),
          '-Pandroid.enableR8.fullMode=' + str(IsR8FullMode(shrinker)).lower()]

  # Warm up gradle if pre_runs > 0. For posterity we generate the same sequence
  # as the benchmarking at https://github.com/madsager/santa-tracker-android.
  for i in range(0, options.gradle_pre_runs):
    if i == 0:
      utils.RunGradlew(
          ["--stop"],
          env_vars=env_vars,
          quiet=options.quiet,
          logging=IsLoggingEnabledFor(app, options),
          use_daemon=options.use_daemon)
    utils.RunGradlew(
        args,
        env_vars=env_vars,
        quiet=options.quiet,
        clean=i > 0,
        use_daemon=options.use_daemon,
        logging=IsLoggingEnabledFor(app, options))

  if keepRuleSynthesisForRecompilation:
    args.append('-Dcom.android.tools.r8.keepRuleSynthesisForRecompilation=true')
  if options.gradle_flags:
    args.extend(options.gradle_flags.split(' '))

  args.append('--profile')

  stdout = utils.RunGradlew(
      args,
      env_vars=env_vars,
      quiet=options.quiet,
      use_daemon=options.use_daemon,
      logging=IsLoggingEnabledFor(app, options))

  apk_base_name = (archives_base_name
      + (('-' + app.flavor) if app.flavor else '') + '-release')
  signed_apk_name = (
      app.signed_apk_name
      if app.signed_apk_name
      else apk_base_name + '.apk')
  unsigned_apk_name = apk_base_name + '-unsigned.apk'

  build_dir = os.path.join(app.module, app.build_dir)
  build_output_apks = os.path.join(build_dir, 'outputs', 'apk')
  if app.flavor:
    build_output_apks = os.path.join(build_output_apks, app.flavor, 'release')
  else:
    build_output_apks = os.path.join(build_output_apks, 'release')

  signed_apk = os.path.join(build_output_apks, signed_apk_name)
  unsigned_apk = os.path.join(build_output_apks, unsigned_apk_name)

  assert os.path.isfile(signed_apk) or os.path.isfile(unsigned_apk), (
      "Expected a file to be present at {} or {}, found: {}\n"
      "Standard out from compilation: {}".format(
          signed_apk,
          unsigned_apk,
          ', '.join(
              as_utils.ListFiles(build_dir, lambda x : x.endswith('.apk'))),
          stdout))

  if options.sign_apks and not os.path.isfile(signed_apk):
    assert os.path.isfile(unsigned_apk)
    if options.sign_apks:
      apk_utils.sign_with_apksigner(
          unsigned_apk,
          signed_apk,
          options.keystore,
          options.keystore_password,
          quiet=options.quiet,
          logging=IsLoggingEnabledFor(app, options))

  if os.path.isfile(signed_apk):
    apk_dest = os.path.join(out_dir, signed_apk_name)
    as_utils.MoveFile(signed_apk, apk_dest, quiet=options.quiet)
  else:
    apk_dest = os.path.join(out_dir, unsigned_apk_name)
    as_utils.MoveFile(unsigned_apk, apk_dest, quiet=options.quiet)

  assert ('r8' not in shrinker
      or CheckIsBuiltWithExpectedR8(apk_dest, temp_dir, shrinker, options))

  profile_dest_dir = os.path.join(out_dir, 'profile')
  as_utils.MoveProfileReportTo(profile_dest_dir, stdout, quiet=options.quiet)

  return (apk_dest, profile_dest_dir, proguard_config_dest)

def ComputeInstrumentationTestResults(
    app, options, checkout_dir, out_dir, shrinker):
  args = ['connectedAndroidTest',
         '-Pandroid.enableR8=' + str(IsR8(shrinker)).lower(),
         '-Pandroid.enableR8.fullMode=' + str(IsR8FullMode(shrinker)).lower()]
  env_vars = { 'ANDROID_SERIAL': options.emulator_id }
  stdout = utils.RunGradlew(
      args,
      env_vars=env_vars,
      quiet=options.quiet,
      fail=False,
      logging=IsLoggingEnabledFor(app, options),
      use_daemon=options.use_daemon)

  xml_test_result_dest = os.path.join(out_dir, 'test_result')
  as_utils.MoveXMLTestResultFileTo(
      xml_test_result_dest, stdout, quiet=options.quiet)

  with open(xml_test_result_dest, 'r') as f:
    xml_test_result_contents = f.read()

  xml_document = minidom.parseString(xml_test_result_contents)
  testsuite_element = xml_document.documentElement

  return {
    'xml_test_result_dest': xml_test_result_dest,
    'tests': int(testsuite_element.getAttribute('tests')),
    'failures': int(testsuite_element.getAttribute('failures')),
    'errors': int(testsuite_element.getAttribute('errors')),
    'skipped': int(testsuite_element.getAttribute('skipped'))
  }

def ComputeRecompilationResults(
    app, repo, options, checkout_dir, temp_dir, shrinker, proguard_config_file):
  recompilation_results = []

  # Build app with gradle using -D...keepRuleSynthesisForRecompilation=true.
  out_dir = os.path.join(checkout_dir, 'out', shrinker + '-1')
  (apk_dest, profile_dest_dir, ext_proguard_config_file) = \
      BuildAppWithShrinker(
          app, repo, shrinker, checkout_dir, out_dir,
          temp_dir, options, keepRuleSynthesisForRecompilation=True)
  recompilation_result = {
    'apk_dest': apk_dest,
    'build_status': 'success',
    'dex_size': ComputeSizeOfDexFilesInApk(apk_dest),
    'monkey_status': 'skipped'
  }
  recompilation_results.append(recompilation_result)

  # Sanity check that keep rules have changed.
  with open(ext_proguard_config_file) as new:
    with open(proguard_config_file) as old:
      assert(
          sum(1 for line in new
              if line.strip() and '-printconfiguration' not in line)
          >
          sum(1 for line in old
              if line.strip() and '-printconfiguration' not in line))

  # Extract min-sdk and target-sdk
  (min_sdk, compile_sdk) = \
      as_utils.GetMinAndCompileSdk(app, checkout_dir, apk_dest)

  # Now rebuild generated apk.
  previous_apk = apk_dest

  # We may need main dex rules when re-compiling with R8 as standalone.
  main_dex_rules = None
  if app.main_dex_rules:
    main_dex_rules = os.path.join(checkout_dir, app.main_dex_rules)

  for i in range(1, options.r8_compilation_steps):
    try:
      recompiled_apk_dest = os.path.join(
          checkout_dir, 'out', shrinker, 'app-release-{}.apk'.format(i))
      RebuildAppWithShrinker(
          app, previous_apk, recompiled_apk_dest,
          ext_proguard_config_file, shrinker, min_sdk, compile_sdk,
          options, temp_dir, main_dex_rules)
      recompilation_result = {
        'apk_dest': recompiled_apk_dest,
        'build_status': 'success',
        'dex_size': ComputeSizeOfDexFilesInApk(recompiled_apk_dest)
      }
      if options.monkey:
        recompilation_result['monkey_status'] = 'success' if RunMonkey(
            app, options, recompiled_apk_dest) else 'failed'
      recompilation_results.append(recompilation_result)
      previous_apk = recompiled_apk_dest
    except Exception as e:
      warn('Failed to recompile {} with {}'.format(
          app.name, shrinker))
      recompilation_results.append({ 'build_status': 'failed' })
      break
  return recompilation_results

def RebuildAppWithShrinker(
    app, apk, apk_dest, proguard_config_file, shrinker, min_sdk, compile_sdk,
    options, temp_dir, main_dex_rules):
  assert 'r8' in shrinker
  assert apk_dest.endswith('.apk')

  print('Rebuilding {} with {}'.format(app.name, shrinker))

  # Compile given APK with shrinker to temporary zip file.
  android_jar = utils.get_android_jar(compile_sdk)
  r8_jar = os.path.join(
      temp_dir, 'r8lib.jar' if IsMinifiedR8(shrinker) else 'r8.jar')
  zip_dest = apk_dest[:-4] + '.zip'

  # TODO(christofferqa): Entry point should be CompatProguard if the shrinker
  # is 'r8'.
  entry_point = 'com.android.tools.r8.R8'

  cmd = ([jdk.GetJavaExecutable()] +
         (['-ea:com.android.tools.r8...']
          if not options.disable_assertions
          else []) +
         ['-cp', r8_jar, entry_point,
         '--release', '--min-api', str(min_sdk),
         '--pg-conf', proguard_config_file,
         '--lib', android_jar,
         '--output', zip_dest,
         apk])

  for android_optional_jar in utils.get_android_optional_jars(compile_sdk):
    cmd.append('--lib')
    cmd.append(android_optional_jar)

  if main_dex_rules:
    cmd.append('--main-dex-rules')
    cmd.append(main_dex_rules)

  utils.RunCmd(
    cmd, quiet=options.quiet, logging=IsLoggingEnabledFor(app, options))

  # 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(
      apk, dex=zip_dest, resources='META-INF/services/*', out=apk_dest,
      quiet=options.quiet, logging=IsLoggingEnabledFor(app, options),
      keystore=options.keystore)

def RunMonkey(app, options, apk_dest):
  if not WaitForEmulator(options):
    return False

  UninstallApkOnEmulator(app, options)
  InstallApkOnEmulator(apk_dest, options)

  number_of_events_to_generate = options.monkey_events

  # Intentionally using a constant seed such that the monkey generates the same
  # event sequence for each shrinker.
  random_seed = 42

  cmd = ['adb', '-s', options.emulator_id, 'shell', 'monkey', '-p', app.id,
      '-s', str(random_seed), str(number_of_events_to_generate)]

  try:
    stdout = utils.RunCmd(
        cmd, quiet=options.quiet, logging=IsLoggingEnabledFor(app, options))
    succeeded = (
        'Events injected: {}'.format(number_of_events_to_generate) in stdout)
  except subprocess.CalledProcessError as e:
    succeeded = False

  UninstallApkOnEmulator(app, options)

  return succeeded

def LogResultsForApps(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 LogResultsForApp(app, result_per_shrinker, options)
                   else 0)
  return app_errors

def LogResultsForApp(app, result_per_shrinker, options):
  if options.print_dexsegments:
    LogSegmentsForApp(app, result_per_shrinker, options)
    return False
  else:
    return LogComparisonResultsForApp(app, result_per_shrinker, options)

def LogSegmentsForApp(app, result_per_shrinker, options):
  for shrinker in SHRINKERS:
    if shrinker not in result_per_shrinker:
      continue
    result = result_per_shrinker[shrinker];
    benchmark_name = '{}-{}'.format(options.print_dexsegments, app.name)
    utils.print_dexsegments(benchmark_name, [result.get('apk_dest')])
    duration = sum(result.get('profile').values())
    print('%s-Total(RunTimeRaw): %s ms' % (benchmark_name, duration * 1000))
    print('%s-Total(CodeSize): %s' % (benchmark_name, result.get('dex_size')))


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

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

  for shrinker in SHRINKERS:
    if shrinker not in result_per_shrinker:
      continue
    result = result_per_shrinker.get(shrinker)
    build_status = result.get('build_status')
    if build_status != 'success':
      app_error = True
      warn('  {}: {}'.format(shrinker, build_status))
    else:
      print('  {}:'.format(shrinker))
      dex_size = result.get('dex_size')
      msg = '    dex size: {}'.format(dex_size)
      if dex_size != proguard_dex_size and proguard_dex_size >= 0:
        msg = '{} ({}, {})'.format(
            msg, dex_size - proguard_dex_size,
            PercentageDiffAsString(proguard_dex_size, dex_size))
        success(msg) if dex_size < proguard_dex_size else warn(msg)
      else:
        print(msg)

      profile = result.get('profile')
      duration = sum(profile.values())
      msg = '    performance: {}s'.format(duration)
      if duration != proguard_duration and proguard_duration > 0:
        msg = '{} ({}s, {})'.format(
            msg, duration - proguard_duration,
            PercentageDiffAsString(proguard_duration, duration))
        success(msg) if duration < proguard_duration else warn(msg)
      else:
        print(msg)
      if len(profile) >= 2:
        for task_name, task_duration in profile.iteritems():
          print('      {}: {}s'.format(task_name, task_duration))

      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))

      recompilation_results = result.get('recompilation_results', [])
      i = 0
      for recompilation_result in recompilation_results:
        build_status = recompilation_result.get('build_status')
        if build_status != 'success':
          app_error = True
          print('    recompilation #{}: {}'.format(i, build_status))
        else:
          dex_size = recompilation_result.get('dex_size')
          print('    recompilation #{}'.format(i))
          print('      dex size: {}'.format(dex_size))
          if options.monkey:
            monkey_status = recompilation_result.get('monkey_status')
            msg = '      monkey: {}'.format(monkey_status)
            if monkey_status == 'success':
              success(msg)
            elif monkey_status == 'skipped':
              print(msg)
            else:
              warn(msg)
        i += 1

      if options.run_tests and 'instrumentation_test_results' in result:
        instrumentation_test_results = \
            result.get('instrumentation_test_results')
        succeeded = (
            instrumentation_test_results.get('failures')
                + instrumentation_test_results.get('errors')
                + instrumentation_test_results.get('skipped')) == 0
        if succeeded:
          success('    tests: succeeded')
        else:
          app_error = True
          warn(
              '    tests: failed (failures: {}, errors: {}, skipped: {})'
              .format(
                  instrumentation_test_results.get('failures'),
                  instrumentation_test_results.get('errors'),
                  instrumentation_test_results.get('skipped')))

  return app_error

def ParseOptions(argv):
  result = optparse.OptionParser()
  result.add_option('--app',
                    help='What app to run on',
                    choices=GetAllAppNames(),
                    action='append')
  result.add_option('--bot',
                    help='Running on bot, use third_party dependency.',
                    default=False,
                    action='store_true')
  result.add_option('--disable-assertions', '--disable_assertions',
                    help='Disable assertions when compiling',
                    default=False,
                    action='store_true')
  result.add_option('--download-only', '--download_only',
                    help='Whether to download apps without any compilation',
                    default=False,
                    action='store_true')
  result.add_option('--emulator-id', '--emulator_id',
                    help='Id of the emulator to use',
                    default='emulator-5554')
  result.add_option('--golem',
                    help='Running on golem, do not download',
                    default=False,
                    action='store_true')
  result.add_option('--gradle-flags', '--gradle_flags',
                    help='Flags to pass in to gradle')
  result.add_option('--gradle-pre-runs', '--gradle_pre_runs',
                    help='Do rounds of compilations to warm up gradle',
                    default=0,
                    type=int)
  result.add_option('--hash',
                    help='The version of R8 to use')
  result.add_option('--ignore-versions', '--ignore_versions',
                    help='Allow checked-out app to differ in revision from '
                         'pinned',
                    default=False,
                    action='store_true')
  result.add_option('--keystore',
                    help='Path to app.keystore',
                    default=os.path.join(utils.TOOLS_DIR, 'debug.keystore'))
  result.add_option('--keystore-password', '--keystore_password',
                    help='Password for app.keystore',
                    default='android')
  result.add_option('--app-logging-filter', '--app_logging_filter',
                    help='The apps for which to turn on logging',
                    action='append')
  result.add_option('--monkey',
                    help='Whether to install and run app(s) with monkey',
                    default=False,
                    action='store_true')
  result.add_option('--monkey-events', '--monkey_events',
                    help='Number of events that the monkey should trigger',
                    default=250,
                    type=int)
  result.add_option('--no-build', '--no_build',
                    help='Run without building ToT first (only when using ToT)',
                    default=False,
                    action='store_true')
  result.add_option('--no-logging', '--no_logging',
                    help='Disable logging except for errors',
                    default=False,
                    action='store_true')
  result.add_option('--print-dexsegments',
                    metavar='BENCHMARKNAME',
                    help='Print the sizes of individual dex segments as ' +
                         '\'<BENCHMARKNAME>-<APP>-<segment>(CodeSize): '
                         '<bytes>\'')
  result.add_option('--quiet',
                    help='Disable verbose logging',
                    default=False,
                    action='store_true')
  result.add_option('--r8-compilation-steps', '--r8_compilation_steps',
                    help='Number of times R8 should be run on each app',
                    default=2,
                    type=int)
  result.add_option('--run-tests', '--run_tests',
                    help='Whether to run instrumentation tests',
                    default=False,
                    action='store_true')
  result.add_option('--sign-apks', '--sign_apks',
                    help='Whether the APKs should be signed',
                    default=False,
                    action='store_true')
  result.add_option('--shrinker',
                    help='The shrinkers to use (by default, all are run)',
                    action='append')
  result.add_option('--use-daemon', '--use_daemon',
                    help='Whether to use a gradle daemon',
                    default=False,
                    action='store_true')
  result.add_option('--version',
                    help='The version of R8 to use (e.g., 1.4.51)')
  (options, args) = result.parse_args(argv)
  if options.app:
    options.apps = [(app, repo) for (app, repo) in GetAllApps()
                    if app.name in options.app]
    del options.app
  else:
    options.apps = GetAllApps()
  if options.app_logging_filter:
    for app_name in options.app_logging_filter:
      assert any(app.name == app_name for (app, repo) in options.apps)
  if options.shrinker:
    for shrinker in options.shrinker:
      assert shrinker in SHRINKERS
  else:
    options.shrinker = [shrinker for shrinker in SHRINKERS]
  if options.hash or 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 clone_repositories(quiet):
  # Clone repositories into WORKING_DIR.
  with utils.ChangedWorkingDirectory(WORKING_DIR):
    for repo in APP_REPOSITORIES:
      repo_dir = os.path.join(WORKING_DIR, repo.name)
      if not os.path.exists(repo_dir):
        GitClone(repo, repo_dir, quiet)


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

  if options.bot:
    utils.DownloadFromGoogleCloudStorage(utils.OPENSOURCE_APPS_SHA_FILE)
    utils.DownloadFromGoogleCloudStorage(utils.ANDROID_SDK + '.tar.gz.sha1',
                                         bucket='r8-deps-internal',
                                         auth=True)
    if os.path.exists(WORKING_DIR):
      shutil.rmtree(WORKING_DIR)
    shutil.copytree(utils.OPENSOURCE_APPS_FOLDER, WORKING_DIR)
    os.environ[utils.ANDROID_HOME_ENVIROMENT_NAME] = os.path.join(
        utils.ANDROID_SDK)
    os.environ[utils.ANDROID_TOOLS_VERSION_ENVIRONMENT_NAME] = '28.0.3'
    # TODO(b/141081520): Set to True once fixed.
    options.no_logging = False
    # TODO(b/141081520): Remove logging filter once fixed.
    options.app_logging_filter = ['sqldelight']
    options.shrinker = [shrinker for shrinker in SHRINKERS if shrinker != 'pg']
    print(options.shrinker)

  if options.golem:
    golem.link_third_party()
    if os.path.exists(WORKING_DIR):
      shutil.rmtree(WORKING_DIR)
    shutil.copytree(utils.OPENSOURCE_APPS_FOLDER, WORKING_DIR)
    os.environ[utils.ANDROID_HOME_ENVIROMENT_NAME] = os.path.join(
        utils.ANDROID_SDK)
    os.environ[utils.ANDROID_TOOLS_VERSION_ENVIRONMENT_NAME] = '28.0.3'
    options.disable_assertions = True
    options.ignore_versions = True
    options.no_build = True
    options.r8_compilation_steps = 1
    options.quiet = True
    options.gradle_pre_runs = 2
    options.use_daemon = True
    options.no_logging = True

  if not os.path.exists(WORKING_DIR):
    os.makedirs(WORKING_DIR)

  if options.download_only:
    clone_repositories(options.quiet)
    return

  with utils.TempDir() as temp_dir:
    if not (options.no_build or options.golem):
      gradle.RunGradle(['r8', 'r8lib', '-Pno_internal'])

    if options.hash:
      # Download r8-<hash>.jar from
      # http://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 options.version:
      # Download r8-<version>.jar from
      # http://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)
    else:
      # 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'))

    result_per_shrinker_per_app = []

    for (app, repo) in options.apps:
      if app.skip:
        continue
      result_per_shrinker_per_app.append(
          (app, GetResultsForApp(app, repo, options, temp_dir)))

    return LogResultsForApps(result_per_shrinker_per_app, options)

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:]))
