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

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