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

'''
Build r8lib.jar using src/main/keep.txt and test that d8_api_usage_sample.jar
works with the minified R8.
'''

import argparse
import gradle
import jdk
import os
import subprocess
import toolhelper
import utils

parser = argparse.ArgumentParser(description=__doc__.strip(),
                                 formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-e', '--exclude_deps', action='store_true',
                    help='Create lib jar without dependencies')
parser.add_argument('-k', '--keep', default=utils.R8LIB_KEEP_RULES,
                    help='Keep rules file for lib')
parser.add_argument('-n', '--no_relocate', action='store_true',
                    help='Create lib jar without relocating libraries')
parser.add_argument('-o', '--out', default=None,
                    help='Output for built library')
parser.add_argument('-t', '--target', default='r8',
                    help='Compile target for library')

API_LEVEL = 26
DEPS_JAR = os.path.join(utils.LIBS, 'deps.jar')
SAMPLE_JAR = os.path.join(utils.REPO_ROOT, 'tests', 'd8_api_usage_sample.jar')

def build_r8lib(target, exclude_deps, no_relocate, keep_rules_path,
    output_path, **kwargs):
  # Clean the build directory to ensure no repackaging of any existing
  # lib or deps.
  gradle.RunGradle(['clean'])
  lib_args = [target]
  deps_args = ['repackageDeps']
  if exclude_deps:
    lib_args.append('-Pexclude_deps')
  if no_relocate:
    lib_args.append('-Plib_no_relocate')
    deps_args.append('-Plib_no_relocate')
  # Produce the r8lib target to be processed later.
  gradle.RunGradle(lib_args)
  target_lib = os.path.join(utils.LIBS, target + '.jar')
  temp_lib = os.path.join(utils.LIBS, target + '_to_process.jar')
  os.rename(target_lib, temp_lib)
  # Produce the dependencies needed for running r8 on lib.jar.
  gradle.RunGradle(deps_args)
  temp_deps = os.path.join(utils.LIBS, target + 'lib_deps.jar')
  os.rename(DEPS_JAR, temp_deps)
  # Produce R8 for compiling lib
  if output_path is None:
    output_path = target + 'lib.jar'
  output_map_path = output_path + '.map'
  toolhelper.run(
      'r8',
      ('--release',
       '--classfile',
       '--lib', utils.RT_JAR,
       '--lib', temp_deps,
       temp_lib,
       '--output', output_path,
       '--pg-conf', keep_rules_path,
       '--pg-map-output', output_map_path),
      **kwargs)
  if exclude_deps:
    return [output_path, temp_deps]
  else:
    return [output_path]


def test_d8sample(paths):
  with utils.TempDir() as path:
    args = [jdk.GetJavaExecutable(),
            '-cp', '%s:%s' % (SAMPLE_JAR, ":".join(paths)),
            'com.android.tools.apiusagesample.D8ApiUsageSample',
            '--output', path,
            '--min-api', str(API_LEVEL),
            '--lib', utils.get_android_jar(API_LEVEL),
            '--classpath', utils.R8_JAR,
            '--main-dex-list', '/dev/null',
            os.path.join(utils.BUILD, 'test/examples/hello.jar')]
    utils.PrintCmd(args)
    subprocess.check_call(args)


def test_r8command(paths):
  with utils.TempDir() as path:
    # SAMPLE_JAR and LIB_JAR should not have any classes in common, since e.g.
    # R8CommandParser should have been minified in LIB_JAR.
    # Just in case R8CommandParser is also present in LIB_JAR, we put
    # SAMPLE_JAR first on the classpath to use its version of R8CommandParser.
    args = [jdk.GetJavaExecutable(),
            '-cp', '%s:%s' % (SAMPLE_JAR, ":".join(paths)),
            'com.android.tools.r8.R8CommandParser',
            '--output', path + "/output.zip",
            '--min-api', str(API_LEVEL),
            '--lib', utils.get_android_jar(API_LEVEL),
            '--main-dex-list', '/dev/null',
            os.path.join(utils.BUILD, 'test/examples/hello.jar')]
    utils.PrintCmd(args)
    subprocess.check_call(args)


def test_r8cfcommand(paths):
  with utils.TempDir() as path:
    # SAMPLE_JAR and LIB_JAR should not have any classes in common, since e.g.
    # R8CommandParser should have been minified in LIB_JAR.
    # Just in case R8CommandParser is also present in LIB_JAR, we put
    # SAMPLE_JAR first on the classpath to use its version of R8CommandParser.
    args = [jdk.GetJavaExecutable(),
            '-cp', '%s:%s' % (SAMPLE_JAR, ":".join(paths)),
            'com.android.tools.r8.R8CommandParser',
            '--classfile',
            '--output', path + "/output.jar",
            '--lib', utils.RT_JAR,
            os.path.join(utils.BUILD, 'test/examples/hello.jar')]
    utils.PrintCmd(args)
    subprocess.check_call(args)


def main():
  # Handle --help
  args = parser.parse_args()
  output_paths = build_r8lib(
      args.target, args.exclude_deps, args.no_relocate, args.keep, args.out)
  if args.target == 'r8':
    gradle.RunGradle(['buildExampleJars'])
    test_r8command(output_paths)
    test_r8cfcommand(output_paths)
  if args.target == 'd8':
    gradle.RunGradle(['buildExampleJars'])
    test_d8sample(output_paths)


if __name__ == '__main__':
  main()
