// Copyright (c) 2023, 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.code;

import com.android.tools.r8.dex.code.DexInvokeCustom;
import com.android.tools.r8.dex.code.DexInvokeCustomRange;
import com.android.tools.r8.dex.code.DexInvokeDirect;
import com.android.tools.r8.dex.code.DexInvokeDirectRange;
import com.android.tools.r8.dex.code.DexInvokeInterface;
import com.android.tools.r8.dex.code.DexInvokeInterfaceRange;
import com.android.tools.r8.dex.code.DexInvokePolymorphic;
import com.android.tools.r8.dex.code.DexInvokePolymorphicRange;
import com.android.tools.r8.dex.code.DexInvokeStatic;
import com.android.tools.r8.dex.code.DexInvokeStaticRange;
import com.android.tools.r8.dex.code.DexInvokeSuper;
import com.android.tools.r8.dex.code.DexInvokeSuperRange;
import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexInvokeVirtualRange;
import com.android.tools.r8.dex.code.DexNewArray;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexClassAndMethod;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle.MethodHandleType;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.GraphLens.MethodLookupResult;
import org.objectweb.asm.Opcodes;

public enum InvokeType {
  DIRECT(DexInvokeDirect.OPCODE, DexInvokeDirectRange.OPCODE),
  INTERFACE(DexInvokeInterface.OPCODE, DexInvokeInterfaceRange.OPCODE),
  STATIC(DexInvokeStatic.OPCODE, DexInvokeStaticRange.OPCODE),
  SUPER(DexInvokeSuper.OPCODE, DexInvokeSuperRange.OPCODE),
  VIRTUAL(DexInvokeVirtual.OPCODE, DexInvokeVirtualRange.OPCODE),
  NEW_ARRAY(DexNewArray.OPCODE, Invoke.NO_SUCH_DEX_INSTRUCTION),
  MULTI_NEW_ARRAY(Invoke.NO_SUCH_DEX_INSTRUCTION, Invoke.NO_SUCH_DEX_INSTRUCTION),
  CUSTOM(DexInvokeCustom.OPCODE, DexInvokeCustomRange.OPCODE),
  POLYMORPHIC(DexInvokePolymorphic.OPCODE, DexInvokePolymorphicRange.OPCODE);

  private final int dexOpcode;
  private final int dexOpcodeRange;

  InvokeType(int dexOpcode, int dexOpcodeRange) {
    this.dexOpcode = dexOpcode;
    this.dexOpcodeRange = dexOpcodeRange;
  }

  public static InvokeType fromCfOpcode(
      int opcode, DexMethod invokedMethod, DexClassAndMethod context, AppView<?> appView) {
    return fromCfOpcode(opcode, invokedMethod, context, appView, appView.codeLens());
  }

  public static InvokeType fromCfOpcode(
      int opcode,
      DexMethod invokedMethod,
      DexClassAndMethod context,
      AppView<?> appView,
      GraphLens codeLens) {
    switch (opcode) {
      case org.objectweb.asm.Opcodes.INVOKEINTERFACE:
        return InvokeType.INTERFACE;
      case org.objectweb.asm.Opcodes.INVOKESPECIAL:
        return fromInvokeSpecial(invokedMethod, context, appView, codeLens);
      case org.objectweb.asm.Opcodes.INVOKESTATIC:
        return InvokeType.STATIC;
      case org.objectweb.asm.Opcodes.INVOKEVIRTUAL:
        return appView.dexItemFactory().polymorphicMethods.isPolymorphicInvoke(invokedMethod)
                && !appView.options().shouldDesugarVarHandle()
            ? InvokeType.POLYMORPHIC
            : InvokeType.VIRTUAL;
      default:
        throw new Unreachable("unknown CfInvoke opcode " + opcode);
    }
  }

