// 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;

import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.dex.ApplicationWriter;
import com.android.tools.r8.dex.Marker;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.Timing;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

public class DexFileMergerHelper {

  private final Map<String, Integer> inputOrdering;

  private DexFileMergerHelper(Map<String, Integer> inputOrdering) {
    this.inputOrdering = inputOrdering;
  }

  private DexProgramClass keepFirstProgramClassConflictResolver(
      DexProgramClass a, DexProgramClass b) {
    String aPath = a.getOrigin().parent().part();
    String bPath = b.getOrigin().parent().part();
    Integer aIndex = inputOrdering.get(aPath);
    Integer bIndex = inputOrdering.get(bPath);
    if (aIndex == null || bIndex == null) {
      StringBuilder builder = new StringBuilder();
      builder.append("Class parent paths not found among input paths: ");
      if (aIndex == null) {
        builder.append(aPath);
      }
      if (bIndex == null) {
        if (aIndex == null) {
          builder.append(", ");
        }
        builder.append(bPath);
      }
      throw new RuntimeException(builder.toString());
    }
    return aIndex <= bIndex ? a.get() : b.get();
  }

  public static void run(
      D8Command command, Boolean minimalMainDex, Map<String, Integer> inputOrdering)
      throws CompilationFailedException {
    InternalOptions options = command.getInternalOptions();
    ExceptionUtils.withD8CompilationHandler(
        options.reporter,
        () -> runInternal(command.getInputApp(), options, minimalMainDex, inputOrdering));
  }

  private static void runInternal(
      AndroidApp inputApp,
      InternalOptions options,
      Boolean minimalMainDex,
      Map<String, Integer> inputOrdering)
      throws IOException {
    options.enableDesugaring = false;
    options.enableMainDexListCheck = false;
    options.minimalMainDex = minimalMainDex;
    options.enableMinification = false;
    options.enableInlining = false;
    options.outline.enabled = false;

    ExecutorService executor = ThreadUtils.getExecutorService(ThreadUtils.NOT_SPECIFIED);
    try {
      try {
        Timing timing = new Timing("DexFileMerger");
        DexApplication app =
            new ApplicationReader(inputApp, options, timing)
                .read(
                    null,
                    executor,
                    new DexFileMergerHelper(inputOrdering)::keepFirstProgramClassConflictResolver);
        AppInfo appInfo = new AppInfo(app);
        app = D8.optimize(app, appInfo, options, timing, executor);

        List<Marker> markers = app.dexItemFactory.extractMarkers();

        assert !options.hasMethodsFilter();
        ApplicationWriter writer =
            new ApplicationWriter(
                app,
                options,
                markers,
                null,
                GraphLense.getIdentityLense(),
                NamingLens.getIdentityLens(),
                null,
                null);
        writer.write(executor);
        options.printWarnings();
      } catch (ExecutionException e) {
        throw R8.unwrapExecutionException(e);
      } finally {
        options.signalFinishedToConsumers();
      }
    } finally {
      executor.shutdown();
    }
  }

  public static void runD8ForTesting(D8Command command, boolean dontCreateMarkerInD8)
      throws CompilationFailedException {
    InternalOptions options = command.getInternalOptions();
    options.testing.dontCreateMarkerInD8 = dontCreateMarkerInD8;
    D8.runForTesting(command.getInputApp(), options);
  }
}
