#!/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.
'''
Run R8 (with the class-file backend) to optimize a command-line program.

Given an input JAR (default: r8.jar) and a main-class, generates a new input JAR
with the given main-class in the manifest along with a -keep rule for keeping
just the main entrypoint, and runs R8 in release+classfile mode on the JAR.

If --benchmark-name NAME is given, prints "<NAME>(RunTimeRaw): <elapsed> ms"
to standard output at the end of the run.
'''

import argparse
import os
import re
import sys
import time
import zipfile

import toolhelper
import utils

KEEP = '-keep public class %s { public static void main(...); }\n'
MANIFEST_PATH = 'META-INF/MANIFEST.MF'
MANIFEST = 'Manifest-Version: 1.0\nMain-Class: %s\n\n'
MANIFEST_PATTERN = r'Main-Class:\s*(\S+)'

parser = argparse.ArgumentParser(description=__doc__.strip(),
                                 formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-i',
                    '--input-jar',
                    default=utils.R8_JAR,
                    help='Input JAR to use (default: build/libs/r8.jar)')
parser.add_argument(
    '-o',
    '--output-jar',
    help='Path to output JAR (default: build/libs/<MainClass>-min.jar)')
parser.add_argument('-l',
                    '--lib',
                    default=utils.RT_JAR,
                    help='Path to rt.jar to use instead of OpenJDK 1.8')
parser.add_argument(
    '-m',
    '--mainclass',
    help='Create/overwrite MANIFEST.MF with the given Main-Class')
parser.add_argument('-O',
                    '--no-debug',
                    dest='debug',
                    action='store_false',
                    help='Disable assertions when running R8')
parser.add_argument('--benchmark-name',
                    help='Print benchmarks with the given name')


def generate_output_name(input_jar, mainclass):
    if not mainclass:
        input_base, input_ext = os.path.splitext(input_jar)
        return '%s-min%s' % (input_base, input_ext)
    base = mainclass[mainclass.rindex('.') +
                     1:] if '.' in mainclass else mainclass
    return os.path.join(utils.LIBS, '%s-min.jar' % base)


def repackage(input_jar, output_jar, mainclass):
    print("Repackaging %s to %s with Main-Class: %s..." %
          (input_jar, output_jar, mainclass))
    manifest = MANIFEST % mainclass
    with zipfile.ZipFile(input_jar, 'r') as input_zf:
        with zipfile.ZipFile(output_jar, 'w') as output_zf:
            for zipinfo in input_zf.infolist():
                if zipinfo.filename.upper() == MANIFEST_PATH:
                    assert manifest is not None
                    output_zf.writestr(MANIFEST_PATH, manifest)
                    manifest = None
                else:
                    output_zf.writestr(zipinfo, input_zf.read(zipinfo))
            if manifest is not None:
                output_zf.writestr(MANIFEST_PATH, manifest)


def extract_mainclass(input_jar):
    with zipfile.ZipFile(input_jar, 'r') as input_zf:
        try:
            manifest = input_zf.getinfo(MANIFEST_PATH)
        except KeyError:
            raise SystemExit(
                'No --mainclass specified and no manifest in input JAR.')
        mo = re.search(MANIFEST_PATTERN, input_zf.read(manifest))
        if not mo:
            raise SystemExit(
                'No --mainclass specified and no Main-Class in input JAR manifest.'
            )
        return mo.group(1)


def minify_tool(mainclass=None,
                input_jar=utils.R8_JAR,
                output_jar=None,
                lib=utils.RT_JAR,
                debug=True,
                build=True,
                benchmark_name=None,
                track_memory_file=None,
                additional_args=[],
                java_args=[]):
    if output_jar is None:
        output_jar = generate_output_name(input_jar, mainclass)
    with utils.TempDir() as path:
        if mainclass:
            tmp_input_path = os.path.join(path, 'input.jar')
            repackage(input_jar, tmp_input_path, mainclass)
        else:
            tmp_input_path = input_jar
            mainclass = extract_mainclass(input_jar)
        keep_path = os.path.join(path, 'keep.txt')
        with open(keep_path, 'w') as fp:
            fp.write(KEEP % mainclass)
        args = [
            '--lib', lib, '--classfile', '--output', output_jar, '--pg-conf',
            keep_path, '--release', tmp_input_path
        ] + additional_args
        start_time = time.time()
        return_code = toolhelper.run('r8',
                                     args,
                                     debug=debug,
                                     build=build,
                                     track_memory_file=track_memory_file,
                                     extra_args=java_args)
        if benchmark_name:
            elapsed_ms = 1000 * (time.time() - start_time)
            print('%s(RunTimeRaw): %s ms' % (benchmark_name, elapsed_ms))
            if track_memory_file:
                print('%s(MemoryUse): %s' %
                      (benchmark_name, utils.grep_memoryuse(track_memory_file)))

        return return_code


if __name__ == '__main__':
    sys.exit(minify_tool(**vars(parser.parse_args())))
