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

import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.desugar.CfInstructionDesugaring;
import com.android.tools.r8.ir.desugar.DesugarDescription;
import com.android.tools.r8.ir.synthetic.ForwardMethodBuilder;
import com.google.common.collect.ImmutableList;
import org.objectweb.asm.Opcodes;

/** This class defines the desugaring of a single invoke-special instruction. */
public class InvokeSpecialToSelfDesugaring implements CfInstructionDesugaring {

  public static final String INVOKE_SPECIAL_BRIDGE_PREFIX = "$invoke$special$";

  private final DexItemFactory dexItemFactory;

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

  @Override
  public DesugarDescription compute(CfInstruction instruction, ProgramMethod context) {
    if (!instruction.isInvokeSpecial()) {
      return DesugarDescription.nothing();
    }

    CfInvoke invoke = instruction.asInvoke();
    if (!invoke.isInvokeSpecial() || invoke.isInvokeConstructor(dexItemFactory)) {
      return DesugarDescription.nothing();
    }

    DexMethod invokedMethod = invoke.getMethod();
    if (invokedMethod.getHolderType() != context.getHolderType()) {
      return DesugarDescription.nothing();
    }

    ProgramMethod method = context.getHolder().lookupProgramMethod(invokedMethod);
    if (method == null
        || method.getAccessFlags().isPrivate()
        || method.getDefinition().isStatic()
        || (invoke.isInterface() && method.isDefaultMethod())) {
      return DesugarDescription.nothing();
    }

    if (method.getAccessFlags().isFinal()) {
      // This method is final thus we can use invoke-virtual.
      return desugarToInvokeVirtual(invoke);
    }

    // This is an invoke-special to a virtual method on invoke-special method holder.
    // The invoke should be rewritten with a bridge.
    return desugarWithBridge(invoke, method);
  }

  private DesugarDescription desugarToInvokeVirtual(CfInvoke invoke) {
    return DesugarDescription.builder()
        .setDesugarRewrite(
            (freshLocalProvider,
                localStackAllocator,
                eventConsumer,
                context,
                methodProcessingContext,
                desugaringCollection,
                dexItemFactory) ->
                ImmutableList.of(
                    new CfInvoke(Opcodes.INVOKEVIRTUAL, invoke.getMethod(), invoke.isInterface())))
        .build();
  }

  private DesugarDescription desugarWithBridge(CfInvoke invoke, ProgramMethod method) {
    return DesugarDescription.builder()
        .setDesugarRewrite(
            (freshLocalProvider,
                localStackAllocator,
                eventConsumer,
                context,
                methodProcessingContext,
                desugaringCollection,
                dexItemFactory) ->
                ImmutableList.of(
                    new CfInvoke(
                        Opcodes.INVOKESPECIAL,
                        ensureInvokeSpecialBridge(method, eventConsumer),
                        invoke.isInterface())))
        .build();
  }

  private DexMethod ensureInvokeSpecialBridge(
      ProgramMethod method, InvokeSpecialToSelfDesugaringEventConsumer eventConsumer) {
    DexMethod bridgeReference = getInvokeSpecialBridgeReference(method);
    DexProgramClass clazz = method.getHolder();
    synchronized (clazz.getMethodCollection()) {
      if (clazz.lookupProgramMethod(bridgeReference) == null) {
        // Create a new private method holding the code of the virtual method.
        ProgramMethod newDirectMethod =
            method.getDefinition().toPrivateSyntheticMethod(clazz, bridgeReference);

        // Create the new cf code object for the virtual method.
        CfCode virtualMethodCode =
            ForwardMethodBuilder.builder(dexItemFactory)
                .setDirectTarget(bridgeReference, clazz.isInterface())
                .setNonStaticSource(method.getReference())
                .build();

        // Add the newly created direct method to its holder.
        clazz.addDirectMethod(newDirectMethod.getDefinition());

        eventConsumer.acceptInvokeSpecialBridgeInfo(
            new InvokeSpecialBridgeInfo(newDirectMethod, method, virtualMethodCode));
      }
    }
    return bridgeReference;
  }

  private DexMethod getInvokeSpecialBridgeReference(DexClassAndMethod method) {
    return method
        .getReference()
        .withName(
            dexItemFactory.createString(INVOKE_SPECIAL_BRIDGE_PREFIX + method.getName().toString()),
            dexItemFactory);
  }
}
