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

import static com.android.tools.r8.utils.StringUtils.join;

import com.android.tools.r8.cf.code.CfArithmeticBinop;
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.CfCmp;
import com.android.tools.r8.cf.code.CfConstClass;
import com.android.tools.r8.cf.code.CfConstDynamic;
import com.android.tools.r8.cf.code.CfConstMethodHandle;
import com.android.tools.r8.cf.code.CfConstMethodType;
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.CfFieldInstruction;
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.CfIinc;
import com.android.tools.r8.cf.code.CfInstanceFieldRead;
import com.android.tools.r8.cf.code.CfInstanceFieldWrite;
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.CfInvokeDynamic;
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfLogicalBinop;
import com.android.tools.r8.cf.code.CfMonitor;
import com.android.tools.r8.cf.code.CfMultiANewArray;
import com.android.tools.r8.cf.code.CfNeg;
import com.android.tools.r8.cf.code.CfNew;
import com.android.tools.r8.cf.code.CfNewArray;
import com.android.tools.r8.cf.code.CfNop;
import com.android.tools.r8.cf.code.CfNumberConversion;
import com.android.tools.r8.cf.code.CfPosition;
import com.android.tools.r8.cf.code.CfReturn;
import com.android.tools.r8.cf.code.CfReturnVoid;
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.cf.code.CfStaticFieldRead;
import com.android.tools.r8.cf.code.CfStaticFieldWrite;
import com.android.tools.r8.cf.code.CfStore;
import com.android.tools.r8.cf.code.CfSwitch;
import com.android.tools.r8.cf.code.CfThrow;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.cf.code.frame.FrameType;
import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.errors.Unreachable;
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.DexProto;
import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.code.If.Type;
import com.android.tools.r8.ir.code.MemberType;
import com.android.tools.r8.ir.code.Monitor;
import com.android.tools.r8.ir.code.NumericType;
import com.android.tools.r8.ir.code.ValueType;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.StringUtils.BraceType;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import it.unimi.dsi.fastutil.objects.Reference2IntMap;
import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.objectweb.asm.Opcodes;

/** Rudimentary printer to print the source representation for creating CfCode object. */
public class CfCodePrinter extends CfPrinter {

  private Set<String> imports = new HashSet<>();
  private List<String> methods = new ArrayList<>();
  private Set<String> methodNames = new HashSet<>();
  private Set<String> synthesizedTypes = new HashSet<>();

  // Per method structures.

  // Sorted list of labels.
  private List<CfLabel> sortedLabels = null;
  // Map from label to its sorted-order index.
  private Reference2IntMap<CfLabel> labelToIndex = null;
  private boolean pendingComma = false;
  private StringBuilder builder = null;

  public CfCodePrinter() {}

  public List<String> getImports() {
    ArrayList<String> sorted = new ArrayList<>(imports);
    sorted.sort(String::compareTo);
    return sorted;
  }

  public List<String> getMethods() {
    return methods;
  }

  public void visitMethod(String methodName, CfCode code) {
    if (!methodNames.add(methodName)) {
      throw new IllegalStateException(
          "Invalid attempt to visit the same method twice: " + methodName);
    }
    labelToIndex = new Reference2IntOpenHashMap<>();
    sortedLabels = new ArrayList<>();
    pendingComma = false;
    builder =
        new StringBuilder()
            .append("public static ")
            .append(r8Type("CfCode", "graph"))
            .append(" ")
            .append(methodName)
            .append("(")
            .append(dexItemFactoryType())
            .append(" factory, ")
            .append(r8Type("DexMethod", "graph"))
            .append(" method) {");

    for (CfInstruction instruction : code.getInstructions()) {
      if (instruction instanceof CfLabel) {
        CfLabel label = (CfLabel) instruction;
        labelToIndex.put(label, sortedLabels.size());
        sortedLabels.add(label);
        builder
            .append("CfLabel ")
            .append(labelName(label))
            .append(" = new " + cfType("CfLabel") + "();");
      }
    }

    builder
        .append("return new " + r8Type("CfCode", "graph") + "(")
        .append("method.holder,")
        .append(code.getMaxStack())
        .append(",")
        .append(code.getMaxLocals())
        .append(",")
        .append(immutableListType())
        .append(".of(");

    for (CfInstruction instruction : code.getInstructions()) {
      instruction.print(this);
    }

    builder.append("),").append(immutableListType()).append(".of(");
    pendingComma = false;
    for (CfTryCatch tryCatchRange : code.getTryCatchRanges()) {
      String guards =
          tryCatchRange.guards.stream().map(this::dexType).collect(Collectors.joining(", "));
      String targets =
          tryCatchRange.targets.stream().map(this::labelName).collect(Collectors.joining(", "));
      printNewInstruction(
          "CfTryCatch",
          labelName(tryCatchRange.start),
          labelName(tryCatchRange.end),
          immutableListType() + ".of(" + guards + ")",
          immutableListType() + ".of(" + targets + ")");
    }

    builder.append("),").append(immutableListType()).append(".of());").append("}");

    methods.add(builder.toString());
  }

