// Copyright (c) 2017, 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;

import static com.android.tools.r8.ir.desugar.LambdaClass.JAVAC_EXPECTED_LAMBDA_METHOD_PREFIX;

import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexCallSite;
import com.android.tools.r8.graph.DexDefinitionSupplier;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexMethodHandle;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ProgramMethod;
import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Consumer;

// Represents the lambda descriptor inferred from calls site.
public final class LambdaDescriptor {
  private static final int LAMBDA_ALT_SERIALIZABLE = 1;
  private static final int LAMBDA_ALT_HAS_EXTRA_INTERFACES = 2;
  private static final int LAMBDA_ALT_HAS_BRIDGES = 4;
  private static final int LAMBDA_ALT_MASK = LAMBDA_ALT_SERIALIZABLE
      | LAMBDA_ALT_HAS_EXTRA_INTERFACES | LAMBDA_ALT_HAS_BRIDGES;

  static final LambdaDescriptor MATCH_FAILED = new LambdaDescriptor();

  final String uniqueId;
  final DexMethod mainMethod;
  public final DexString name;
  final DexProto erasedProto;
  final DexProto enforcedProto;
  public final DexMethodHandle implHandle;

  public final List<DexType> interfaces = new ArrayList<>();
  final Set<DexProto> bridges = Sets.newIdentityHashSet();
  public final DexTypeList captures;

  // Used for accessibility analysis and few assertions only.
  private final MethodAccessFlags targetAccessFlags;
  private final DexType targetHolder;

  private LambdaDescriptor() {
    uniqueId = null;
    name = null;
    erasedProto = null;
    enforcedProto = null;
    implHandle = null;
    captures = null;
    targetAccessFlags = null;
    targetHolder = null;
    mainMethod = null;
  }

  public DexMethod getMainMethod() {
    return mainMethod;
  }

  private LambdaDescriptor(
      AppInfoWithClassHierarchy appInfo,
      ProgramMethod context,
      DexCallSite callSite,
      DexString name,
      DexProto erasedProto,
      DexProto enforcedProto,
      DexMethodHandle implHandle,
      DexType mainInterface,
      DexTypeList captures) {
    assert appInfo != null;
    assert callSite != null;
    assert name != null;
    assert erasedProto != null;
    assert enforcedProto != null;
    assert implHandle != null;
    assert mainInterface != null;
    assert captures != null;
    this.mainMethod = appInfo.dexItemFactory().createMethod(mainInterface, erasedProto, name);
    this.uniqueId = callSite.getHash();
    this.name = name;
    this.erasedProto = erasedProto;
    this.enforcedProto = enforcedProto;
    this.implHandle = implHandle;
    this.captures = captures;

    this.interfaces.add(mainInterface);
    DexEncodedMethod targetMethod = context == null ? null : lookupTargetMethod(appInfo, context);
    if (targetMethod != null) {
      targetAccessFlags = targetMethod.accessFlags.copy();
      targetHolder = targetMethod.getHolderType();
    } else {
      targetAccessFlags = null;
      targetHolder = null;
    }
  }

  final DexType getImplReceiverType() {
    // The receiver of instance impl-method is captured as the first captured
    // value or should be the first argument of the enforced method signature.
    DexType[] params = enforcedProto.parameters.values;
    DexType[] captures = this.captures.values;
    assert captures.length > 0 || params.length > 0;
    return captures.length > 0 ? captures[0] : params[0];
  }

