// 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.
package com.android.tools.r8;

import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.ClassNamingForNameMapper;
import com.android.tools.r8.naming.MemberNaming.FieldSignature;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.BiConsumer;

/**
 * JarSizeCompare outputs the class, method, field sizes of the given JAR files. For each input, a
 * ProGuard map can be passed that is used to resolve minified names.
 *
 * <p>By default, only shows methods where R8's DEX output is 5 or more instructions larger than
 * ProGuard+D8's output. Pass {@code --threshold 0} to display all methods.
 */
public class JarSizeCompare {

  private static final String USAGE =
      "Arguments:\n"
          + "    [--threshold <threshold>]\n"
          + "    [--lib <lib.jar>]\n"
          + "    --input <name1> <input1.jar> [<map1.txt>]\n"
          + "    --input <name2> <input2.jar> [<map2.txt>] ...\n"
          + "\n"
          + "JarSizeCompare outputs the class, method, field sizes of the given JAR files.\n"
          + "For each input, a ProGuard map can be passed that is used to resolve minified"
          + " names.\n";

  private static final ImmutableMap<String, String> R8_RELOCATIONS =
      ImmutableMap.<String, String>builder()
          .put("com.google.common", "com.android.tools.r8.com.google.common")
          .put("com.google.gson", "com.android.tools.r8.com.google.gson")
          .put("com.google.thirdparty", "com.android.tools.r8.com.google.thirdparty")
          .put("joptsimple", "com.android.tools.r8.joptsimple")
          .put("org.apache.commons", "com.android.tools.r8.org.apache.commons")
          .put("org.objectweb.asm", "com.android.tools.r8.org.objectweb.asm")
          .put("it.unimi.dsi.fastutil", "com.android.tools.r8.it.unimi.dsi.fastutil")
          .build();

  private final List<Path> libraries;
  private final List<InputParameter> inputParameters;
  private final int threshold;
  private final InternalOptions options;
  private int pgIndex;
  private int r8Index;

  private JarSizeCompare(
      List<Path> libraries, List<InputParameter> inputParameters, int threshold) {
    this.libraries = libraries;
    this.inputParameters = inputParameters;
    this.threshold = threshold;
    options = new InternalOptions();
  }

  public void run() throws Exception {
    List<String> names = new ArrayList<>();
    List<InputApplication> inputApplicationList = new ArrayList<>();
    Timing timing = new Timing("JarSizeCompare");
    for (InputParameter inputParameter : inputParameters) {
      AndroidApp inputApp = inputParameter.getInputApp(libraries);
      DexApplication input = inputParameter.getReader(options, inputApp, timing);
      AndroidAppConsumers appConsumer = new AndroidAppConsumers();
      D8.run(
          D8Command.builder(inputApp)
              .setMinApiLevel(AndroidApiLevel.P.getLevel())
              .setProgramConsumer(appConsumer.wrapDexIndexedConsumer(null))
              .build());
      DexApplication d8Input = inputParameter.getReader(options, appConsumer.build(), timing);
      InputApplication inputApplication =
          new InputApplication(input, translateClassNames(input, input.classes()));
      InputApplication d8Classes =
          new InputApplication(input, translateClassNames(input, d8Input.classes()));
      names.add(inputParameter.name + "-input");
      inputApplicationList.add(inputApplication);
      names.add(inputParameter.name + "-d8");
      inputApplicationList.add(d8Classes);
    }
    if (threshold != 0) {
      pgIndex = names.indexOf("pg-d8");
      r8Index = names.indexOf("r8-d8");
    }
    Map<String, InputClass[]> inputClasses = new HashMap<>();
    for (int i = 0; i < names.size(); i++) {
      InputApplication classes = inputApplicationList.get(i);
      for (String className : classes.getClasses()) {
        inputClasses.computeIfAbsent(className, k -> new InputClass[names.size()])[i] =
            classes.getInputClass(className);
      }
    }
    for (Entry<String, Map<String, InputClass[]>> library : byLibrary(inputClasses)) {
      System.out.println("");
      System.out.println(Strings.repeat("=", 100));
      String commonPrefix = getCommonPrefix(library.getValue().keySet());
      if (library.getKey().isEmpty()) {
        System.out.println("PROGRAM (" + commonPrefix + ")");
      } else {
        System.out.println("LIBRARY: " + library.getKey() + " (" + commonPrefix + ")");
      }
      printLibrary(library.getValue(), commonPrefix);
    }
  }

