// Copyright (c) 2021, 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.ir.desugar.desugaredlibrary.retargeter;

import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.ClasspathMethod;
import com.android.tools.r8.graph.ClasspathOrLibraryClass;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.DerivedMethod;
import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.EmulatedDispatchMethodDescriptor;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterInstructionEventConsumer;
import com.android.tools.r8.ir.desugar.desugaredlibrary.retargeter.DesugaredLibraryRetargeterSynthesizerEventConsumer.DesugaredLibraryRetargeterL8SynthesizerEventConsumer;
import com.android.tools.r8.ir.synthetic.EmulateDispatchSyntheticCfCodeProvider;
import com.android.tools.r8.synthesis.SyntheticClassBuilder;
import com.android.tools.r8.synthesis.SyntheticItems.SyntheticKindSelector;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import java.util.LinkedHashMap;

public class DesugaredLibraryRetargeterSyntheticHelper {

  private final AppView<?> appView;

  public DesugaredLibraryRetargeterSyntheticHelper(AppView<?> appView) {
    this.appView = appView;
  }

  public DexMethod ensureRetargetMethod(
      DexMethod retarget, DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
    DexClass holderClass = appView.definitionFor(retarget.getHolderType());
    if (holderClass != null && !holderClass.isClasspathClass()) {
      // The holder class is a library class in orthodox set-ups where the L8 compilation
      // is done in multiple steps, this is only partially supported (most notably for tests).
      assert holderClass.lookupMethod(retarget) != null;
      return retarget;
    }
    assert eventConsumer != null;
    ClasspathMethod ensuredMethod =
        appView
            .getSyntheticItems()
            .ensureFixedClasspathMethodFromType(
                retarget.getName(),
                retarget.getProto(),
                kinds -> kinds.RETARGET_STUB,
                retarget.getHolderType(),
                appView,
                ignored -> {},
                eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass,
                methodBuilder ->
                    methodBuilder
                        .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
                        .setCode(null));
    assert ensuredMethod.getReference() == retarget;
    return retarget;
  }

  DexMethod forwardingMethod(EmulatedDispatchMethodDescriptor descriptor) {
    assert descriptor.getForwardingMethod().getHolderKind() == null;
    return descriptor.getForwardingMethod().getMethod();
  }

  public DexMethod ensureForwardingMethod(
      EmulatedDispatchMethodDescriptor descriptor,
      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
    return ensureRetargetMethod(forwardingMethod(descriptor), eventConsumer);
  }

  private boolean verifyKind(DerivedMethod method, SyntheticKindSelector kindSelector) {
    SyntheticKind kind = kindSelector.select(appView.getSyntheticItems().getNaming());
    assert method.getHolderKind().equals(kind);
    return true;
  }

  private DexMethod emulatedHolderDispatchMethod(DexType holder, DerivedMethod method) {
    assert verifyKind(method, kinds -> kinds.RETARGET_CLASS);
    DexProto newProto = appView.dexItemFactory().prependHolderToProto(method.getMethod());
    return appView.dexItemFactory().createMethod(holder, newProto, method.getName());
  }

  DexMethod emulatedInterfaceDispatchMethod(DexType holder, DerivedMethod method) {
    assert verifyKind(method, kinds -> kinds.RETARGET_INTERFACE);
    return appView.dexItemFactory().createMethod(holder, method.getProto(), method.getName());
  }

  public DexMethod emulatedInterfaceDispatchMethod(
      DexClass newInterface, EmulatedDispatchMethodDescriptor descriptor) {
    DexMethod method =
        emulatedInterfaceDispatchMethod(newInterface.type, descriptor.getInterfaceMethod());
    assert newInterface.lookupMethod(method) != null;
    return method;
  }