  private DexEncodedMethod lookupTargetMethod(
      AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
    assert context != null;
    // Find the lambda's impl-method target.
    DexMethod method = implHandle.asMethod();
    switch (implHandle.type) {
      case INVOKE_DIRECT:
      case INVOKE_INSTANCE: {
          DexEncodedMethod target =
              appInfo
                  .resolveMethodOn(getImplReceiverType(), method, implHandle.isInterface)
                  .getSingleTarget();
        if (target == null) {
            target = appInfo.lookupDirectTarget(method, context);
        }
        assert target == null
            || (implHandle.type.isInvokeInstance() && isInstanceMethod(target))
            || (implHandle.type.isInvokeDirect() && isPrivateInstanceMethod(target))
            || (implHandle.type.isInvokeDirect() && isPublicizedInstanceMethod(target));
        return target;
      }

      case INVOKE_STATIC: {
          DexEncodedMethod target = appInfo.lookupStaticTarget(method, context);
        assert target == null || target.accessFlags.isStatic();
        return target;
      }

      case INVOKE_CONSTRUCTOR: {
          DexEncodedMethod target = appInfo.lookupDirectTarget(method, context);
        assert target == null || target.accessFlags.isConstructor();
        return target;
      }

      case INVOKE_INTERFACE: {
          DexEncodedMethod target =
              appInfo.resolveMethodOnInterface(getImplReceiverType(), method).getSingleTarget();
        assert target == null || isInstanceMethod(target);
        return target;
      }

      default:
        throw new Unreachable("Unexpected method handle kind in " + implHandle);
    }
  }

  private boolean isInstanceMethod(DexEncodedMethod encodedMethod) {
    assert encodedMethod != null;
    return !encodedMethod.accessFlags.isConstructor() && !encodedMethod.isStatic();
  }

  private boolean isPrivateInstanceMethod(DexEncodedMethod encodedMethod) {
    assert encodedMethod != null;
    return encodedMethod.isPrivateMethod() && isInstanceMethod(encodedMethod);
  }

  private boolean isPublicizedInstanceMethod(DexEncodedMethod encodedMethod) {
    assert encodedMethod != null;
    return encodedMethod.isPublicized() && isInstanceMethod(encodedMethod);
  }

  public final boolean verifyTargetFoundInClass(DexType type) {
    return targetHolder == type;
  }

  public boolean canAccessModifyLambdaImplementationMethods(AppView<?> appView) {
    return appView.enableWholeProgramOptimizations();
  }

  /** If the lambda delegates to lambda$ method. */
  public boolean delegatesToLambdaImplMethod() {
    String methodName = implHandle.asMethod().getName().toString();
    return methodName.startsWith(JAVAC_EXPECTED_LAMBDA_METHOD_PREFIX);
  }

  /** Is a stateless lambda, i.e. lambda does not capture any values */
  final boolean isStateless() {
    return captures.isEmpty();
  }

  /** Checks if call site needs a accessor when referenced from `accessedFrom`. */
  boolean needsAccessor(AppView<?> appView, ProgramMethod accessedFrom) {
    if (appView.options().canAccessModifyLambdaImplementationMethods(appView)
        && delegatesToLambdaImplMethod()) {
      return false;
    }

    if (implHandle.type.isInvokeInterface()) {
      // Interface methods must be public.
      return false;
    }

    boolean staticTarget = implHandle.type.isInvokeStatic();
    boolean instanceTarget = implHandle.type.isInvokeInstance() || implHandle.type.isInvokeDirect();
    boolean initTarget = implHandle.type.isInvokeConstructor();
    assert instanceTarget || staticTarget || initTarget;
    assert !implHandle.type.isInvokeDirect()
        || (targetAccessFlags.isPrivate()
            && !targetAccessFlags.isConstructor()
            && !targetAccessFlags.isStatic());

    if (targetAccessFlags == null) {
      // The target cannot be a private method, since otherwise it
      // should have been found.

      if (staticTarget || initTarget) {
        // Create accessor only in case it is accessed from other
        // package, since otherwise it can be called directly.
        // NOTE: This case is different from regular instance method case
        // because the method being called must be present in method holder,
        // and not in one from its supertypes.
        boolean accessedFromSamePackage =
            accessedFrom
                .getHolderType()
                .getPackageDescriptor()
                .equals(implHandle.asMethod().holder.getPackageDescriptor());
        return !accessedFromSamePackage;
      }

      // Since instance method was not found, always generate an accessor
      // since it may be a protected method located in another package.
      return true;
    }

    MethodAccessFlags flags = targetAccessFlags;

    // Private methods always need accessors.
    if (flags.isPrivate()) {
      return true;
    }
    if (flags.isPublic()) {
      return false;
    }

    boolean accessedFromSamePackage =
        accessedFrom
            .getHolderType()
            .getPackageDescriptor()
            .equals(targetHolder.getPackageDescriptor());
    assert flags.isProtected() || accessedFromSamePackage;
    return flags.isProtected() && !accessedFromSamePackage;
  }

