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

import com.android.tools.r8.cf.code.CfCheckCast;
import com.android.tools.r8.cf.code.CfFrame;
import com.android.tools.r8.cf.code.CfIf;
import com.android.tools.r8.cf.code.CfInstanceOf;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.frame.FrameType;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.IfType;
import com.android.tools.r8.ir.code.ValueType;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.Opcodes;

public class EmulateDispatchSyntheticCfCodeProvider extends SyntheticCfCodeProvider {

  private final DexMethod forwardingMethod;
  private final DexMethod interfaceMethod;
  private final LinkedHashMap<DexType, DexMethod> extraDispatchCases;

  public EmulateDispatchSyntheticCfCodeProvider(
      DexType holder,
      DexMethod forwardingMethod,
      DexMethod interfaceMethod,
      LinkedHashMap<DexType, DexMethod> extraDispatchCases,
      AppView<?> appView) {
    super(appView, holder);
    this.forwardingMethod = forwardingMethod;
    this.interfaceMethod = interfaceMethod;
    this.extraDispatchCases = extraDispatchCases;
  }

  @Override
  public CfCode generateCfCode() {
    DexType receiverType = forwardingMethod.getParameter(0);
    List<CfInstruction> instructions = new ArrayList<>();
    CfLabel[] labels = new CfLabel[extraDispatchCases.size() + 1];
    for (int i = 0; i < labels.length; i++) {
      labels[i] = new CfLabel();
    }
    int nextLabel = 0;

    CfFrame frame =
        CfFrame.builder()
            .appendLocal(FrameType.initialized(receiverType))
            .apply(
                builder -> {
                  for (DexType parameter : interfaceMethod.getParameters()) {
                    builder.appendLocal(FrameType.initialized(parameter));
                  }
                })
            .build();

    instructions.add(new CfLoad(ValueType.fromDexType(receiverType), 0));
    instructions.add(new CfInstanceOf(interfaceMethod.holder));
    instructions.add(new CfIf(IfType.EQ, ValueType.INT, labels[nextLabel]));

    // Branch with library call.
    instructions.add(new CfLoad(ValueType.fromDexType(receiverType), 0));
    instructions.add(new CfCheckCast(interfaceMethod.holder));
    loadExtraParameters(instructions);
    instructions.add(new CfInvoke(Opcodes.INVOKEINTERFACE, interfaceMethod, true));
    addReturn(instructions);

    // SubInterface dispatch (subInterfaces are ordered).
    for (Map.Entry<DexType, DexMethod> dispatch : extraDispatchCases.entrySet()) {
      // Type check basic block.
      instructions.add(labels[nextLabel++]);
      instructions.add(frame);
      instructions.add(new CfLoad(ValueType.fromDexType(receiverType), 0));
      instructions.add(new CfInstanceOf(dispatch.getKey()));
      instructions.add(new CfIf(IfType.EQ, ValueType.INT, labels[nextLabel]));

      // Call basic block.
      instructions.add(new CfLoad(ValueType.fromDexType(receiverType), 0));
      instructions.add(new CfCheckCast(dispatch.getKey()));
      loadExtraParameters(instructions);
      instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, dispatch.getValue(), false));
      addReturn(instructions);
    }

    // Branch with companion call.
    instructions.add(labels[nextLabel]);
    instructions.add(frame.clone());
    instructions.add(new CfLoad(ValueType.fromDexType(receiverType), 0));
    loadExtraParameters(instructions);
    instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, forwardingMethod, false));
    addReturn(instructions);
    return standardCfCodeFromInstructions(instructions);
  }

  private void loadExtraParameters(List<CfInstruction> instructions) {
    int index = 1;
    for (DexType type : interfaceMethod.proto.parameters.values) {
      instructions.add(new CfLoad(ValueType.fromDexType(type), index++));
    }
  }

  private void addReturn(List<CfInstruction> instructions) {
    if (interfaceMethod.proto.returnType == appView.dexItemFactory().voidType) {
      instructions.add(new CfReturnVoid());
    } else {
      instructions.add(new CfReturn(ValueType.fromDexType(interfaceMethod.proto.returnType)));
    }
  }
}
