// Copyright (c) 2021, 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.CfArrayStore;
import com.android.tools.r8.cf.code.CfCheckCast;
import com.android.tools.r8.cf.code.CfConstNumber;
import com.android.tools.r8.cf.code.CfFieldInstruction;
import com.android.tools.r8.cf.code.CfFrame;
import com.android.tools.r8.cf.code.CfFrame.FrameType;
import com.android.tools.r8.cf.code.CfIfCmp;
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.CfNewArray;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.CfStore;
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.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.If;
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.utils.collections.ImmutableDeque;
import com.android.tools.r8.utils.collections.ImmutableInt2ReferenceSortedMap;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.Opcodes;

public abstract class RecordCfCodeProvider {

  /**
   * Generates a method which answers all field values as an array of objects. If the field value is
   * a primitive type, it uses the primitive wrapper to wrap it.
   *
   * <p>The fields in parameters are in the order where they should be in the array generated by the
   * method, which is not necessarily the class instanceFields order.
   *
   * <p>Example: <code>record Person{ int age; String name;}</code>
   *
   * <p><code>Object[] getFieldsAsObjects() {
   * Object[] fields = new Object[2];
   * fields[0] = name;
   * fields[1] = Integer.valueOf(age);
   * return fields;</code>
   */
  public static class RecordGetFieldsAsObjectsCfCodeProvider extends SyntheticCfCodeProvider {

    public static void registerSynthesizedCodeReferences(DexItemFactory factory) {
      factory.createSynthesizedType("[Ljava/lang/Object;");
      factory.primitiveToBoxed.forEach(
          (primitiveType, boxedType) -> {
            factory.createSynthesizedType(primitiveType.toDescriptorString());
            factory.createSynthesizedType(boxedType.toDescriptorString());
          });
    }

    private final DexField[] fields;

    public RecordGetFieldsAsObjectsCfCodeProvider(
        AppView<?> appView, DexType holder, DexField[] fields) {
      super(appView, holder);
      this.fields = fields;
    }

    @Override
    public CfCode generateCfCode() {
      // Stack layout:
      // 0 : receiver (the record instance)
      // 1 : the array to return
      // 2+: spills
      DexItemFactory factory = appView.dexItemFactory();
      List<CfInstruction> instructions = new ArrayList<>();
      // Object[] fields = new Object[*length*];
      instructions.add(new CfConstNumber(fields.length, ValueType.INT));
      instructions.add(new CfNewArray(factory.objectArrayType));
      instructions.add(new CfStore(ValueType.OBJECT, 1));
      // fields[*i*] = this.*field* || *PrimitiveWrapper*.valueOf(this.*field*);
      for (int i = 0; i < fields.length; i++) {
        DexField field = fields[i];
        instructions.add(new CfLoad(ValueType.OBJECT, 1));
        instructions.add(new CfConstNumber(i, ValueType.INT));
        instructions.add(new CfLoad(ValueType.OBJECT, 0));
        instructions.add(new CfFieldInstruction(Opcodes.GETFIELD, field, field));
        if (field.type.isPrimitiveType()) {
          factory.primitiveToBoxed.forEach(
              (primitiveType, boxedType) -> {
                if (primitiveType == field.type) {
                  instructions.add(
                      new CfInvoke(
                          Opcodes.INVOKESTATIC,
                          factory.createMethod(
                              boxedType,
                              factory.createProto(boxedType, primitiveType),
                              factory.valueOfMethodName),
                          false));
                }
              });
        }
        instructions.add(new CfArrayStore(MemberType.OBJECT));
      }
      // return fields;
      instructions.add(new CfLoad(ValueType.OBJECT, 1));
      instructions.add(new CfReturn(ValueType.OBJECT));
      return standardCfCodeFromInstructions(instructions);
    }
  }

  public static class RecordEqualsCfCodeProvider extends SyntheticCfCodeProvider {

    private final DexMethod getFieldsAsObjects;

    public RecordEqualsCfCodeProvider(
        AppView<?> appView, DexType holder, DexMethod getFieldsAsObjects) {
      super(appView, holder);
      this.getFieldsAsObjects = getFieldsAsObjects;
    }

    public static void registerSynthesizedCodeReferences(DexItemFactory factory) {
      factory.createSynthesizedType("[Ljava/lang/Object;");
      factory.createSynthesizedType("[Ljava/util/Arrays;");
    }

    @Override
    public CfCode generateCfCode() {
      // This generates something along the lines of:
      // if (this.getClass() != other.getClass()) {
      //     return false;
      // }
      // return Arrays.equals(
      //     recordInstance.getFieldsAsObjects(),
      //     ((RecordClass) other).getFieldsAsObjects());
      ImmutableInt2ReferenceSortedMap<FrameType> locals =
          ImmutableInt2ReferenceSortedMap.<FrameType>builder()
              .put(0, FrameType.initialized(getHolder()))
              .put(1, FrameType.initialized(appView.dexItemFactory().objectType))
              .build();
      DexItemFactory factory = appView.dexItemFactory();
      List<CfInstruction> instructions = new ArrayList<>();
      CfLabel fieldCmp = new CfLabel();
      ValueType recordType = ValueType.fromDexType(getHolder());
      ValueType objectType = ValueType.fromDexType(factory.objectType);
      instructions.add(new CfLoad(recordType, 0));
      instructions.add(new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.getClass, false));
      instructions.add(new CfLoad(objectType, 1));
      instructions.add(new CfInvoke(Opcodes.INVOKEVIRTUAL, factory.objectMembers.getClass, false));
      instructions.add(new CfIfCmp(If.Type.EQ, ValueType.OBJECT, fieldCmp));
      instructions.add(new CfConstNumber(0, ValueType.INT));
      instructions.add(new CfReturn(ValueType.INT));
      instructions.add(fieldCmp);
      instructions.add(new CfFrame(locals, ImmutableDeque.of()));
      instructions.add(new CfLoad(recordType, 0));
      instructions.add(new CfInvoke(Opcodes.INVOKESPECIAL, getFieldsAsObjects, false));
      instructions.add(new CfLoad(objectType, 1));
      instructions.add(new CfCheckCast(getHolder()));
      instructions.add(new CfInvoke(Opcodes.INVOKESPECIAL, getFieldsAsObjects, false));
      instructions.add(
          new CfInvoke(
              Opcodes.INVOKESTATIC, factory.javaUtilArraysMethods.equalsObjectArray, false));
      instructions.add(new CfReturn(ValueType.INT));
      return standardCfCodeFromInstructions(instructions);
    }
  }
}
