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

import com.android.tools.r8.cf.code.CfArithmeticBinop;
import com.android.tools.r8.cf.code.CfArithmeticBinop.Opcode;
import com.android.tools.r8.cf.code.CfArrayLength;
import com.android.tools.r8.cf.code.CfArrayLoad;
import com.android.tools.r8.cf.code.CfArrayStore;
import com.android.tools.r8.cf.code.CfCheckCast;
import com.android.tools.r8.cf.code.CfConstNull;
import com.android.tools.r8.cf.code.CfConstNumber;
import com.android.tools.r8.cf.code.CfFrame;
import com.android.tools.r8.cf.code.CfGoto;
import com.android.tools.r8.cf.code.CfIf;
import com.android.tools.r8.cf.code.CfIfCmp;
import com.android.tools.r8.cf.code.CfInstanceFieldRead;
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.CfNew;
import com.android.tools.r8.cf.code.CfNewArray;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.cf.code.CfStaticFieldRead;
import com.android.tools.r8.cf.code.CfStore;
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.DexEncodedField;
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.NumericType;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.ir.synthetic.SyntheticCfCodeProvider;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.objectweb.asm.Opcodes;

public abstract class NullableConversionCfCodeProvider extends SyntheticCfCodeProvider {

  protected NullableConversionCfCodeProvider(AppView<?> appView, DexType holder) {
    super(appView, holder);
  }

  void generateNullCheck(List<CfInstruction> instructions) {
    CfLabel nullDest = new CfLabel();
    instructions.add(new CfLoad(ValueType.OBJECT, 0));
    instructions.add(new CfIf(If.Type.NE, ValueType.OBJECT, nullDest));
    instructions.add(new CfConstNull());
    instructions.add(new CfReturn(ValueType.OBJECT));
    instructions.add(nullDest);
  }

  public static class ArrayConversionCfCodeProvider extends NullableConversionCfCodeProvider {

    private final DexType typeArray;
    private final DexType convertedTypeArray;
    private final DexMethod conversion;

    public ArrayConversionCfCodeProvider(
        AppView<?> appView,
        DexType holder,
        DexType typeArray,
        DexType convertedTypeArray,
        DexMethod conversion) {
      super(appView, holder);
      this.typeArray = typeArray;
      this.convertedTypeArray = convertedTypeArray;
      this.conversion = conversion;
    }

