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

import com.android.tools.r8.cf.code.CfConstClass;
import com.android.tools.r8.cf.code.CfConstNull;
import com.android.tools.r8.cf.code.CfConstNumber;
import com.android.tools.r8.cf.code.CfConstString;
import com.android.tools.r8.cf.code.CfDexItemBasedConstString;
import com.android.tools.r8.cf.code.CfInstanceFieldWrite;
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.CfPosition;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.CfSafeCheckCast;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLens;
import com.android.tools.r8.graph.GraphLens.MethodLookupResult;
import com.android.tools.r8.graph.ProgramMethod;
import com.android.tools.r8.ir.analysis.value.SingleConstValue;
import com.android.tools.r8.ir.analysis.value.SingleDexItemBasedStringValue;
import com.android.tools.r8.ir.code.Position;
import com.android.tools.r8.ir.code.Position.SyntheticPosition;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.conversion.ExtraParameter;
import com.android.tools.r8.ir.optimize.info.field.InstanceFieldInitializationInfo;
import com.android.tools.r8.utils.IntBox;
import com.google.common.collect.ImmutableList;
import java.util.List;
import java.util.Map;
import org.objectweb.asm.Opcodes;

/**
 * Similar to CfCode, but with a marker that makes it possible to recognize this is synthesized by
 * the horizontal class merger.
 */
public class IncompleteMergedInstanceInitializerCode extends IncompleteHorizontalClassMergerCode {

  private final DexField classIdField;
  private final int extraNulls;
  private final DexMethod originalMethodReference;
  private final DexMethod syntheticMethodReference;

  private final Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPre;
  private final Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPost;

  private final DexMethod parentConstructor;
  private final List<InstanceFieldInitializationInfo> parentConstructorArguments;

  IncompleteMergedInstanceInitializerCode(
      DexField classIdField,
      int extraNulls,
      DexMethod originalMethodReference,
      DexMethod syntheticMethodReference,
      Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPre,
      Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignmentsPost,
      DexMethod parentConstructor,
      List<InstanceFieldInitializationInfo> parentConstructorArguments) {
    this.classIdField = classIdField;
    this.extraNulls = extraNulls;
    this.originalMethodReference = originalMethodReference;
    this.syntheticMethodReference = syntheticMethodReference;
    this.instanceFieldAssignmentsPre = instanceFieldAssignmentsPre;
    this.instanceFieldAssignmentsPost = instanceFieldAssignmentsPost;
    this.parentConstructor = parentConstructor;
    this.parentConstructorArguments = parentConstructorArguments;
  }

  @Override
  public CfCode toCfCode(
      AppView<? extends AppInfoWithClassHierarchy> appView,
      ProgramMethod method,
      HorizontalClassMergerGraphLens lens) {
    int[] argumentToLocalIndex = new int[method.getDefinition().getNumberOfArguments()];
    int maxLocals = 0;
    for (int argumentIndex = 0; argumentIndex < argumentToLocalIndex.length; argumentIndex++) {
      argumentToLocalIndex[argumentIndex] = maxLocals;
      maxLocals += method.getArgumentType(argumentIndex).getRequiredRegisters();
    }

    IntBox maxStack = new IntBox();
    ImmutableList.Builder<CfInstruction> instructionBuilder = ImmutableList.builder();

    // Set position.
    Position callerPosition =
        SyntheticPosition.builder().setLine(0).setMethod(syntheticMethodReference).build();
    Position calleePosition =
        SyntheticPosition.builder()
            .setLine(0)
            .setMethod(originalMethodReference)
            .setCallerPosition(callerPosition)
            .build();
    CfPosition position = new CfPosition(new CfLabel(), calleePosition);
    instructionBuilder.add(position);
    instructionBuilder.add(position.getLabel());

    // Assign class id.
    if (classIdField != null) {
      int classIdLocalIndex = maxLocals - 1 - extraNulls;
      instructionBuilder.add(new CfLoad(ValueType.OBJECT, 0));
      instructionBuilder.add(new CfLoad(ValueType.INT, classIdLocalIndex));
      instructionBuilder.add(
          new CfInstanceFieldWrite(
              lens.getRenamedFieldSignature(classIdField, lens.getPrevious())));
      maxStack.set(2);
    }

    // Assign each field.
    addCfInstructionsForInstanceFieldAssignments(
        appView,
        method,
        instructionBuilder,
        instanceFieldAssignmentsPre,
        argumentToLocalIndex,
        maxStack,
        lens);

    // Load receiver for parent constructor call.
    int stackHeightForParentConstructorCall = 1;
    instructionBuilder.add(new CfLoad(ValueType.OBJECT, 0));

    // Load constructor arguments.
    MethodLookupResult parentConstructorLookup = lens.lookupInvokeDirect(parentConstructor, method);

    int i = 0;
    for (InstanceFieldInitializationInfo initializationInfo : parentConstructorArguments) {
      stackHeightForParentConstructorCall +=
          addCfInstructionsForInitializationInfo(
              instructionBuilder,
              initializationInfo,
              argumentToLocalIndex,
              parentConstructorLookup.getReference().getParameter(i));
      i++;
    }

    for (ExtraParameter extraParameter :
        parentConstructorLookup.getPrototypeChanges().getExtraParameters()) {
      stackHeightForParentConstructorCall +=
          addCfInstructionsForInitializationInfo(
              instructionBuilder,
              extraParameter.getValue(appView),
              argumentToLocalIndex,
              parentConstructorLookup.getReference().getParameter(i));
      i++;
    }

    assert i == parentConstructorLookup.getReference().getParameters().size();

    // Invoke parent constructor.
    instructionBuilder.add(
        new CfInvoke(Opcodes.INVOKESPECIAL, parentConstructorLookup.getReference(), false));
    maxStack.setMax(stackHeightForParentConstructorCall);

    // Assign each field.
    addCfInstructionsForInstanceFieldAssignments(
        appView,
        method,
        instructionBuilder,
        instanceFieldAssignmentsPost,
        argumentToLocalIndex,
        maxStack,
        lens);

    // Return.
    instructionBuilder.add(new CfReturnVoid());

    return new CfCode(
        originalMethodReference.getHolderType(),
        maxStack.get(),
        maxLocals,
        instructionBuilder.build()) {

      @Override
      public GraphLens getCodeLens(AppView<?> appView) {
        return lens;
      }
    };
  }