  private String quote(String string) {
    return "\"" + string + "\"";
  }

  private String longValue(long value) {
    return (value < Integer.MIN_VALUE || Integer.MAX_VALUE < value) ? (value + "L") : ("" + value);
  }

  // Ensure a type import for a given type.
  // Note that the package should be given as individual parts to avoid the repackage "fixing" it...
  private String type(String name, List<String> pkg) {
    assert !name.contains(".");
    assert pkg.stream().noneMatch(p -> p.contains("."));
    imports.add(String.join(".", pkg) + "." + name);
    return name;
  }

  private String immutableListType() {
    return type("ImmutableList", ImmutableList.of("com", "google", "common", "collect"));
  }

  private String int2ObjectAVLTreeMapType() {
    return type("Int2ObjectAVLTreeMap", ImmutableList.of("it", "unimi", "dsi", "fastutil", "ints"));
  }

  private String frameTypeType() {
    return r8Type("FrameType", ImmutableList.of("cf", "code", "frame"));
  }

  private String monitorType() {
    return r8Type("Monitor", ImmutableList.of("ir", "code"));
  }

  private String asmOpcodesType() {
    return type("Opcodes", ImmutableList.of("org", "objectweb", "asm"));
  }

  private String dexItemFactoryType() {
    return r8Type("DexItemFactory", "graph");
  }

  private String arrayDequeType() {
    return type("ArrayDeque", ImmutableList.of("java", "util"));
  }

  private String arraysType() {
    return type("Arrays", ImmutableList.of("java", "util"));
  }

  private String r8Type(String name, String pkg) {
    return r8Type(name, Collections.singletonList(pkg));
  }

  private String r8Type(String name, List<String> pkg) {
    return type(name, ImmutableList.<String>builder()
        .addAll(ImmutableList.of("com", "android", "tools", "r8"))
        .addAll(pkg).build());
  }

  private String irType(String name) {
    return r8Type(name, ImmutableList.of("ir", "code"));
  }

  private String cfType(String name) {
    return r8Type(name, ImmutableList.of("cf", "code"));
  }

  private String cfFrameType() {
    return cfType("CfFrame");
  }

  private String labelName(CfLabel label) {
    return "label" + labelToIndex.getInt(label);
  }

  private String valueType(ValueType type) {
    return irType("ValueType") + "." + type.name();
  }

  private String numericType(NumericType type) {
    return irType("NumericType") + "." + type.name();
  }

  private String memberType(MemberType type) {
    return irType("MemberType") + "." + type.name();
  }

  private String ifTypeKind(Type kind) {
    return irType("If") + ".Type." + kind.name();
  }

  private String dexString(DexString string) {
    return "factory.createString(" + quote(string.toString()) + ")";
  }

