#!/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.
'''
Compare the R8 API used by the API usage sample to the API kept by @Keep.
'''

import argparse
import jdk
import os
import subprocess
import utils

parser = argparse.ArgumentParser(description=__doc__.strip(),
                                 formatter_class=argparse.RawTextHelpFormatter)
parser.add_argument('-o', '--output-dir')

API_SAMPLE_JAR = 'tests/d8_api_usage_sample.jar'


def main(output_dir=None):
    if output_dir is None:
        output_dir = ''

    javaExecutable = jdk.GetJavaExecutable()
    printseeds_path = os.path.join(output_dir, 'keep-seeds.txt')
    printseeds_args = [
        javaExecutable,
        '-jar',
        utils.R8_JAR,
        'printseeds',
        utils.RT_JAR,
        utils.R8_JAR,
        utils.R8LIB_KEEP_RULES,
    ]
    write_sorted_lines(printseeds_args, printseeds_path)

    printuses_path = os.path.join(output_dir, 'sample-uses.txt')
    printuses_args = [
        javaExecutable,
        '-jar',
        utils.R8_JAR,
        'printuses',
        utils.RT_JAR,
        utils.R8_JAR,
        API_SAMPLE_JAR,
    ]
    write_sorted_lines(printuses_args, printuses_path)

    print_diff(printseeds_path, printuses_path)


def write_sorted_lines(cmd_args, output_path):
    utils.PrintCmd(cmd_args)
    output_lines = subprocess.check_output(cmd_args).splitlines(True)
    print("Write output to %s" % output_path)
    output_lines.sort()
    with open(output_path, 'w') as fp:
        for line in output_lines:
            fp.write(line)


def print_diff(printseeds_path, printuses_path):
    with open(printseeds_path) as fp:
        seeds = set(fp.read().splitlines())
    with open(printuses_path) as fp:
        uses = set(fp.read().splitlines())
    only_in_seeds = seeds - uses
    only_in_uses = uses - seeds
    if only_in_seeds:
        print("%s lines with '-' are marked @Keep " % len(only_in_seeds) +
              "but not used by sample.")
    if only_in_uses:
        print("%s lines with '+' are used by sample " % len(only_in_uses) +
              "but are missing @Keep annotations.")
    for line in sorted(only_in_seeds):
        print('-' + line)
    for line in sorted(only_in_uses):
        print('+' + line)
    if not only_in_seeds and not only_in_uses:
        print('Sample uses the entire set of members marked @Keep. Well done!')


if __name__ == '__main__':
    main(**vars(parser.parse_args()))
