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

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