  public DexMethod ensureEmulatedHolderDispatchMethod(
      EmulatedDispatchMethodDescriptor descriptor,
      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
    assert eventConsumer != null;
    DerivedMethod emulatedDispatchMethod = descriptor.getEmulatedDispatchMethod();
    DexClass holderContext =
        appView.contextIndependentDefinitionFor(emulatedDispatchMethod.getHolderContext());
    DexClass syntheticClass;
    if (appView.options().isDesugaredLibraryCompilation()) {
      syntheticClass =
          appView
              .getSyntheticItems()
              .getExistingFixedClass(
                  ignored -> emulatedDispatchMethod.getHolderKind(), holderContext, appView);
      DexMethod dispatchMethod =
          emulatedHolderDispatchMethod(syntheticClass.type, emulatedDispatchMethod);
      assert syntheticClass.lookupMethod(dispatchMethod) != null;
      return dispatchMethod;
    } else {
      DexClass itfClass = ensureEmulatedInterfaceDispatchMethod(descriptor, eventConsumer);
      ClasspathOrLibraryClass context = holderContext.asClasspathOrLibraryClass();
      assert context != null;
      syntheticClass =
          appView
              .getSyntheticItems()
              .ensureFixedClasspathClass(
                  kinds -> kinds.RETARGET_CLASS,
                  context,
                  appView,
                  classBuilder ->
                      buildHolderDispatchMethod(classBuilder, itfClass, descriptor, eventConsumer),
                  eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
    }
    DexMethod dispatchMethod =
        emulatedHolderDispatchMethod(syntheticClass.type, emulatedDispatchMethod);
    assert syntheticClass.lookupMethod(dispatchMethod) != null;
    return dispatchMethod;
  }

  public void ensureProgramEmulatedHolderDispatchMethod(
      EmulatedDispatchMethodDescriptor descriptor,
      DesugaredLibraryRetargeterL8SynthesizerEventConsumer eventConsumer) {
    assert eventConsumer != null;
    assert appView.options().isDesugaredLibraryCompilation();
    DerivedMethod emulatedDispatchMethod = descriptor.getEmulatedDispatchMethod();
    DexClass holderContext =
        appView.contextIndependentDefinitionFor(emulatedDispatchMethod.getHolderContext());
    DexClass itfClass = ensureEmulatedInterfaceDispatchMethod(descriptor, eventConsumer);
    appView
        .getSyntheticItems()
        .ensureFixedClass(
            ignored -> emulatedDispatchMethod.getHolderKind(),
            holderContext,
            appView,
            classBuilder -> buildHolderDispatchMethod(classBuilder, itfClass, descriptor, null),
            eventConsumer::acceptDesugaredLibraryRetargeterDispatchProgramClass);
  }

  public DexClass ensureEmulatedInterfaceDispatchMethod(
      EmulatedDispatchMethodDescriptor descriptor,
      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
    assert eventConsumer != null;
    DerivedMethod itfMethod = descriptor.getInterfaceMethod();
    DexClass itfContext = appView.contextIndependentDefinitionFor(itfMethod.getHolderContext());
    if (appView.options().isDesugaredLibraryCompilation()) {
      return appView
          .getSyntheticItems()
          .getExistingFixedClass(ignored -> itfMethod.getHolderKind(), itfContext, appView);
    }
    ClasspathOrLibraryClass context = itfContext.asClasspathOrLibraryClass();
    assert context != null;
    return appView
        .getSyntheticItems()
        .ensureFixedClasspathClass(
            kinds -> kinds.RETARGET_INTERFACE,
            context,
            appView,
            classBuilder -> buildInterfaceDispatchMethod(classBuilder, descriptor),
            eventConsumer::acceptDesugaredLibraryRetargeterDispatchClasspathClass);
  }

  public DexClass ensureEmulatedInterfaceDispatchMethod(
      EmulatedDispatchMethodDescriptor descriptor,
      DesugaredLibraryRetargeterL8SynthesizerEventConsumer eventConsumer) {
    assert appView.options().isDesugaredLibraryCompilation();
    assert eventConsumer != null;
    DerivedMethod itfMethod = descriptor.getInterfaceMethod();
    DexClass itfContext = appView.contextIndependentDefinitionFor(itfMethod.getHolderContext());
    return appView
        .getSyntheticItems()
        .ensureFixedClass(
            ignore -> itfMethod.getHolderKind(),
            itfContext,
            appView,
            classBuilder -> buildInterfaceDispatchMethod(classBuilder, descriptor),
            eventConsumer::acceptDesugaredLibraryRetargeterDispatchProgramClass);
  }

  private void buildInterfaceDispatchMethod(
      SyntheticClassBuilder<?, ?> classBuilder, EmulatedDispatchMethodDescriptor descriptor) {
    classBuilder
        .setInterface()
        .addMethod(
            methodBuilder -> {
              DexMethod itfMethod =
                  emulatedInterfaceDispatchMethod(
                      classBuilder.getType(), descriptor.getInterfaceMethod());
              MethodAccessFlags flags =
                  MethodAccessFlags.fromSharedAccessFlags(
                      Constants.ACC_PUBLIC | Constants.ACC_ABSTRACT | Constants.ACC_SYNTHETIC,
                      false);
              methodBuilder
                  .setName(itfMethod.getName())
                  .setProto(itfMethod.getProto())
                  // Will be traced by the enqueuer.
                  .disableAndroidApiLevelCheck()
                  .setAccessFlags(flags);
            });
  }

  private <SCB extends SyntheticClassBuilder<?, ?>> void buildHolderDispatchMethod(
      SCB classBuilder,
      DexClass itfClass,
      EmulatedDispatchMethodDescriptor descriptor,
      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
    classBuilder.addMethod(
        methodBuilder -> {
          DexMethod dispatchMethod =
              emulatedHolderDispatchMethod(
                  classBuilder.getType(), descriptor.getEmulatedDispatchMethod());
          methodBuilder
              .setName(dispatchMethod.getName())
              .setProto(dispatchMethod.getProto())
              .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
              // Will be traced by the enqueuer.
              .disableAndroidApiLevelCheck()
              .setCode(
                  methodSig ->
                      appView.options().isDesugaredLibraryCompilation()
                          ? generateEmulatedDispatchCfCode(
                              descriptor, itfClass, methodSig, eventConsumer)
                          : null);
        });
  }

  private CfCode generateEmulatedDispatchCfCode(
      EmulatedDispatchMethodDescriptor descriptor,
      DexClass itfClass,
      DexMethod methodSig,
      DesugaredLibraryRetargeterInstructionEventConsumer eventConsumer) {
    DexMethod forwardingMethod = ensureForwardingMethod(descriptor, eventConsumer);
    DexMethod itfMethod = emulatedInterfaceDispatchMethod(itfClass, descriptor);
    assert descriptor.getDispatchCases().isEmpty();
    return new EmulateDispatchSyntheticCfCodeProvider(
            methodSig.getHolderType(), forwardingMethod, itfMethod, new LinkedHashMap<>(), appView)
        .generateCfCode();
  }
}
