#!/usr/bin/env python3
# Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import argparse
import os
import subprocess
import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

import apk_masseur
import apk_utils
import extractmarker
import toolhelper
import utils
import zip_utils

LOWEST_SUPPORTED_MIN_API = 21 # Android L (native multi dex)

def parse_options(argv):
  result = argparse.ArgumentParser(
      description='Relayout a given APK using a startup profile.')
  result.add_argument('--apk',
                      help='Path to the .apk',
                      required=True)
  result.add_argument('--desugared-library',
                      choices=['auto', 'true', 'false'],
                      default='auto',
                      help='Whether the last dex file of the app is desugared '
                           'library')
  result.add_argument('--no-build',
                      action='store_true',
                      default=False,
                      help='To disable building using gradle')
  result.add_argument('--out',
                      help='Destination of resulting apk',
                      required=True)
  result.add_argument('--profile',
                      help='Path to the startup profile',
                      required=True)
  options, args = result.parse_known_args(argv)
  return options, args

def get_dex_to_relayout(options, temp):
  marker = extractmarker.extractmarker(options.apk, build=not options.no_build)
  if '~~L8' not in marker:
    return [options.apk], None
  dex_dir = os.path.join(temp, 'dex')
  dex_predicate = \
      lambda name : name.startswith('classes') and name.endswith('.dex')
  extracted_dex_files = \
      zip_utils.extract_all_that_matches(options.apk, dex_dir, dex_predicate)
  desugared_library_dex = 'classes%s.dex' % len(extracted_dex_files)
  assert desugared_library_dex in extracted_dex_files
  return [
      os.path.join(dex_dir, name) \
          for name in extracted_dex_files if name != desugared_library_dex], \
      os.path.join(dex_dir, desugared_library_dex)

def has_desugared_library_dex(options):
  if options.desugared_library == 'auto':
    marker = extractmarker.extractmarker(
        options.apk, build=not options.no_build)
    return '~~L8' in marker
  return options.desugared_library == 'true'

def main(argv):
  (options, args) = parse_options(argv)
  with utils.TempDir() as temp:
    dex = os.path.join(temp, 'dex.zip')
    d8_args = [
        '--min-api',
        str(max(apk_utils.get_min_api(options.apk), LOWEST_SUPPORTED_MIN_API)),
        '--output', dex,
        '--startup-profile', options.profile,
        '--no-desugaring',
        '--release']
    dex_to_relayout, desugared_library_dex = get_dex_to_relayout(options, temp)
    d8_args.extend(dex_to_relayout)
    toolhelper.run(
        'd8',
        d8_args,
        build=not options.no_build,
        main='com.android.tools.r8.D8')
    if desugared_library_dex is not None:
      dex_files = [name for name in \
          zip_utils.get_names_that_matches(dex, lambda x : True)]
      zip_utils.add_file_to_zip(
          desugared_library_dex, 'classes%s.dex' % str(len(dex_files) + 1), dex)
    apk_masseur.masseur(options.apk, dex=dex, out=options.out)

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