  private Map<String, DexProgramClass> translateClassNames(
      DexApplication input, List<DexProgramClass> classes) {
    Map<String, DexProgramClass> result = new HashMap<>();
    ClassNameMapper classNameMapper = input.getProguardMap();
    for (DexProgramClass programClass : classes) {
      ClassNamingForNameMapper classNaming;
      if (classNameMapper == null) {
        classNaming = null;
      } else {
        classNaming = classNameMapper.getClassNaming(programClass.type);
      }
      String type =
          classNaming == null ? programClass.type.toSourceString() : classNaming.originalName;
      result.put(type, programClass);
    }
    return result;
  }

  private String getCommonPrefix(Set<String> classes) {
    if (classes.size() <= 1) {
      return "";
    }
    String commonPrefix = null;
    for (String clazz : classes) {
      if (clazz.equals("r8.GeneratedOutlineSupport")) {
        continue;
      }
      if (commonPrefix == null) {
        commonPrefix = clazz;
      } else {
        int i = 0;
        while (i < clazz.length()
            && i < commonPrefix.length()
            && clazz.charAt(i) == commonPrefix.charAt(i)) {
          i++;
        }
        commonPrefix = commonPrefix.substring(0, i);
      }
    }
    return commonPrefix;
  }

  private void printLibrary(Map<String, InputClass[]> classMap, String commonPrefix) {
    List<Entry<String, InputClass[]>> classes = new ArrayList<>(classMap.entrySet());
    classes.sort(Comparator.comparing(Entry::getKey));
    for (Entry<String, InputClass[]> clazz : classes) {
      printClass(
          clazz.getKey().substring(commonPrefix.length()), new ClassCompare(clazz.getValue()));
    }
  }

  private void printClass(String name, ClassCompare inputClasses) {
    List<MethodSignature> methods = getMethods(inputClasses);
    List<FieldSignature> fields = getFields(inputClasses);
    if (methods.isEmpty() && fields.isEmpty()) {
      return;
    }
    System.out.println(name);
    for (MethodSignature sig : methods) {
      printSignature(getMethodString(sig), inputClasses.sizes(sig));
    }
    for (FieldSignature sig : fields) {
      printSignature(getFieldString(sig), inputClasses.sizes(sig));
    }
  }

  private String getMethodString(MethodSignature sig) {
    StringBuilder builder = new StringBuilder().append('(');
    for (int i = 0; i < sig.parameters.length; i++) {
      builder.append(DescriptorUtils.javaTypeToShorty(sig.parameters[i]));
    }
    builder.append(')').append(DescriptorUtils.javaTypeToShorty(sig.type)).append(' ');
    return builder.append(sig.name).toString();
  }

  private String getFieldString(FieldSignature sig) {
    return DescriptorUtils.javaTypeToShorty(sig.type) + ' ' + sig.name;
  }

  private void printSignature(String key, int[] sizes) {
    System.out.print(padItem(key));
    for (int size : sizes) {
      System.out.print(padValue(size));
    }
    System.out.print('\n');
  }

  private List<MethodSignature> getMethods(ClassCompare inputClasses) {
    List<MethodSignature> methods = new ArrayList<>();
    for (MethodSignature methodSignature : inputClasses.getMethods()) {
      if (threshold == 0 || methodExceedsThreshold(inputClasses, methodSignature)) {
        methods.add(methodSignature);
      }
    }
    return methods;
  }

  private boolean methodExceedsThreshold(
      ClassCompare inputClasses, MethodSignature methodSignature) {
    assert threshold > 0;
    assert pgIndex != r8Index;
    int pgSize = inputClasses.size(methodSignature, pgIndex);
    int r8Size = inputClasses.size(methodSignature, r8Index);
    return pgSize != -1 && r8Size != -1 && pgSize + threshold <= r8Size;
  }

