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

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
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.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaring;
import com.android.tools.r8.ir.desugar.CfClassSynthesizerDesugaringEventConsumer;
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.machinespecification.EmulatedInterfaceDescriptor;
import com.android.tools.r8.ir.desugar.itf.EmulatedInterfaceSynthesizerEventConsumer.L8ProgramEmulatedInterfaceSynthesizerEventConsumer;
import com.android.tools.r8.ir.synthetic.EmulateDispatchSyntheticCfCodeProvider;
import com.android.tools.r8.synthesis.SyntheticMethodBuilder;
import com.android.tools.r8.synthesis.SyntheticNaming;
import com.android.tools.r8.synthesis.SyntheticNaming.SyntheticKind;
import com.android.tools.r8.synthesis.SyntheticProgramClassBuilder;
import com.android.tools.r8.utils.StringDiagnostic;
import java.util.LinkedHashMap;

public final class ProgramEmulatedInterfaceSynthesizer implements CfClassSynthesizerDesugaring {

  private final AppView<?> appView;
  private final InterfaceDesugaringSyntheticHelper helper;

  public static ProgramEmulatedInterfaceSynthesizer create(AppView<?> appView) {
    if (!appView.options().isDesugaredLibraryCompilation()
        || !appView.options().machineDesugaredLibrarySpecification.hasEmulatedInterfaces()) {
      return null;
    }
    return new ProgramEmulatedInterfaceSynthesizer(appView);
  }

  public ProgramEmulatedInterfaceSynthesizer(AppView<?> appView) {
    this.appView = appView;
    helper = new InterfaceDesugaringSyntheticHelper(appView);
  }

  DexProgramClass synthesizeProgramEmulatedInterface(
      DexProgramClass emulatedInterface,
      EmulatedInterfaceDescriptor emulatedInterfaceDescriptor,
      L8ProgramEmulatedInterfaceSynthesizerEventConsumer eventConsumer) {
    return appView
        .getSyntheticItems()
        .ensureFixedClass(
            SyntheticNaming.SyntheticKind.EMULATED_INTERFACE_CLASS,
            emulatedInterface,
            appView,
            builder ->
                synthesizeEmulateInterfaceMethods(
                    emulatedInterface, emulatedInterfaceDescriptor, builder),
            eventConsumer::acceptProgramEmulatedInterface);
  }

  private void synthesizeEmulateInterfaceMethods(
      DexProgramClass emulatedInterface,
      EmulatedInterfaceDescriptor emulatedInterfaceDescriptor,
      SyntheticProgramClassBuilder builder) {
    emulatedInterface.forEachProgramVirtualMethodMatching(
        m -> emulatedInterfaceDescriptor.getEmulatedMethods().containsKey(m.getReference()),
        method ->
            builder.addMethod(
                methodBuilder ->
                    synthesizeEmulatedInterfaceMethod(
                        method,
                        emulatedInterfaceDescriptor.getEmulatedMethods().get(method.getReference()),
                        builder.getType(),
                        methodBuilder)));
  }

  private DexMethod emulatedMethod(DerivedMethod method, DexType holder) {
    assert method.getHolderKind() == SyntheticKind.EMULATED_INTERFACE_CLASS;
    DexProto newProto = appView.dexItemFactory().prependHolderToProto(method.getMethod());
    return appView.dexItemFactory().createMethod(holder, newProto, method.getName());
  }

  private DexMethod interfaceMethod(DerivedMethod method) {
    assert method.getHolderKind() == null;
    return method.getMethod();
  }

  private void synthesizeEmulatedInterfaceMethod(
      ProgramMethod method,
      EmulatedDispatchMethodDescriptor descriptor,
      DexType dispatchType,
      SyntheticMethodBuilder methodBuilder) {
    assert !method.getDefinition().isStatic();
    DexMethod emulatedMethod =
        helper.emulatedInterfaceDispatchMethod(
            descriptor.getEmulatedDispatchMethod(), dispatchType);
    DexMethod itfMethod = helper.emulatedInterfaceInterfaceMethod(descriptor.getInterfaceMethod());
    DexMethod companionMethod =
        helper.ensureEmulatedInterfaceForwardingMethod(descriptor.getForwardingMethod());
    LinkedHashMap<DexType, DexMethod> extraDispatchCases = resolveDispatchCases(descriptor);
    methodBuilder
        .setName(emulatedMethod.getName())
        .setProto(emulatedMethod.getProto())
        .setAccessFlags(MethodAccessFlags.createPublicStaticSynthetic())
        .setCode(
            emulatedInterfaceMethod ->
                new EmulateDispatchSyntheticCfCodeProvider(
                        emulatedMethod.getHolderType(),
                        companionMethod,
                        itfMethod,
                        extraDispatchCases,
                        appView)
                    .generateCfCode());
  }

  private LinkedHashMap<DexType, DexMethod> resolveDispatchCases(
      EmulatedDispatchMethodDescriptor descriptor) {
    LinkedHashMap<DexType, DexMethod> extraDispatchCases = new LinkedHashMap<>();
    descriptor
        .getDispatchCases()
        .forEach(
            (type, derivedMethod) ->
                extraDispatchCases.put(
                    type, helper.ensureEmulatedInterfaceForwardingMethod(derivedMethod)));
    return extraDispatchCases;
  }

  @Override
  public void synthesizeClasses(CfClassSynthesizerDesugaringEventConsumer eventConsumer) {
    assert appView.options().isDesugaredLibraryCompilation();
    appView
        .options()
        .machineDesugaredLibrarySpecification
        .getEmulatedInterfaces()
        .forEach(
            (emulatedInterfaceType, emulatedInterfaceDescriptor) -> {
              DexClass emulatedInterfaceClazz = appView.definitionFor(emulatedInterfaceType);
              if (emulatedInterfaceClazz == null || !emulatedInterfaceClazz.isProgramClass()) {
                warnMissingEmulatedInterface(emulatedInterfaceType);
                return;
              }
              DexProgramClass emulatedInterface = emulatedInterfaceClazz.asProgramClass();
              assert emulatedInterface != null;
              if (!appView.isAlreadyLibraryDesugared(emulatedInterface)
                  && !emulatedInterfaceDescriptor.getEmulatedMethods().isEmpty()) {
                synthesizeProgramEmulatedInterface(
                    emulatedInterface, emulatedInterfaceDescriptor, eventConsumer);
              }
            });
  }

  private void warnMissingEmulatedInterface(DexType interfaceType) {
    StringDiagnostic warning =
        new StringDiagnostic(
            "Cannot emulate interface "
                + interfaceType.getName()
                + " because the interface is missing.");
    appView.options().reporter.warning(warning);
  }
}