  private final Map<String, String> knownTypeFields =
      ImmutableMap.<String, String>builder()
          .put("Z", "booleanType")
          .put("B", "byteType")
          .put("C", "charType")
          .put("D", "doubleType")
          .put("F", "floatType")
          .put("I", "intType")
          .put("J", "longType")
          .put("S", "shortType")
          .put("V", "voidType")
          .put("[Z", "booleanArrayType")
          .put("[B", "byteArrayType")
          .put("[C", "charArrayType")
          .put("[D", "doubleArrayType")
          .put("[F", "floatArrayType")
          .put("[I", "intArrayType")
          .put("[J", "longArrayType")
          .put("[S", "shortArrayType")
          .put("Ljava/lang/Object;", "objectType")
          .put("Ljava/lang/Class;", "classType")
          .put("Ljava/lang/Throwable;", "throwableType")
          .put("Ljava/lang/String;", "stringType")
          .put("Ljava/lang/Character;", "boxedCharType")
          .put("Ljava/lang/CharSequence;", "charSequenceType")
          .put("Ljava/lang/StringBuilder;", "stringBuilderType")
          .put("Ljava/lang/AutoCloseable;", "autoCloseableType")
          .build();

  private String dexType(DexType type) {
    String descriptor = type.toDescriptorString();
    String field = knownTypeFields.get(descriptor);
    if (field != null) {
      return "factory." + field;
    }
    synthesizedTypes.add(descriptor);
    return "factory.createType(" + quote(descriptor) + ")";
  }

  private String dexProto(DexProto proto) {
    StringBuilder builder =
        new StringBuilder().append("factory.createProto(").append(dexType(proto.returnType));
    for (DexType param : proto.parameters.values) {
      builder.append(", ").append(dexType(param));
    }
    return builder.append(")").toString();
  }

  private String dexMethod(DexMethod method) {
    return "factory.createMethod("
        + dexType(method.holder)
        + ", "
        + dexProto(method.proto)
        + ", "
        + dexString(method.name)
        + ")";
  }

  private String dexField(DexField field) {
    return "factory.createField("
        + dexType(field.holder)
        + ", "
        + dexType(field.type)
        + ", "
        + dexString(field.name)
        + ")";
  }

  private void ensureComma() {
    if (pendingComma) {
      builder.append(",");
    }
    pendingComma = true;
  }

  private void printNewInstruction(String name, String... args) {
    ensureComma();
    builder.append("new ").append(cfType(name));
    StringUtils.append(builder, Arrays.asList(args), ", ", BraceType.PARENS);
  }

  private void printNewVarInstruction(String name, ValueType type, int index) {
    printNewInstruction(name, valueType(type), "" + index);
  }

  private void printNewJumpInstruction(String name, Type kind, ValueType type, CfLabel target) {
    printNewInstruction(name, ifTypeKind(kind), valueType(type), labelName(target));
  }

  @Override
  public void print(CfNop nop) {
    // Since locals and lines are not printed, no need to print nops.
  }

  @Override
  public void print(CfStackInstruction instruction) {
    printNewInstruction(
        "CfStackInstruction",
        cfType("CfStackInstruction") + ".Opcode." + instruction.getOpcode().name());
  }

  @Override
  public void print(CfThrow insn) {
    printNewInstruction("CfThrow");
  }

  @Override
  public void print(CfConstNull constNull) {
    printNewInstruction("CfConstNull");
  }

  @Override
  public void print(CfConstNumber constNumber) {
    printNewInstruction(
        "CfConstNumber", longValue(constNumber.getRawValue()), valueType(constNumber.getType()));
  }

  @Override
  public void print(CfConstClass constClass) {
    printNewInstruction("CfConstClass", dexType(constClass.getType()));
  }

  @Override
  public void print(CfConstDynamic constDynamic) {
    // TODO(b/198143561): Support CfConstDynamic.
    throw new Unimplemented(constDynamic.getClass().getSimpleName());
  }

  @Override
  public void print(CfReturnVoid ret) {
    printNewInstruction("CfReturnVoid");
  }

  @Override
  public void print(CfReturn ret) {
    printNewInstruction("CfReturn", valueType(ret.getType()));
  }

  @Override
  public void print(CfMonitor monitor) {
    printNewInstruction(
        "CfMonitor",
        monitor.getType() == Monitor.Type.ENTER
            ? monitorType() + ".Type.ENTER"
            : monitorType() + ".Type.EXIT");
  }

  @Override
  public void print(CfArithmeticBinop arithmeticBinop) {
    printNewInstruction(
        "CfArithmeticBinop",
        cfType("CfArithmeticBinop") + ".Opcode." + arithmeticBinop.getOpcode().name(),
        numericType(arithmeticBinop.getType()));
  }

