// 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.contexts.CompilationContext.MethodProcessingContext;
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.CfInstructionDesugaringEventConsumer;
import com.android.tools.r8.ir.desugar.FreshLocalProvider;
import com.android.tools.r8.ir.desugar.LocalStackAllocator;
import com.android.tools.r8.ir.synthetic.ForwardMethodBuilder;
import com.google.common.collect.ImmutableList;
import java.util.Collection;
import java.util.List;
import org.objectweb.asm.Opcodes;

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

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

  private final DexItemFactory dexItemFactory;

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

  @Override
  public boolean needsDesugaring(CfInstruction instruction, ProgramMethod context) {
    if (instruction.isInvokeSpecial()) {
      return needsDesugaring(instruction.asInvoke(), context) != null;
    }
    return false;
  }

  /** @return the resolved method if desugaring is needed, otherwise null. */
  private ProgramMethod needsDesugaring(CfInvoke invoke, ProgramMethod context) {
    if (!invoke.isInvokeSpecial() || invoke.isInvokeConstructor(dexItemFactory)) {
      return null;
    }

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

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

    return method;
  }

  @Override
  public Collection<CfInstruction> desugarInstruction(
      CfInstruction instruction,
      FreshLocalProvider freshLocalProvider,
      LocalStackAllocator localStackAllocator,
      CfInstructionDesugaringEventConsumer eventConsumer,
      ProgramMethod context,
      MethodProcessingContext methodProcessingContext,
      DexItemFactory dexItemFactory) {
    if (instruction.isInvokeSpecial()) {
      return desugarInvokeInstruction(instruction.asInvoke(), eventConsumer, context);
    }
    return null;
  }

  private List<CfInstruction> desugarInvokeInstruction(
      CfInvoke invoke,
      InvokeSpecialToSelfDesugaringEventConsumer eventConsumer,
      ProgramMethod context) {
    ProgramMethod method = needsDesugaring(invoke, context);
    if (method == null) {
      return null;
    }

    if (method.getAccessFlags().isFinal()) {
      // This method is final thus we can use invoke-virtual.
      return ImmutableList.of(
          new CfInvoke(Opcodes.INVOKEVIRTUAL, invoke.getMethod(), invoke.isInterface()));
    }

    // This is an invoke-special to a virtual method on invoke-special method holder.
    // The invoke should be rewritten with a bridge.
    DexMethod bridgeMethod = ensureInvokeSpecialBridge(method, eventConsumer);
    return ImmutableList.of(
        new CfInvoke(Opcodes.INVOKESPECIAL, bridgeMethod, invoke.isInterface()));
  }

  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);
  }
}
