// Copyright (c) 2024, 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.diagnostic.R8VersionDiagnostic;
import com.android.tools.r8.features.FeatureSplitConfiguration;
import com.android.tools.r8.graph.DexClasspathClass;
import com.android.tools.r8.graph.DirectMappedDexApplication;
import com.android.tools.r8.keepanno.ast.KeepDeclaration;
import com.android.tools.r8.metadata.impl.R8PartialCompilationStatsMetadataBuilder;
import com.android.tools.r8.partial.R8PartialD8Input;
import com.android.tools.r8.partial.R8PartialD8Result;
import com.android.tools.r8.partial.R8PartialProgramPartitioning;
import com.android.tools.r8.partial.R8PartialSubCompilationConfiguration.R8PartialD8SubCompilationConfiguration;
import com.android.tools.r8.partial.R8PartialSubCompilationConfiguration.R8PartialR8SubCompilationConfiguration;
import com.android.tools.r8.profile.art.ArtProfileOptions;
import com.android.tools.r8.profile.startup.StartupOptions;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ExceptionUtils;
import com.android.tools.r8.utils.FeatureSplitConsumers;
import com.android.tools.r8.utils.ForwardingDiagnosticsHandler;
import com.android.tools.r8.utils.InternalClasspathOrLibraryClassProvider;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.InternalProgramClassProvider;
import com.android.tools.r8.utils.ThreadUtils;
import com.android.tools.r8.utils.internal.ListUtils;
import com.android.tools.r8.utils.internal.exceptions.Unreachable;
import com.android.tools.r8.utils.timing.Timing;
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.function.Consumer;

class R8Partial {

  private final InternalOptions options;
  private final Timing timing;

  R8Partial(InternalOptions options, ExecutorService executor) {
    this.options = options;
    this.timing = Timing.createRoot("R8 partial " + Version.LABEL, options, executor);
  }

  static void runForTesting(AndroidApp app, InternalOptions options)
      throws CompilationFailedException {
    ExecutorService executor = ThreadUtils.getExecutorService(options);
    ExceptionUtils.withR8CompilationHandler(
        options.reporter,
        () -> {
          try {
            new R8Partial(options, executor).runInternal(app, executor);
          } finally {
            executor.shutdown();
          }
        });
  }

  void runInternal(AndroidApp app, ExecutorService executor) throws IOException, ResourceException {
    if (options.getProguardConfiguration().isProtoShrinkingEnabled()) {
      throw options.reporter.fatalError("Partial shrinking does not support proto shrinking");
    }

    Map<FeatureSplit, FeatureSplitConsumers> featureSplitConsumers =
        getAndClearFeatureSplitConsumers();

    timing.begin("Process input");
    R8PartialD8Input input = runProcessInputStep(app, executor);

    R8PartialCompilationStatsMetadataBuilder statsMetadataBuilder =
        R8PartialCompilationStatsMetadataBuilder.create(input, options);

    timing.end().begin("Run D8");
    R8PartialD8Result d8Result = runD8Step(input, executor);
    timing.end();

    setFeatureSplitConsumers(featureSplitConsumers);
    lockFeatureSplitProgramResourceProviders();

    timing.begin("Run R8");
    runR8Step(app, d8Result, statsMetadataBuilder, executor);
    timing.end();

    if (options.isPrintTimesReportingEnabled()) {
      timing.report();
    }
  }

  private R8PartialD8Input runProcessInputStep(AndroidApp androidApp, ExecutorService executor)
      throws IOException {
    DirectMappedDexApplication app =
        new ApplicationReader(androidApp, options, timing).readDirect(executor);
    List<KeepDeclaration> keepDeclarations = app.getKeepDeclarations();
    R8PartialProgramPartitioning partitioning = R8PartialProgramPartitioning.create(app);
    partitioning.printForTesting(options);
    options.getLibraryDesugaringOptions().loadMachineDesugaredLibrarySpecification(timing, app);
    return new R8PartialD8Input(
        partitioning.getD8Classes(),
        partitioning.getR8Classes(),
        app.classpathClasses(),
        app.libraryClasses(),
        app.getFlags(),
        keepDeclarations);
  }