  private static void addCfInstructionsForInstanceFieldAssignments(
      AppView<? extends AppInfoWithClassHierarchy> appView,
      ProgramMethod method,
      ImmutableList.Builder<CfInstruction> instructionBuilder,
      Map<DexField, InstanceFieldInitializationInfo> instanceFieldAssignments,
      int[] argumentToLocalIndex,
      IntBox maxStack,
      HorizontalClassMergerGraphLens lens) {
    instanceFieldAssignments.forEach(
        (field, initializationInfo) -> {
          // Load the receiver, the field value, and then set the field.
          instructionBuilder.add(new CfLoad(ValueType.OBJECT, 0));
          int stackSizeForInitializationInfo =
              addCfInstructionsForInitializationInfo(
                  instructionBuilder, initializationInfo, argumentToLocalIndex, field.getType());
          DexField rewrittenField = lens.getRenamedFieldSignature(field, lens.getPrevious());

          // Insert a check to ensure the program continues to type check according to Java type
          // checking. Otherwise, instance initializer merging may cause open interfaces. If
          // <init>(A) and <init>(B) both have the behavior `this.i = arg; this.j = arg` where the
          // type of `i` is I and the type of `j` is J, and both A and B implements I and J, then
          // the constructors are merged into a single constructor <init>(java.lang.Object), which
          // is no longer strictly type checking. Note that no choice of parameter type would solve
          // this.
          if (initializationInfo.isArgumentInitializationInfo()) {
            int argumentIndex =
                initializationInfo.asArgumentInitializationInfo().getArgumentIndex();
            if (argumentIndex > 0) {
              DexType argumentType = method.getArgumentType(argumentIndex);
              if (argumentType.isClassType()
                  && !appView.appInfo().isSubtype(argumentType, rewrittenField.getType())) {
                instructionBuilder.add(new CfSafeCheckCast(rewrittenField.getType()));
              }
            }
          }

          instructionBuilder.add(new CfInstanceFieldWrite(rewrittenField));
          maxStack.setMax(stackSizeForInitializationInfo + 1);
        });
  }

  private static int addCfInstructionsForInitializationInfo(
      ImmutableList.Builder<CfInstruction> instructionBuilder,
      InstanceFieldInitializationInfo initializationInfo,
      int[] argumentToLocalIndex,
      DexType type) {
    if (initializationInfo.isArgumentInitializationInfo()) {
      int argumentIndex = initializationInfo.asArgumentInitializationInfo().getArgumentIndex();
      instructionBuilder.add(
          new CfLoad(ValueType.fromDexType(type), argumentToLocalIndex[argumentIndex]));
      return type.getRequiredRegisters();
    }

    assert initializationInfo.isSingleValue();
    assert initializationInfo.asSingleValue().isSingleConstValue();

    SingleConstValue singleConstValue = initializationInfo.asSingleValue().asSingleConstValue();
    if (singleConstValue.isSingleConstClassValue()) {
      instructionBuilder.add(
          new CfConstClass(singleConstValue.asSingleConstClassValue().getType()));
      return 1;
    } else if (singleConstValue.isSingleDexItemBasedStringValue()) {
      SingleDexItemBasedStringValue dexItemBasedStringValue =
          singleConstValue.asSingleDexItemBasedStringValue();
      instructionBuilder.add(
          new CfDexItemBasedConstString(
              dexItemBasedStringValue.getItem(), dexItemBasedStringValue.getNameComputationInfo()));
      return 1;
    } else if (singleConstValue.isSingleNumberValue()) {
      if (type.isReferenceType()) {
        assert singleConstValue.isNull();
        instructionBuilder.add(new CfConstNull());
        return 1;
      } else {
        instructionBuilder.add(
            new CfConstNumber(
                singleConstValue.asSingleNumberValue().getValue(), ValueType.fromDexType(type)));
        return type.getRequiredRegisters();
      }
    } else {
      assert singleConstValue.isSingleStringValue();
      instructionBuilder.add(
          new CfConstString(singleConstValue.asSingleStringValue().getDexString()));
      return 1;
    }
  }

  @Override
  public String toString() {
    return "IncompleteMergedInstanceInitializerCode";
  }
}