  @Override
  public void print(CfCmp cmp) {
    printNewInstruction(
        "CfCmp", irType("Cmp") + ".Bias." + cmp.getBias().name(), numericType(cmp.getType()));
  }

  @Override
  public void print(CfLogicalBinop logicalBinop) {
    printNewInstruction(
        "CfLogicalBinop",
        cfType("CfLogicalBinop") + ".Opcode." + logicalBinop.getOpcode().name(),
        numericType(logicalBinop.getType()));
  }

  @Override
  public void print(CfNeg neg) {
    printNewInstruction("CfNeg", numericType(neg.getType()));
  }

  @Override
  public void print(CfNumberConversion numberConversion) {
    printNewInstruction(
        "CfNumberConversion",
        numericType(numberConversion.getFromType()),
        numericType(numberConversion.getToType()));
  }

  @Override
  public void print(CfConstString constString) {
    printNewInstruction("CfConstString", dexString(constString.getString()));
  }

  @Override
  public void print(CfDexItemBasedConstString constString) {
    throw new Unimplemented(constString.getClass().getSimpleName());
  }

  @Override
  public void print(CfArrayLoad arrayLoad) {
    printNewInstruction("CfArrayLoad", memberType(arrayLoad.getType()));
  }

  @Override
  public void print(CfArrayStore arrayStore) {
    printNewInstruction("CfArrayStore", memberType(arrayStore.getType()));
  }

  @Override
  public void print(CfInvoke invoke) {
    printNewInstruction(
        "CfInvoke",
        Integer.toString(invoke.getOpcode()),
        dexMethod(invoke.getMethod()),
        Boolean.toString(invoke.isInterface()));
  }

  @Override
  public void print(CfInvokeDynamic invoke) {
    throw new Unimplemented(invoke.getClass().getSimpleName());
  }

  @Override
  public void print(CfFrame frame) {
    if (frame.getLocals().isEmpty()) {
      if (frame.getStack().isEmpty()) {
        printNewInstruction(cfFrameType());
      } else {
        printNewInstruction(cfFrameType(), getCfFrameStack(frame));
      }
    } else {
      if (frame.getStack().isEmpty()) {
        printNewInstruction(cfFrameType(), getCfFrameLocals(frame));
      } else {
        printNewInstruction(cfFrameType(), getCfFrameLocals(frame), getCfFrameStack(frame));
      }
    }
  }

  private String getCfFrameLocals(CfFrame frame) {
    String localsKeys = join(",", frame.getLocals().keySet());
    String localsElements = join(",", frame.getLocals().values(), this::frameTypeType);
    return "new "
        + int2ObjectAVLTreeMapType()
        + "<>("
        + "new int[] {"
        + localsKeys
        + "},"
        + "new "
        + frameTypeType()
        + "[] { "
        + localsElements
        + " })";
  }

  private String getCfFrameStack(CfFrame frame) {
    String stackElements = join(",", frame.getStack(), this::frameTypeType);
    return "new " + arrayDequeType() + "<>(" + arraysType() + ".asList(" + stackElements + "))";
  }

  private String frameTypeType(FrameType frameType) {
    if (frameType.isOneWord()) {
      return frameTypeType() + ".oneWord()";
    } else if (frameType.isTwoWord()) {
      return frameTypeType() + ".twoWord()";
    } else if (frameType.isUninitializedThis()) {
      return frameTypeType() + ".uninitializedThis()";
    } else if (frameType.isUninitializedNew()) {
      return frameTypeType() + ".uninitializedNew(new " + cfType("CfLabel") + "())";
    } else if (frameType.isPrimitive()) {
      if (frameType.isWidePrimitiveHigh()) {
        return frameTypeType()
            + "."
            + frameType.asWidePrimitive().getLowType().getTypeName()
            + "HighType()";
      } else {
        return frameTypeType() + "." + frameType.asPrimitive().getTypeName() + "Type()";
      }
    } else {
      assert frameType.isInitializedReferenceType();
      assert !frameType.isInitializedNonNullReferenceTypeWithInterfaces()
          : "Unexpected InitializedNonNullReferenceTypeWithInterfaces in CfFrame";
      if (frameType.isNullType()) {
        return frameTypeType() + ".nullType()";
      } else {
        assert frameType.isInitializedNonNullReferenceTypeWithoutInterfaces();
        return frameTypeType()
            + ".initializedNonNullReference("
            + dexType(
                frameType.asInitializedNonNullReferenceTypeWithoutInterfaces().getInitializedType())
            + ")";
      }
    }
  }

