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

import optparse
import os
import subprocess
import sys

import utils

LINUX_DIR = os.path.join(utils.TOOLS_DIR, 'linux')

LATEST = '12.0.0'

VERSIONS = [
    '12.0.0',
    # TODO(b/258170524): Fix the broken dex2oat versions.
    # 'default',
    # '9.0.0',
    # '8.1.0',
    # '7.0.0',
    '6.0.1',
    # '5.1.1',
]

DIRS = {
    '12.0.0': 'host/art-12.0.0-beta4',
    'default': 'art',
    '9.0.0': 'art-9.0.0',
    '8.1.0': 'art-8.1.0',
    '7.0.0': 'art-7.0.0',
    '6.0.1': 'art-6.0.1',
    '5.1.1': 'art-5.1.1',
}

PRODUCTS = {
    '12.0.0': 'redfin',
    'default': 'angler',
    '9.0.0': 'marlin',
    '8.1.0': 'marlin',
    '7.0.0': 'angler',
    '6.0.1': 'angler',
    '5.1.1': 'mako',
}

ARCHS = {
    '12.0.0': 'x86_64',
    'default': 'arm64',
    '9.0.0': 'arm64',
    '8.1.0': 'arm64',
    '7.0.0': 'arm64',
    '6.0.1': 'arm64',
    '5.1.1': 'arm',
}

VERBOSE_OPTIONS = [
    'verifier',
    'compiler',
    'gc',
    'jit',
    'jni',
    'class',
    'all',
]

BOOT_IMAGE = {'12.0.0': 'apex/art_boot_images/javalib/boot.art'}


def ParseOptions():
    parser = optparse.OptionParser()
    parser.add_option('--version',
                      help='Version of dex2oat. (defaults to latest: ' +
                      LATEST + ').',
                      choices=VERSIONS,
                      default=LATEST)
    parser.add_option(
        '--device',
        help='Run dex2oat on this device (this is passed as the -s SERIAL.')
    parser.add_option('--all',
                      help='Run dex2oat on all possible versions',
                      default=False,
                      action='store_true')
    parser.add_option(
        '--output',
        help=
        'Where to place the output oat (defaults to no output / temp file).',
        default=None)
    parser.add_option('--verbose',
                      help='Enable verbose dex2oat logging.',
                      choices=VERBOSE_OPTIONS,
                      default=None)
    return parser.parse_args()


def Main():
    (options, args) = ParseOptions()
    if len(args) != 1:
        print("Can only take a single dex/zip/jar/apk file as input.")
        return 1
    if (options.device):
        return run_device_dex2oat(options, args)
    else:
        return run_host_dex2oat(options, args)


def run_host_dex2oat(options, args):
    if options.all and options.output:
        print("Can't write output when running all versions.")
        return 1
    dexfile = args[0]
    oatfile = options.output
    versions = VERSIONS if options.all else [options.version]
    for version in versions:
        run(options, dexfile, oatfile, version)
        print("")
    return 0


def adb_cmd(serial, *args):
    cmd = ['adb', '-s', serial]
    cmd.extend(args)
    return cmd


def append_dex2oat_verbose_flags(options, cmd):
    verbose = [options.verbose] if options.verbose else []
    if 'all' in verbose:
        verbose = [x for x in VERBOSE_OPTIONS if x != 'all']
    for flag in verbose:
        cmd += ['--runtime-arg', '-verbose:' + flag]
    return cmd


def run_device_dex2oat(options, args):
    serial = options.device
    dexfile = args[0]
    device_dexfile = '/data/local/tmp/' + os.path.basename(dexfile)
    device_oatfile = '/data/local/tmp/unused.oat'
    cmd = adb_cmd(serial, 'shell', 'rm', '-f', device_dexfile, device_oatfile)
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
    cmd = adb_cmd(serial, 'push', dexfile, device_dexfile)
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
    cmd = adb_cmd(serial, 'logcat', '-c')
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
    cmd = adb_cmd(serial, 'shell', 'dex2oat', '--dex-file=' + device_dexfile,
                  '--oat-file=/data/local/tmp/unused.oat')
    append_dex2oat_verbose_flags(options, cmd)
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
    cmd = adb_cmd(serial, 'logcat', '-d', '-s', 'dex2oat')
    utils.PrintCmd(cmd)
    subprocess.check_call(cmd)
    return 0


def run(options, dexfile, oatfile=None, version=None):
    if not version:
        version = LATEST
    # dex2oat accepts non-existent dex files, check here instead
    if not os.path.exists(dexfile):
        raise Exception('DEX file not found: "{}"'.format(dexfile))
    with utils.TempDir() as temp:
        if not oatfile:
            oatfile = os.path.join(temp, "out.oat")
        base = os.path.join(LINUX_DIR, DIRS[version])
        product = PRODUCTS[version]
        arch = ARCHS[version]
        cmd = [
            os.path.join(base, 'bin', 'dex2oat'),
            '--android-root=' +
            os.path.join(base, 'product', product, 'system'),
            '--runtime-arg',
            '-Xnorelocate',
            '--dex-file=' + dexfile,
            '--oat-file=' + oatfile,
            '--instruction-set=' + arch,
        ]
        append_dex2oat_verbose_flags(options, cmd)
        if version in BOOT_IMAGE:
            cmd += ['--boot-image=' + BOOT_IMAGE[version]]
        env = {"LD_LIBRARY_PATH": os.path.join(base, 'lib')}
        utils.PrintCmd(cmd)
        with utils.ChangedWorkingDirectory(base):
            subprocess.check_call(cmd, env=env)


if __name__ == '__main__':
    sys.exit(Main())