  private List<FieldSignature> getFields(ClassCompare inputClasses) {
    return threshold == 0 ? inputClasses.getFields() : Collections.emptyList();
  }

  private String padItem(String s) {
    return String.format("%-52s", s);
  }

  private String padValue(int v) {
    return String.format("%8s", v == -1 ? "---" : v);
  }

  private List<Map.Entry<String, Map<String, InputClass[]>>> byLibrary(
      Map<String, InputClass[]> inputClasses) {
    Map<String, Map<String, InputClass[]>> byLibrary = new HashMap<>();
    for (Entry<String, InputClass[]> entry : inputClasses.entrySet()) {
      Map<String, InputClass[]> library =
          byLibrary.computeIfAbsent(getLibraryName(entry.getKey()), k -> new HashMap<>());
      library.put(entry.getKey(), entry.getValue());
    }
    List<Entry<String, Map<String, InputClass[]>>> list = new ArrayList<>(byLibrary.entrySet());
    list.sort(Comparator.comparing(Entry::getKey));
    return list;
  }

  private String getLibraryName(String className) {
    for (Entry<String, String> relocation : R8_RELOCATIONS.entrySet()) {
      if (className.startsWith(relocation.getValue())) {
        return relocation.getKey();
      }
    }
    return "";
  }

  static class InputParameter {

    private final String name;
    private final Path jar;
    private final Path map;

    InputParameter(String name, Path jar, Path map) {
      this.name = name;
      this.jar = jar;
      this.map = map;
    }

    DexApplication getReader(InternalOptions options, AndroidApp inputApp, Timing timing)
        throws Exception {
      ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
      return applicationReader.read(map == null ? null : StringResource.fromFile(map)).toDirect();
    }

    AndroidApp getInputApp(List<Path> libraries) throws Exception {
      return AndroidApp.builder().addLibraryFiles(libraries).addProgramFiles(jar).build();
    }
  }

  static class InputApplication {

    private final DexApplication dexApplication;
    private final Map<String, DexProgramClass> classMap;

    private InputApplication(DexApplication dexApplication, Map<String, DexProgramClass> classMap) {
      this.dexApplication = dexApplication;
      this.classMap = classMap;
    }

    public Set<String> getClasses() {
      return classMap.keySet();
    }

    private InputClass getInputClass(String type) {
      DexProgramClass inputClass = classMap.get(type);
      ClassNameMapper proguardMap = dexApplication.getProguardMap();
      return new InputClass(inputClass, proguardMap);
    }
  }

  static class InputClass {
    private final DexProgramClass programClass;
    private final ClassNameMapper proguardMap;

    InputClass(DexClass dexClass, ClassNameMapper proguardMap) {
      this.programClass = dexClass == null ? null : dexClass.asProgramClass();
      this.proguardMap = proguardMap;
    }

    void forEachMethod(BiConsumer<MethodSignature, DexEncodedMethod> consumer) {
      if (programClass == null) {
        return;
      }
      programClass.forEachMethod(
          dexEncodedMethod -> {
            MethodSignature originalSignature =
                proguardMap == null
                    ? null
                    : proguardMap.originalSignatureOf(dexEncodedMethod.getReference());
            MethodSignature signature =
                MethodSignature.fromDexMethod(dexEncodedMethod.getReference());
            consumer.accept(
                originalSignature == null ? signature : originalSignature, dexEncodedMethod);
          });
    }

    void forEachField(BiConsumer<FieldSignature, DexEncodedField> consumer) {
      if (programClass == null) {
        return;
      }
      programClass.forEachField(
          dexEncodedField -> {
            FieldSignature originalSignature =
                proguardMap == null
                    ? null
                    : proguardMap.originalSignatureOf(dexEncodedField.getReference());
            FieldSignature signature = FieldSignature.fromDexField(dexEncodedField.getReference());
            consumer.accept(
                originalSignature == null ? signature : originalSignature, dexEncodedField);
          });
    }
  }