  /**
   * Matches call site for lambda metafactory invocation pattern and returns extracted match
   * information, or null if match failed.
   */
  public static LambdaDescriptor tryInfer(
      DexCallSite callSite, AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
    LambdaDescriptor descriptor = infer(callSite, appInfo, context);
    return descriptor == MATCH_FAILED ? null : descriptor;
  }

  public static boolean isLambdaMetafactoryMethod(
      DexCallSite callSite, DexDefinitionSupplier definitions) {
    return callSite.bootstrapMethod.type.isInvokeStatic()
        && definitions
            .dexItemFactory()
            .isLambdaMetafactoryMethod(callSite.bootstrapMethod.asMethod());
  }

  /**
   * Matches call site for lambda metafactory invocation pattern and returns extracted match
   * information, or MATCH_FAILED if match failed.
   */
  static LambdaDescriptor infer(
      DexCallSite callSite, AppInfoWithClassHierarchy appInfo, ProgramMethod context) {
    if (!isLambdaMetafactoryMethod(callSite, appInfo)) {
      return LambdaDescriptor.MATCH_FAILED;
    }

    DexItemFactory factory = appInfo.dexItemFactory();
    DexMethod bootstrapMethod = callSite.bootstrapMethod.asMethod();

    // 'Method name' operand of the invoke-custom instruction represents
    // the name of the functional interface main method.
    DexString funcMethodName = callSite.methodName;

    // Signature of main functional interface method.
    DexValue.DexValueMethodType funcErasedSignature =
        getBootstrapArgument(callSite.bootstrapArgs, 0, DexValue.DexValueMethodType.class);

    // Method handle of the implementation method.
    DexMethodHandle lambdaImplMethodHandle =
        getBootstrapArgument(callSite.bootstrapArgs, 1, DexValue.DexValueMethodHandle.class).value;
    // Even though there are some limitations on which method handle kinds are
    // allowed for lambda impl-methods, there is no way to detect unsupported
    // handle kinds after they are transformed into DEX method handle.

    // Signature to be enforced on main method.
    DexValue.DexValueMethodType funcEnforcedSignature =
        getBootstrapArgument(callSite.bootstrapArgs, 2, DexValue.DexValueMethodType.class);
    if (!isEnforcedSignatureValid(
        factory, funcEnforcedSignature.value, funcErasedSignature.value)) {
      throw new Unreachable(
          "Enforced and erased signatures are inconsistent in " + callSite.toString());
    }

    // 'Method type' of the invoke-custom instruction represents the signature
    // of the lambda method factory.
    DexProto lambdaFactoryProto = callSite.methodProto;
    // Main functional interface is the return type of the lambda factory method.
    DexType mainFuncInterface = lambdaFactoryProto.returnType;
    // Lambda captures are represented as parameters of the lambda factory method.
    DexTypeList captures = lambdaFactoryProto.parameters;

    // Create a match.
    LambdaDescriptor match =
        new LambdaDescriptor(
            appInfo,
            context,
            callSite,
            funcMethodName,
            funcErasedSignature.value,
            funcEnforcedSignature.value,
            lambdaImplMethodHandle,
            mainFuncInterface,
            captures);

    if (bootstrapMethod == factory.metafactoryMethod) {
      if (callSite.bootstrapArgs.size() != 3) {
        throw new Unreachable(
            "Unexpected number of metafactory method arguments in " + callSite.toString());
      }
    } else {
      extractAltMetafactory(
          factory,
          callSite.bootstrapArgs,
          interfaceType -> {
            if (!match.interfaces.contains(interfaceType)) {
              match.interfaces.add(interfaceType);
            }
          },
          match.bridges::add);
    }

    return match;
  }