    @Override
    public CfCode generateCfCode() {
      DexItemFactory factory = appView.dexItemFactory();
      List<CfInstruction> instructions = new ArrayList<>();

      // if (arg == null) { return null; }
      generateNullCheck(instructions);
      instructions.add(CfFrame.builder().appendLocal(FrameType.initialized(typeArray)).build());

      CfFrame frame =
          CfFrame.builder()
              .appendLocal(FrameType.initialized(typeArray))
              .appendLocal(FrameType.initialized(factory.intType))
              .appendLocal(FrameType.initialized(convertedTypeArray))
              .appendLocal(FrameType.initialized(factory.intType))
              .build();

      // int t1 = arg.length;
      instructions.add(new CfLoad(ValueType.fromDexType(typeArray), 0));
      instructions.add(new CfArrayLength());
      instructions.add(new CfStore(ValueType.INT, 1));
      // ConvertedType[] t2 = new ConvertedType[t1];
      instructions.add(new CfLoad(ValueType.INT, 1));
      instructions.add(new CfNewArray(convertedTypeArray));
      instructions.add(new CfStore(ValueType.fromDexType(convertedTypeArray), 2));
      // int t3 = 0;
      instructions.add(new CfConstNumber(0, ValueType.INT));
      instructions.add(new CfStore(ValueType.INT, 3));
      // while (t3 < t1) {
      CfLabel returnLabel = new CfLabel();
      CfLabel loopLabel = new CfLabel();
      instructions.add(loopLabel);
      instructions.add(frame);
      instructions.add(new CfLoad(ValueType.INT, 3));
      instructions.add(new CfLoad(ValueType.INT, 1));
      instructions.add(new CfIfCmp(If.Type.GE, ValueType.INT, returnLabel));
      // t2[t3] = convert(arg[t3]);
      instructions.add(new CfLoad(ValueType.fromDexType(convertedTypeArray), 2));
      instructions.add(new CfLoad(ValueType.INT, 3));
      instructions.add(new CfLoad(ValueType.fromDexType(typeArray), 0));
      instructions.add(new CfLoad(ValueType.INT, 3));
      instructions.add(new CfArrayLoad(MemberType.OBJECT));
      instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, conversion, false));
      instructions.add(new CfArrayStore(MemberType.OBJECT));
      // t3 = t3 + 1; }
      instructions.add(new CfLoad(ValueType.INT, 3));
      instructions.add(new CfConstNumber(1, ValueType.INT));
      instructions.add(new CfArithmeticBinop(Opcode.Add, NumericType.INT));
      instructions.add(new CfStore(ValueType.INT, 3));
      instructions.add(new CfGoto(loopLabel));
      // return t2;
      instructions.add(returnLabel);
      instructions.add(frame.clone());
      instructions.add(new CfLoad(ValueType.fromDexType(convertedTypeArray), 2));
      instructions.add(new CfReturn(ValueType.fromDexType(convertedTypeArray)));
      return standardCfCodeFromInstructions(instructions);
    }
  }

  public static class EnumConversionCfCodeProvider extends NullableConversionCfCodeProvider {

    private final Iterable<DexEncodedField> enumFields;
    private final DexType enumType;
    private final DexType convertedType;

    public EnumConversionCfCodeProvider(
        AppView<?> appView,
        DexType holder,
        Iterable<DexEncodedField> enumFields,
        DexType enumType,
        DexType convertedType) {
      super(appView, holder);
      this.enumFields = enumFields;
      this.enumType = enumType;
      this.convertedType = convertedType;
    }

    @Override
    public CfCode generateCfCode() {
      DexItemFactory factory = appView.dexItemFactory();
      List<CfInstruction> instructions = new ArrayList<>();

      CfFrame frame = CfFrame.builder().appendLocal(FrameType.initialized(enumType)).build();

      // if (arg == null) { return null; }
      generateNullCheck(instructions);
      instructions.add(frame);

      // if (arg == enumType.enumField1) { return convertedType.enumField1; }
      Iterator<DexEncodedField> iterator = enumFields.iterator();
      while (iterator.hasNext()) {
        DexEncodedField enumField = iterator.next();
        CfLabel notEqual = new CfLabel();
        if (iterator.hasNext()) {
          instructions.add(new CfLoad(ValueType.fromDexType(enumType), 0));
          instructions.add(
              new CfStaticFieldRead(factory.createField(enumType, enumType, enumField.getName())));
          instructions.add(new CfIfCmp(If.Type.NE, ValueType.OBJECT, notEqual));
        }
        instructions.add(
            new CfStaticFieldRead(
                factory.createField(convertedType, convertedType, enumField.getName())));
        instructions.add(new CfReturn(ValueType.fromDexType(convertedType)));
        if (iterator.hasNext()) {
          instructions.add(notEqual);
          instructions.add(frame.clone());
        }
      }
      return standardCfCodeFromInstructions(instructions);
    }
  }

  public static class WrapperConversionCfCodeProvider extends NullableConversionCfCodeProvider {

    DexField reverseWrapperField;
    DexField wrapperField;

    public WrapperConversionCfCodeProvider(
        AppView<?> appView, DexField reverseWrapperField, DexField wrapperField) {
      super(appView, wrapperField.holder);
      this.reverseWrapperField = reverseWrapperField;
      this.wrapperField = wrapperField;
    }

    @Override
    public CfCode generateCfCode() {
      DexItemFactory factory = appView.dexItemFactory();
      List<CfInstruction> instructions = new ArrayList<>();

      DexType argType = wrapperField.type;
      CfFrame frame = CfFrame.builder().appendLocal(FrameType.initialized(argType)).build();

      // if (arg == null) { return null };
      generateNullCheck(instructions);
      instructions.add(frame);

      // if (arg instanceOf ReverseWrapper) { return ((ReverseWrapper) arg).wrapperField};
      assert reverseWrapperField != null;
      CfLabel unwrapDest = new CfLabel();
      instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
      instructions.add(new CfInstanceOf(reverseWrapperField.holder));
      instructions.add(new CfIf(If.Type.EQ, ValueType.INT, unwrapDest));
      instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
      instructions.add(new CfCheckCast(reverseWrapperField.holder));
      instructions.add(new CfInstanceFieldRead(reverseWrapperField));
      instructions.add(new CfReturn(ValueType.fromDexType(reverseWrapperField.type)));
      instructions.add(unwrapDest);
      instructions.add(frame.clone());

      // return new Wrapper(wrappedValue);
      instructions.add(new CfNew(wrapperField.holder));
      instructions.add(CfStackInstruction.fromAsm(Opcodes.DUP));
      instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
      instructions.add(
          new CfInvoke(
              Opcodes.INVOKESPECIAL,
              factory.createMethod(
                  wrapperField.holder,
                  factory.createProto(factory.voidType, argType),
                  factory.constructorMethodName),
              false));
      instructions.add(new CfReturn(ValueType.fromDexType(wrapperField.holder)));
      return standardCfCodeFromInstructions(instructions);
    }
  }

  public static class CollectionConversionCfCodeProvider extends NullableConversionCfCodeProvider {

    private final DexType collectionType;
    private final DexMethod conversion;

    public CollectionConversionCfCodeProvider(
        AppView<?> appView, DexType holder, DexType collectionType, DexMethod conversion) {
      super(appView, holder);
      this.collectionType = collectionType;
      this.conversion = conversion;
    }

    @Override
    public CfCode generateCfCode() {
      DexItemFactory factory = appView.dexItemFactory();
      List<CfInstruction> instructions = new ArrayList<>();

      // if (arg == null) { return null; }
      generateNullCheck(instructions);
      instructions.add(
          CfFrame.builder().appendLocal(FrameType.initialized(collectionType)).build());

      CfFrame frame =
          CfFrame.builder()
              .appendLocal(FrameType.initialized(collectionType))
              .appendLocal(FrameType.initialized(collectionType))
              .appendLocal(FrameType.initialized(factory.iteratorType))
              .build();

      // Collection<E> t1 = new Collection<E>();
      if (collectionType == factory.setType) {
        DexType hashSetType = factory.createType("Ljava/util/HashSet;");
        instructions.add(new CfNew(hashSetType));
        instructions.add(
            new CfInvoke(
                Opcodes.INVOKESPECIAL,
                factory.createMethod(
                    hashSetType,
                    factory.createProto(factory.voidType),
                    factory.constructorMethodName),
                false));
      } else {
        assert collectionType == factory.listType;
        DexType arrayListType = factory.createType("Ljava/util/ArrayList;");
        instructions.add(new CfNew(arrayListType));
        instructions.add(
            new CfInvoke(
                Opcodes.INVOKESPECIAL,
                factory.createMethod(
                    arrayListType,
                    factory.createProto(factory.voidType),
                    factory.constructorMethodName),
                false));
      }
      instructions.add(new CfStore(ValueType.OBJECT, 1));

      // Iterator<E> t2 = receiver.iterator();
      instructions.add(new CfLoad(ValueType.OBJECT, 0));
      instructions.add(
          new CfInvoke(
              Opcodes.INVOKEINTERFACE,
              factory.createMethod(
                  factory.collectionType, factory.createProto(factory.iteratorType), "iterator"),
              true));
      instructions.add(new CfStore(ValueType.OBJECT, 2));

      // while(t2.hasNext())
      CfLabel returnLabel = new CfLabel();
      CfLabel loopLabel = new CfLabel();
      instructions.add(loopLabel);
      instructions.add(frame);
      instructions.add(new CfLoad(ValueType.fromDexType(factory.iteratorType), 2));
      instructions.add(
          new CfInvoke(
              Opcodes.INVOKEINTERFACE,
              factory.createMethod(
                  factory.iteratorType, factory.createProto(factory.booleanType), "hasNext"),
              true));
      instructions.add(new CfConstNumber(0, ValueType.INT));
      instructions.add(new CfIfCmp(If.Type.EQ, ValueType.INT, returnLabel));

      // {t1.add(convert(t2.next());}
      instructions.add(new CfLoad(ValueType.fromDexType(collectionType), 1));
      instructions.add(new CfLoad(ValueType.fromDexType(factory.iteratorType), 2));
      instructions.add(
          new CfInvoke(
              Opcodes.INVOKEINTERFACE,
              factory.createMethod(
                  factory.iteratorType,
                  factory.createProto(conversion.getArgumentType(0, true)),
                  "next"),
              true));
      instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, conversion, false));
      instructions.add(
          new CfInvoke(
              Opcodes.INVOKEINTERFACE,
              factory.createMethod(
                  factory.collectionType,
                  factory.createProto(factory.booleanType, factory.objectType),
                  "add"),
              true));
      instructions.add(new CfGoto(loopLabel));

      // return t1;
      instructions.add(returnLabel);
      instructions.add(frame.clone());
      instructions.add(new CfLoad(ValueType.fromDexType(collectionType), 1));
      instructions.add(new CfReturn(ValueType.fromDexType(collectionType)));

      return standardCfCodeFromInstructions(instructions);
    }
  }
}