  private static class ClassCompare {
    final Map<MethodSignature, DexEncodedMethod[]> methods = new HashMap<>();
    final Map<FieldSignature, DexEncodedField[]> fields = new HashMap<>();
    final int classes;

    ClassCompare(InputClass[] inputs) {
      for (int i = 0; i < inputs.length; i++) {
        InputClass inputClass = inputs[i];
        int finalI = i;
        if (inputClass == null) {
          continue;
        }
        inputClass.forEachMethod(
            (sig, m) ->
                methods.computeIfAbsent(sig, o -> new DexEncodedMethod[inputs.length])[finalI] = m);
        inputClass.forEachField(
            (sig, f) ->
                fields.computeIfAbsent(sig, o -> new DexEncodedField[inputs.length])[finalI] = f);
      }
      classes = inputs.length;
    }

    List<MethodSignature> getMethods() {
      List<MethodSignature> methods = new ArrayList<>(this.methods.keySet());
      methods.sort(Comparator.comparing(MethodSignature::toString));
      return methods;
    }

    List<FieldSignature> getFields() {
      List<FieldSignature> fields = new ArrayList<>(this.fields.keySet());
      fields.sort(Comparator.comparing(FieldSignature::toString));
      return fields;
    }

    int size(MethodSignature method, int classIndex) {
      DexEncodedMethod dexEncodedMethod = methods.get(method)[classIndex];
      if (dexEncodedMethod == null) {
        return -1;
      }
      Code code = dexEncodedMethod.getCode();
      if (code == null) {
        return 0;
      }
      if (code.isCfCode()) {
        return code.asCfCode().getInstructions().size();
      }
      if (code.isDexCode()) {
        return code.asDexCode().instructions.length;
      }
      throw new Unreachable();
    }

    int[] sizes(MethodSignature method) {
      int[] result = new int[classes];
      for (int i = 0; i < classes; i++) {
        result[i] = size(method, i);
      }
      return result;
    }

    int size(FieldSignature field, int classIndex) {
      return fields.get(field)[classIndex] == null ? -1 : 1;
    }

    int[] sizes(FieldSignature field) {
      int[] result = new int[classes];
      for (int i = 0; i < classes; i++) {
        result[i] = size(field, i);
      }
      return result;
    }
  }

  public static void main(String[] args) throws Exception {
    JarSizeCompare program = JarSizeCompare.parse(args);
    if (program == null) {
      System.out.println(USAGE);
    } else {
      program.run();
    }
  }

  public static JarSizeCompare parse(String[] args) {
    int i = 0;
    int threshold = 0;
    List<Path> libraries = new ArrayList<>();
    List<InputParameter> inputs = new ArrayList<>();
    Set<String> names = new HashSet<>();
    while (i < args.length) {
      if (args[i].equals("--threshold") && i + 1 < args.length) {
        threshold = Integer.parseInt(args[i + 1]);
        i += 2;
      } else if (args[i].equals("--lib") && i + 1 < args.length) {
        libraries.add(Paths.get(args[i + 1]));
        i += 2;
      } else if (args[i].equals("--input") && i + 2 < args.length) {
        String name = args[i + 1];
        Path jar = Paths.get(args[i + 2]);
        Path map = null;
        if (i + 3 < args.length && !args[i + 3].startsWith("-")) {
          map = Paths.get(args[i + 3]);
          i += 4;
        } else {
          i += 3;
        }
        inputs.add(new InputParameter(name, jar, map));
        if (!names.add(name)) {
          System.out.println("Duplicate name: " + name);
          return null;
        }
      } else {
        return null;
      }
    }
    if (inputs.size() < 2) {
      return null;
    }
    if (threshold != 0 && (!names.contains("r8") || !names.contains("pg"))) {
      System.out.println(
          "You must either specify names \"pg\" and \"r8\" for input files "
              + "or use \"--threshold 0\".");
      return null;
    }
    return new JarSizeCompare(libraries, inputs, threshold);
  }
}