  private static void extractAltMetafactory(
      DexItemFactory dexItemFactory,
      List<DexValue> bootstrapArgs,
      Consumer<DexType> interfaceConsumer,
      Consumer<DexProto> bridgeConsumer) {
    int argIndex = 3;
    int flagsArg =
        getBootstrapArgument(bootstrapArgs, argIndex++, DexValue.DexValueInt.class).value;
    assert (flagsArg & ~LAMBDA_ALT_MASK) == 0;

    // Load extra interfaces if any.
    if ((flagsArg & LAMBDA_ALT_HAS_EXTRA_INTERFACES) != 0) {
      int count = getBootstrapArgument(bootstrapArgs, argIndex++, DexValue.DexValueInt.class).value;
      for (int i = 0; i < count; i++) {
        DexType interfaceType =
            getBootstrapArgument(bootstrapArgs, argIndex++, DexValue.DexValueType.class).value;
        interfaceConsumer.accept(interfaceType);
      }
    }

    // If the lambda is serializable, add it.
    if ((flagsArg & LAMBDA_ALT_SERIALIZABLE) != 0) {
      interfaceConsumer.accept(dexItemFactory.serializableType);
    }

    // Load bridges if any.
    if ((flagsArg & LAMBDA_ALT_HAS_BRIDGES) != 0) {
      int count = getBootstrapArgument(bootstrapArgs, argIndex++, DexValue.DexValueInt.class).value;
      for (int i = 0; i < count; i++) {
        DexProto bridgeProto =
            getBootstrapArgument(bootstrapArgs, argIndex++, DexValue.DexValueMethodType.class)
                .value;
        bridgeConsumer.accept(bridgeProto);
      }
    }

    if (bootstrapArgs.size() != argIndex) {
      throw new Unreachable("Unexpected number of metafactory method arguments in DexCallSite");
    }
  }

  public static List<DexType> getInterfaces(
      DexCallSite callSite, AppInfoWithClassHierarchy appInfo) {
    // No need for the invocationContext to figure out only the interfaces.
    LambdaDescriptor descriptor = infer(callSite, appInfo, null);
    if (descriptor == LambdaDescriptor.MATCH_FAILED) {
      return null;
    }
    return descriptor.interfaces;
  }

  @SuppressWarnings("unchecked")
  private static <T> T getBootstrapArgument(List<DexValue> bootstrapArgs, int i, Class<T> clazz) {
    if (bootstrapArgs.size() < i) {
      throw new Unreachable(
          "Expected to find at least " + i + " bootstrap arguments in DexCallSite");
    }
    DexValue value = bootstrapArgs.get(i);
    if (!clazz.isAssignableFrom(value.getClass())) {
      throw new Unreachable("Unexpected type of bootstrap arguments #" + i + " in DexCallSite");
    }
    return (T) value;
  }

  private static boolean isEnforcedSignatureValid(
      DexItemFactory factory, DexProto enforced, DexProto erased) {
    if (!isSameOrDerived(factory, enforced.returnType, erased.returnType)) {
      return false;
    }
    DexType[] enforcedValues = enforced.parameters.values;
    DexType[] erasedValues = erased.parameters.values;
    int count = enforcedValues.length;
    if (count != erasedValues.length) {
      return false;
    }
    for (int i = 0; i < count; i++) {
      if (!isSameOrDerived(factory, enforcedValues[i], erasedValues[i])) {
        return false;
      }
    }
    return true;
  }

  // Checks if the types are the same OR both types are reference types and
  // `subType` is derived from `b`. Note that in the latter case we only check if
  // both types are class types, for the reasons mentioned in isSameOrAdaptableTo(...).
  static boolean isSameOrDerived(
      DexItemFactory factory, DexType subType, DexType superType) {
    if (subType == superType || (subType.isClassType() && superType.isClassType())) {
      return true;
    }

    if (subType.isArrayType()) {
      if (superType.isArrayType()) {
        // X[] -> Y[].
        return isSameOrDerived(factory,
            subType.toArrayElementType(factory), superType.toArrayElementType(factory));
      }
      return superType == factory.objectType; // T[] -> Object.
    }

    return false;
  }
}
