// 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 com.android.tools.r8.errors.Unreachable;
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.DexType;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.ir.code.Invoke;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.IRBuilder;
import java.util.ArrayList;
import java.util.List;

// Source code representing synthesized accessor method.
final class AccessorMethodSourceCode extends SynthesizedLambdaSourceCode {

  AccessorMethodSourceCode(LambdaClass lambda, Position callerPosition) {
    super(
        lambda, lambda.target.callTarget, callerPosition, null /* no receiver for static method */);
    // We should never need an accessor for interface methods since
    // they are supposed to be public.
    assert !descriptor().implHandle.type.isInvokeInterface();
    assert checkSignatures();
  }

  private boolean checkSignatures() {
    DexMethodHandle implHandle = descriptor().implHandle;
    assert implHandle != null;

    DexType[] accessorParams = proto.parameters.values;
    DexMethod implMethod = implHandle.asMethod();
    DexProto implProto = implMethod.proto;
    DexType[] implParams = implProto.parameters.values;

    int index = 0;
    if (implHandle.type.isInvokeInstance() || implHandle.type.isInvokeDirect()) {
      assert accessorParams[index] == descriptor().getImplReceiverType();
      index++;
    }

    for (DexType implParam : implParams) {
      assert accessorParams[index] == implParam;
      index++;
    }
    assert index == accessorParams.length;

    assert delegatingToConstructor()
        ? this.proto.returnType == implMethod.holder
        : this.proto.returnType == implProto.returnType;
    return true;
  }

  private boolean isPrivateMethod() {
    // We should be able to find targets for all private impl-methods, so
    // we can rely on knowing accessibility flags for them.
    MethodAccessFlags flags = descriptor().getAccessibility();
    return flags != null && flags.isPrivate();
  }

  // Are we delegating to a constructor?
  private boolean delegatingToConstructor() {
    return descriptor().implHandle.type.isInvokeConstructor();
  }

  private Invoke.Type inferInvokeType() {
    switch (descriptor().implHandle.type) {
      case INVOKE_INSTANCE:
        return Invoke.Type.VIRTUAL;
      case INVOKE_STATIC:
        return Invoke.Type.STATIC;
      case INVOKE_DIRECT:
      case INVOKE_CONSTRUCTOR:
        return Invoke.Type.DIRECT;
      case INVOKE_INTERFACE:
        throw new Unreachable("Accessor for an interface method?");
      default:
        throw new Unreachable();
    }
  }

  @Override
  protected void prepareInstructions() {
    DexMethod implMethod = descriptor().implHandle.asMethod();
    DexType[] accessorParams = proto.parameters.values;

    // Prepare call arguments.
    List<ValueType> argValueTypes = new ArrayList<>();
    List<Integer> argRegisters = new ArrayList<>();

    // If we are delegating to a constructor, we need to create the instance
    // first. This instance will be the first argument to the call.
    if (delegatingToConstructor()) {
      int instance = nextRegister(ValueType.OBJECT);
      add(builder -> builder.addNewInstance(instance, implMethod.holder));
      argValueTypes.add(ValueType.OBJECT);
      argRegisters.add(instance);
    }

    for (int i = 0; i < accessorParams.length; i++) {
      DexType param = accessorParams[i];
      argValueTypes.add(ValueType.fromDexType(param));
      argRegisters.add(getParamRegister(i));
    }

    // Method call to the original impl-method.
    // Mirroring assert in constructor, we never need accessors to interfaces.
    assert !descriptor().implHandle.type.isInvokeInterface();
    add(
        builder ->
            builder.addInvoke(
                inferInvokeType(),
                implMethod,
                implMethod.proto,
                argValueTypes,
                argRegisters,
                false /* isInterface */));

    // Does the method have return value?
    if (proto.returnType == factory().voidType) {
      add(IRBuilder::addReturn);
    } else if (delegatingToConstructor()) {
      // Return newly created instance
      add(builder -> builder.addReturn(argRegisters.get(0)));
    } else {
      ValueType valueType = ValueType.fromDexType(proto.returnType);
      int tempValue = nextRegister(valueType);
      add(builder -> builder.addMoveResult(tempValue));
      add(builder -> builder.addReturn(tempValue));
    }
  }
}