  private R8PartialD8Result runD8Step(R8PartialD8Input input, ExecutorService executor)
      throws IOException {
    // TODO(b/389039057): This will desugar the entire R8 part. For build speed, look into if some
    //  desugarings can be postponed to the R8 compilation, since we do not desugar dead code in R8.
    //  As a simple example, it should be safe to postpone backporting to the R8 compilation.
    D8Command.Builder d8Builder =
        D8Command.builder(options.reporter)
            .setEnableExperimentalMissingLibraryApiModeling(
                options.apiModelingOptions().isApiModelingEnabled())
            .setEnableVerboseSyntheticNames(
                options.desugarSpecificOptions().enableVerboseSyntheticNames)
            .setMinApiLevel(options.getMinApiLevel().getLevel())
            .setMode(options.getCompilationMode())
            .setProgramConsumer(DexIndexedConsumer.emptyConsumer());
    input.configure(d8Builder);
    d8Builder.getAppBuilder().disableAndroidJarHiddenClassExtension();
    d8Builder.validate();
    D8Command d8Command = d8Builder.makeD8Command(options.dexItemFactory());
    AndroidApp d8App = d8Command.getInputApp();
    InternalOptions d8Options = d8Command.getInternalOptions();
    forwardOptions(d8Options);
    options.partialCompilationConfiguration.d8DexOptionsConsumer.accept(d8Options);
    R8PartialD8SubCompilationConfiguration subCompilationConfiguration =
        new R8PartialD8SubCompilationConfiguration(
            input.getD8Types(),
            input.getR8Types(),
            input.getFlags(),
            options.getLibraryDesugaringOptions(),
            timing);
    d8Options.setArtProfileOptions(
        new ArtProfileOptions(d8Options, options.getArtProfileOptions()));
    d8Options.setFeatureSplitConfiguration(options.getFeatureSplitConfiguration());
    d8Options.setStartupOptions(new StartupOptions(d8Options, options.getStartupOptions()));
    d8Options.partialSubCompilationConfiguration = subCompilationConfiguration;
    D8.runInternal(d8App, d8Options, executor);
    return new R8PartialD8Result(
        subCompilationConfiguration.getArtProfiles(),
        subCompilationConfiguration.getClassToFeatureSplitMap(),
        subCompilationConfiguration.getDexedOutputClasses(),
        subCompilationConfiguration.getDesugaredOutputClasses(),
        input.getFlags(),
        input.getKeepDeclarations(),
        subCompilationConfiguration.getOutputClasspathClasses(),
        subCompilationConfiguration.getOutputLibraryClasses(),
        subCompilationConfiguration.getStartupProfile(),
        subCompilationConfiguration.getSynthetics());
  }

