#!/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('--compress-dex',
                        help='Whether the dex should be stored compressed',
                        action='store_true',
                        default=False)
    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')
    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,
            '--no-desugaring', '--release'
        ]
        if options.profile:
            d8_args.extend(['--startup-profile', options.profile])
        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,
                            compress_dex=options.compress_dex)


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