// Copyright (c) 2017, 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.benchmarks;

import static com.android.tools.r8.benchmarks.BenchmarkUtils.printRuntimeNanoseconds;

import com.android.tools.r8.ClassFileResourceProvider;
import com.android.tools.r8.CompilationException;
import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.D8;
import com.android.tools.r8.D8Command;
import com.android.tools.r8.D8Command.Builder;
import com.android.tools.r8.DexFilePerClassFileConsumer;
import com.android.tools.r8.DexFilePerClassFileConsumer.ForwardingConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.DiagnosticsHandler;
import com.android.tools.r8.ProgramConsumer;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.ResourceException;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.origin.PathOrigin;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.ZipUtils;
import com.google.common.collect.ImmutableMap;
import com.google.common.io.ByteStreams;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;

public class FrameworkIncrementalDexingBenchmark {
  private static final int ITERATIONS = 100;
  private static final int API = 24;
  private static final Path JAR_DESUGARED =
      Paths.get("third_party", "framework", "framework_14082017_desugared.jar");
  private static final Path JAR_NOT_DESUGARED =
      Paths.get("third_party", "framework", "framework_14082017.jar");
  private static final Path LIB =
      Paths.get("third_party", "android_jar", "lib-v" + API, "android.jar");

  static class InMemoryClassPathProvider implements ClassFileResourceProvider {
    Origin origin;
    Map<String, byte[]> resources;

    InMemoryClassPathProvider(Path archive) throws IOException {
      origin = new PathOrigin(archive);
      ImmutableMap.Builder<String, byte[]> builder = ImmutableMap.builder();
      ZipUtils.iter(
          archive.toString(),
          (entry, stream) -> {
            String name = entry.getName();
            if (ZipUtils.isClassFile(name)) {
              String descriptor = DescriptorUtils.guessTypeDescriptor(name);
              builder.put(descriptor, ByteStreams.toByteArray(stream));
            }
          });
      resources = builder.build();
    }

    @Override
    public Set<String> getClassDescriptors() {
      return resources.keySet();
    }

    @Override
    public ProgramResource getProgramResource(String descriptor) {
      byte[] bytes = resources.get(descriptor);
      return bytes == null
          ? null
          : ProgramResource.fromBytes(
              new EntryOrigin(descriptor, origin),
              Kind.CF,
              bytes,
              Collections.singleton(descriptor));
    }
  }

  static class EntryOrigin extends Origin {
    final String descriptor;

    public EntryOrigin(String descriptor, Origin parent) {
      super(parent);
      this.descriptor = descriptor;
    }

    @Override
    public String part() {
      return descriptor;
    }
  }

  private static String title(String title, boolean desugar) {
    return "FrameworkIncremental" + (desugar ? title : "NoDesugar" + title);
  }

  private static void compileAll(
      Path input,
      InMemoryClassPathProvider provider,
      boolean desugar,
      Map<String, ProgramResource> outputs,
      ExecutorService executor)
      throws IOException, CompilationException, CompilationFailedException {

    ProgramConsumer consumer =
        new DexFilePerClassFileConsumer.ForwardingConsumer(null) {
          @Override
          public synchronized void accept(
              String primaryClassDescriptor,
              byte[] data,
              Set<String> descriptors,
              DiagnosticsHandler handler) {
            ProgramResource resource =
                ProgramResource.fromBytes(Origin.unknown(), Kind.DEX, data, descriptors);
            for (String descriptor : descriptors) {
              assert !outputs.containsKey(descriptor);
              if (provider.resources.containsKey(descriptor)) {
                outputs.put(descriptor, resource);
              }
            }
          }
        };

    long start = System.nanoTime();
    D8.run(
        D8Command.builder()
            .setMinApiLevel(API)
            .setIntermediate(true)
            .setMode(CompilationMode.DEBUG)
            .addProgramFiles(input)
            .addLibraryFiles(LIB)
            .setDisableDesugaring(!desugar)
            .setProgramConsumer(consumer)
            .build(),
        executor);
    printRuntimeNanoseconds(title("DexAll", desugar), System.nanoTime() - start);
  }