  private void runR8Step(
      AndroidApp app,
      R8PartialD8Result d8Result,
      R8PartialCompilationStatsMetadataBuilder statsMetadataBuilder,
      ExecutorService executor)
      throws IOException {
    // Compile R8 input with R8 using the keep rules from trace references.
    DiagnosticsHandler r8DiagnosticsHandler =
        new ForwardingDiagnosticsHandler(options.reporter) {

          @Override
          public DiagnosticsLevel modifyDiagnosticsLevel(
              DiagnosticsLevel level, Diagnostic diagnostic) {
            if (diagnostic instanceof R8VersionDiagnostic) {
              return DiagnosticsLevel.NONE;
            }
            return super.modifyDiagnosticsLevel(level, diagnostic);
          }
        };
    // TODO(b/390389764): Disable desugaring.
    R8Command.Builder r8Builder =
        R8Command.builder(r8DiagnosticsHandler)
            .addProgramResourceProvider(
                new InternalProgramClassProvider(d8Result.getDesugaredClasses()))
            .addClasspathResourceProvider(
                new InternalClasspathOrLibraryClassProvider<>(
                    DexClasspathClass.toClasspathClasses(d8Result.getDexedClasses())))
            .addClasspathResourceProvider(
                new InternalClasspathOrLibraryClassProvider<>(d8Result.getOutputClasspathClasses()))
            .addLibraryResourceProvider(
                new InternalClasspathOrLibraryClassProvider<>(d8Result.getOutputLibraryClasses()))
            .enableLegacyFullModeForKeepRules(true)
            .setBuildMetadataConsumer(options.r8BuildMetadataConsumer)
            .setEnableExperimentalMissingLibraryApiModeling(
                options.apiModelingOptions().isApiModelingEnabled())
            .setEnableVerboseSyntheticNames(
                options.desugarSpecificOptions().enableVerboseSyntheticNames)
            .setMapIdProvider(options.mapIdProvider)
            .setMinApiLevel(options.getMinApiLevel().getLevel())
            .setMode(options.getCompilationMode())
            .setPartialCompilationConfiguration(options.partialCompilationConfiguration)
            .setProgramConsumer(options.programConsumer)
            .setSourceFileProvider(options.sourceFileProvider)
            .setNativeReferencesConsumer(options.nativeReferencesConsumer);
    // The program input that R8 must compile is provided above using an
    // InternalProgramClassProvider. This passes in the data resources that we must either rewrite
    // or pass through.
    for (ProgramResourceProvider programResourceProvider : app.getProgramResourceProviders()) {
      if (programResourceProvider.getDataResourceProvider() == null) {
        programResourceProvider.finished(options.reporter);
      } else {
        r8Builder.addProgramResourceProvider(
            new ProgramResourceProvider() {

              @Override
              public Collection<ProgramResource> getProgramResources() {
                return Collections.emptyList();
              }

              @Override
              public void getProgramResources(Consumer<ProgramResource> consumer) {
                // Intentionally empty.
              }

              @Override
              public DataResourceProvider getDataResourceProvider() {
                return programResourceProvider.getDataResourceProvider();
              }

              @Override
              public void finished(DiagnosticsHandler handler) throws IOException {
                programResourceProvider.finished(handler);
              }
            });
      }
    }
    r8Builder.getAppBuilder().disableAndroidJarHiddenClassExtension();
    r8Builder.validate();
    R8Command r8Command =
        r8Builder.makeR8Command(options.dexItemFactory(), options.getProguardConfiguration());
    AndroidApp r8App = r8Command.getInputApp();
    InternalOptions r8Options = r8Command.getInternalOptions();
    forwardOptions(r8Options);
    options.partialCompilationConfiguration.r8OptionsConsumer.accept(r8Options);
    r8Options.partialSubCompilationConfiguration =
        new R8PartialR8SubCompilationConfiguration(
            d8Result.getArtProfiles(),
            d8Result.getClassToFeatureSplitMap(),
            d8Result.getDexedClasses(),
            d8Result.getFlags(),
            d8Result.getKeepDeclarations(),
            d8Result.getStartupProfile(),
            statsMetadataBuilder,
            d8Result.getSynthetics(),
            timing);
    r8Options.setArtProfileOptions(
        new ArtProfileOptions(r8Options, options.getArtProfileOptions()));
    r8Options.setFeatureSplitConfiguration(options.getFeatureSplitConfiguration());
    r8Options.setStartupOptions(new StartupOptions(r8Options, options.getStartupOptions()));
    r8Options.setKeepSpecificationSources(options.getKeepSpecifications());
    r8Options.getTestingOptions().enableEmbeddedKeepAnnotations =
        options.getTestingOptions().enableEmbeddedKeepAnnotations;
    r8Options.configurationConsumer = options.configurationConsumer;
    r8Options.mapConsumer = options.mapConsumer;
    r8Options.proguardSeedsConsumer = options.proguardSeedsConsumer;
    r8Options.usageInformationConsumer = options.usageInformationConsumer;
    r8Options.sourceFileProvider = options.sourceFileProvider;
    r8Options
        .getLibraryDesugaringOptions()
        .setMachineDesugaredLibrarySpecification(
            options.getLibraryDesugaringOptions().getMachineDesugaredLibrarySpecification())
        .setTypeRewriter(options.getLibraryDesugaringOptions().getTypeRewriter());
    if (options.androidResourceProvider != null) {
      r8Options.androidResourceProvider = options.androidResourceProvider;
      r8Options.androidResourceConsumer = options.androidResourceConsumer;
      r8Options.resourceShrinkerConfiguration = options.resourceShrinkerConfiguration;
    }
    R8.runInternal(r8App, r8Options, executor);
  }

