// 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.IfType;
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(IfType.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.intType())
              .appendLocal(FrameType.initialized(convertedTypeArray))
              .appendLocal(FrameType.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(IfType.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(IfType.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 {

    private final DexField reverseWrapperField;
    private final DexField wrapperField;
    private final List<DexMethod> subwrapperConvertList;

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

    @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(IfType.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());

      // if (arg instanceOf Subtype) {
      //     return SubtypeWrapper.convert((Subtype) arg)
      // };
      for (DexMethod convert : subwrapperConvertList) {
        CfLabel dest = new CfLabel();
        DexType convertArgType = convert.getArgumentType(0, true);
        instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
        instructions.add(new CfInstanceOf(convertArgType));
        instructions.add(new CfIf(IfType.EQ, ValueType.INT, dest));
        instructions.add(new CfLoad(ValueType.fromDexType(argType), 0));
        instructions.add(new CfCheckCast(convertArgType));
        instructions.add(new CfInvoke(Opcodes.INVOKESTATIC, convert, false));
        instructions.add(new CfReturn(ValueType.fromDexType(reverseWrapperField.type)));
        instructions.add(dest);
        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);
    }
  }
}