  @Override
  public void print(CfInstanceOf insn) {
    printNewInstruction("CfInstanceOf", dexType(insn.getType()));
  }

  @Override
  public void print(CfCheckCast insn) {
    printNewInstruction("CfCheckCast", dexType(insn.getType()));
  }

  @Override
  public void print(CfInstanceFieldRead insn) {
    printNewInstruction("CfInstanceFieldRead", dexField(insn.getField()));
  }

  @Override
  public void print(CfInstanceFieldWrite insn) {
    printNewInstruction("CfInstanceFieldWrite", dexField(insn.getField()));
  }

  @Override
  public void print(CfStaticFieldRead insn) {
    printNewInstruction("CfStaticFieldRead", dexField(insn.getField()));
  }

  @Override
  public void print(CfStaticFieldWrite insn) {
    printNewInstruction("CfStaticFieldWrite", dexField(insn.getField()));
  }

  @Override
  public void print(CfFieldInstruction insn) {
    switch (insn.getOpcode()) {
      case Opcodes.GETFIELD:
        printNewInstruction("CfInstanceFieldRead", dexField(insn.getField()));
        break;
      case Opcodes.PUTFIELD:
        printNewInstruction("CfInstanceFieldWrite", dexField(insn.getField()));
        break;
      case Opcodes.GETSTATIC:
        printNewInstruction("CfStaticFieldRead", dexField(insn.getField()));
        break;
      case Opcodes.PUTSTATIC:
        printNewInstruction("CfStaticFieldWrite", dexField(insn.getField()));
        break;
      default:
        throw new Unreachable();
    }
  }

  @Override
  public void print(CfNew newInstance) {
    printNewInstruction("CfNew", dexType(newInstance.getType()));
  }

  @Override
  public void print(CfNewArray newArray) {
    printNewInstruction("CfNewArray", dexType(newArray.getType()));
  }

  @Override
  public void print(CfMultiANewArray multiANewArray) {
    throw new Unimplemented(multiANewArray.getClass().getSimpleName());
  }

  @Override
  public void print(CfArrayLength arrayLength) {
    printNewInstruction("CfArrayLength");
  }

  @Override
  public void print(CfLabel label) {
    ensureComma();
    builder.append(labelName(label));
  }

  @Override
  public void print(CfPosition instruction) {
    // Ignoring positions.
  }

  @Override
  public void print(CfGoto jump) {
    printNewInstruction("CfGoto", labelName(jump.getTarget()));
  }

  @Override
  public void print(CfIf conditional) {
    printNewJumpInstruction(
        "CfIf", conditional.getKind(), conditional.getType(), conditional.getTarget());
  }

  @Override
  public void print(CfIfCmp conditional) {
    printNewJumpInstruction(
        "CfIfCmp", conditional.getKind(), conditional.getType(), conditional.getTarget());
  }

  @Override
  public void print(CfSwitch cfSwitch) {
    throw new Unimplemented(cfSwitch.getClass().getSimpleName());
  }

  @Override
  public void print(CfLoad load) {
    printNewVarInstruction("CfLoad", load.getType(), load.getLocalIndex());
  }

  @Override
  public void print(CfStore store) {
    printNewVarInstruction("CfStore", store.getType(), store.getLocalIndex());
  }

  @Override
  public void print(CfIinc instruction) {
    printNewInstruction(
        "CfIinc",
        Integer.toString(instruction.getLocalIndex()),
        Integer.toString(instruction.getIncrement()));
  }

  @Override
  public void print(CfConstMethodHandle handle) {
    throw new Unimplemented(handle.getClass().getSimpleName());
  }

  @Override
  public void print(CfConstMethodType type) {
    throw new Unimplemented(type.getClass().getSimpleName());
  }

  public Set<String> getSynthesizedTypes() {
    return synthesizedTypes;
  }
}