  public static InvokeType fromInvokeSpecial(
      DexMethod invokedMethod, DexClassAndMethod context, AppView<?> appView, GraphLens codeLens) {
    if (invokedMethod.isInstanceInitializer(appView.dexItemFactory())) {
      return InvokeType.DIRECT;
    }

    GraphLens graphLens = appView.graphLens();
    DexMethod originalContext =
        graphLens.getOriginalMethodSignature(context.getReference(), codeLens);
    if (invokedMethod.getHolderType() != originalContext.getHolderType()) {
      if (appView.options().isGeneratingDex()
          && appView.options().canUseNestBasedAccess()
          && context.getHolder().isInANest()) {
        DexClass holderType = appView.definitionFor(invokedMethod.getHolderType());
        if (holderType != null
            && holderType.isInANest()
            && holderType.isInSameNest(context.getHolder())) {
          return InvokeType.DIRECT;
        }
      }
      return InvokeType.SUPER;
    }

    MethodLookupResult lookupResult =
        graphLens.lookupMethod(invokedMethod, context.getReference(), InvokeType.DIRECT);
    if (lookupResult.getType().isStatic()) {
      // This method has been staticized. The original invoke-type is DIRECT.
      return InvokeType.DIRECT;
    }
    if (lookupResult.getType().isVirtual()) {
      // This method has been publicized. The original invoke-type is DIRECT.
      return InvokeType.DIRECT;
    }

    DexEncodedMethod definition = context.getHolder().lookupMethod(lookupResult.getReference());
    if (definition == null) {
      return InvokeType.SUPER;
    }

    // If the definition was moved to the current context from a super class due to vertical class
    // merging, then this used to be an invoke-super.
    DexType originalHolderOfDefinition =
        graphLens.getOriginalMethodSignature(definition.getReference(), codeLens).getHolderType();
    if (originalHolderOfDefinition != originalContext.getHolderType()) {
      return InvokeType.SUPER;
    }

    boolean originalContextIsInterface =
        context.getHolder().isInterface()
            || (appView.hasVerticallyMergedClasses()
                && appView
                    .verticallyMergedClasses()
                    .hasInterfaceBeenMergedIntoSubtype(originalContext.getHolderType()));
    if (originalContextIsInterface) {
      // On interfaces invoke-special should be mapped to invoke-super if the invoke-special
      // instruction is used to target a default interface method.
      if (definition.belongsToVirtualPool()) {
        return InvokeType.SUPER;
      }
    } else {
      // Due to desugaring of invoke-special instructions that target virtual methods, this should
      // never target a virtual method.
      assert definition.isPrivate() || lookupResult.getType().isVirtual();
    }

    return InvokeType.DIRECT;
  }

  public int getCfOpcode() {
    switch (this) {
      case DIRECT:
        return org.objectweb.asm.Opcodes.INVOKESPECIAL;
      case INTERFACE:
        return org.objectweb.asm.Opcodes.INVOKEINTERFACE;
      case POLYMORPHIC:
        return org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
      case STATIC:
        return org.objectweb.asm.Opcodes.INVOKESTATIC;
      case SUPER:
        return org.objectweb.asm.Opcodes.INVOKESPECIAL;
      case VIRTUAL:
        return Opcodes.INVOKEVIRTUAL;
      case NEW_ARRAY:
      case MULTI_NEW_ARRAY:
      default:
        throw new Unreachable();
    }
  }

  public int getDexOpcode() {
    assert dexOpcode >= 0;
    return dexOpcode;
  }

  public int getDexOpcodeRange() {
    assert dexOpcodeRange >= 0;
    return dexOpcodeRange;
  }

  public boolean isDirect() {
    return this == DIRECT;
  }

  public boolean isInterface() {
    return this == INTERFACE;
  }

  public boolean isStatic() {
    return this == STATIC;
  }

  public boolean isSuper() {
    return this == SUPER;
  }

  public boolean isVirtual() {
    return this == VIRTUAL;
  }

  public MethodHandleType toMethodHandle(DexMethod targetMethod) {
    switch (this) {
      case STATIC:
        return MethodHandleType.INVOKE_STATIC;
      case VIRTUAL:
        return MethodHandleType.INVOKE_INSTANCE;
      case DIRECT:
        if (targetMethod.name.toString().equals("<init>")) {
          return MethodHandleType.INVOKE_CONSTRUCTOR;
        } else {
          return MethodHandleType.INVOKE_DIRECT;
        }
      case INTERFACE:
        return MethodHandleType.INVOKE_INTERFACE;
      case SUPER:
        return MethodHandleType.INVOKE_SUPER;
      default:
        throw new Unreachable("Conversion to method handle with unexpected invoke type: " + this);
    }
  }
}