  private static void compileGroupsOf(
      int count,
      List<String> descriptors,
      InMemoryClassPathProvider provider,
      boolean desugar,
      Map<String, ProgramResource> outputs,
      ExecutorService executor)
      throws IOException, CompilationException, CompilationFailedException {
    ProgramConsumer consumer =
        new ForwardingConsumer(null) {
          @Override
          public synchronized void accept(
              String primaryClassDescriptor,
              byte[] data,
              Set<String> descriptors,
              DiagnosticsHandler handler) {
            ProgramResource resource =
                ProgramResource.fromBytes(Origin.unknown(), Kind.DEX, data, descriptors);
            for (String descriptor : descriptors) {
              if (provider.resources.containsKey(descriptor)) {
                outputs.put(descriptor, resource);
              }
            }
          }
        };

    descriptors.sort(String::compareTo);
    int increment = descriptors.size() / ITERATIONS;
    long start = System.nanoTime();
    for (int iteration = 0; iteration < ITERATIONS; iteration++) {
      int index = iteration * increment;
      Builder builder =
          D8Command.builder()
              .setMinApiLevel(API)
              .setIntermediate(true)
              .setMode(CompilationMode.DEBUG)
              .addClasspathResourceProvider(provider)
              .addLibraryFiles(LIB)
              .setProgramConsumer(consumer)
              .setDisableDesugaring(!desugar);
      for (int j = 0; j < count; j++) {
        builder.addClassProgramData(provider.resources.get(descriptors.get(index + j)),
            Origin.unknown());
      }
      D8.run(builder.build(), executor);
    }
    printRuntimeNanoseconds(title("DexGroupsOf" + count, desugar), System.nanoTime() - start);
  }

  private static void merge(
      boolean desugar, Map<String, ProgramResource> outputs, ExecutorService executor)
      throws IOException, CompilationException, CompilationFailedException, ResourceException {
    Builder builder =
        D8Command.builder()
            .setMinApiLevel(API)
            .setIntermediate(false)
            .setMode(CompilationMode.DEBUG)
            .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
            .setDisableDesugaring(true);
    for (ProgramResource input : outputs.values()) {
      try (InputStream inputStream = input.getByteStream()) {
        builder.addDexProgramData(ByteStreams.toByteArray(inputStream), input.getOrigin());
      }
    }
    long start = System.nanoTime();
    D8.run(
        builder // never need to desugar when merging dex.
            .build(),
        executor);
    printRuntimeNanoseconds(title("DexMerge", desugar), System.nanoTime() - start);
  }

  public static void main(String[] args)
      throws IOException, CompilationException, CompilationFailedException, ResourceException {
    boolean desugar = Arrays.asList(args).contains("--desugar");
    Path input = desugar ? JAR_NOT_DESUGARED : JAR_DESUGARED;
    InMemoryClassPathProvider provider = new InMemoryClassPathProvider(input);
    List<String> descriptors = new ArrayList<>(provider.getClassDescriptors());
    Map<String, ProgramResource> outputs = new HashMap<>(provider.getClassDescriptors().size());
    int threads = Integer.min(Runtime.getRuntime().availableProcessors(), 16) / 2;
    ExecutorService executor = ThreadUtils.getExecutorService(threads);
    try {
      compileAll(input, provider, desugar, outputs, executor);
      compileGroupsOf(1, descriptors, provider, desugar, outputs, executor);
      compileGroupsOf(10, descriptors, provider, desugar, outputs, executor);
      compileGroupsOf(100, descriptors, provider, desugar, outputs, executor);
      merge(desugar, outputs, executor);
      // TODO: We should run dex2oat to verify the compilation.
    } finally {
      executor.shutdown();
    }
  }
}