  private Map<FeatureSplit, FeatureSplitConsumers> getAndClearFeatureSplitConsumers() {
    FeatureSplitConfiguration featureSplitConfiguration = options.getFeatureSplitConfiguration();
    if (featureSplitConfiguration == null) {
      return null;
    }
    Map<FeatureSplit, FeatureSplitConsumers> featureSplitConsumers = new IdentityHashMap<>();
    for (FeatureSplit featureSplit : featureSplitConfiguration.getFeatureSplits()) {
      featureSplitConsumers.put(featureSplit, featureSplit.internalClearConsumers());
    }
    return featureSplitConsumers;
  }

  private void setFeatureSplitConsumers(
      Map<FeatureSplit, FeatureSplitConsumers> featureSplitConsumers) {
    if (featureSplitConsumers == null) {
      return;
    }
    FeatureSplitConfiguration featureSplitConfiguration = options.getFeatureSplitConfiguration();
    for (FeatureSplit featureSplit : featureSplitConfiguration.getFeatureSplits()) {
      featureSplit.internalSetConsumers(featureSplitConsumers.get(featureSplit));
    }
    featureSplitConsumers.clear();
  }

  private void lockFeatureSplitProgramResourceProviders() {
    FeatureSplitConfiguration featureSplitConfiguration = options.getFeatureSplitConfiguration();
    if (featureSplitConfiguration == null) {
      return;
    }
    for (FeatureSplit featureSplit : featureSplitConfiguration.getFeatureSplits()) {
      List<ProgramResourceProvider> programResourceProviders =
          featureSplit.getProgramResourceProviders();
      List<ProgramResourceProvider> replacementProgramResourceProviders =
          ListUtils.map(
              programResourceProviders,
              programResourceProvider ->
                  new ProgramResourceProvider() {

                    @Override
                    public Collection<ProgramResource> getProgramResources() {
                      throw new Unreachable();
                    }

                    @Override
                    public void getProgramResources(Consumer<ProgramResource> consumer) {
                      throw new Unreachable();
                    }

                    @Override
                    public DataResourceProvider getDataResourceProvider() {
                      return programResourceProvider.getDataResourceProvider();
                    }

                    @Override
                    public void finished(DiagnosticsHandler handler) throws IOException {
                      programResourceProvider.finished(handler);
                    }
                  });
      featureSplit.internalSetProgramResourceProviders(replacementProgramResourceProviders);
    }
  }

  private void forwardOptions(InternalOptions subCompilationOptions) {
    subCompilationOptions.emitNestAnnotationsInDex = options.emitNestAnnotationsInDex;
    subCompilationOptions.emitRecordAnnotationsInDex = options.emitRecordAnnotationsInDex;
    subCompilationOptions.emitPermittedSubclassesAnnotationsInDex =
        options.emitPermittedSubclassesAnnotationsInDex;
    subCompilationOptions.desugarState = options.desugarState;
    subCompilationOptions.forceNestDesugaring = options.forceNestDesugaring;
    subCompilationOptions.emitLambdaMethodAnnotations = options.emitLambdaMethodAnnotations;
    subCompilationOptions.disableLambdaMethodAnnotations = options.disableLambdaMethodAnnotations;
    subCompilationOptions.getTestingOptions().forceDexContainerFormat =
        options.getTestingOptions().forceDexContainerFormat;
  }
}
