// 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.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.CfFrame.FrameType;
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.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.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.errors.Unimplemented;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexItemFactory;
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.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;

/** 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(r8Type("InternalOptions", "utils"))
            .append(" options, ")
            .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 int2ReferenceAVLTreeMapType() {
    return type(
        "Int2ReferenceAVLTreeMap", ImmutableList.of("it", "unimi", "dsi", "fastutil", "ints"));
  }

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

  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 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 "options.itemFactory.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 "options.itemFactory." + field;
    }
    synthesizedTypes.add(descriptor);
    return "options.itemFactory.createType(" + quote(descriptor) + ")";
  }

  private String dexProto(DexProto proto) {
    StringBuilder builder =
        new StringBuilder()
            .append("options.itemFactory.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 "options.itemFactory.createMethod("
        + dexType(method.holder)
        + ", "
        + dexProto(method.proto)
        + ", "
        + dexString(method.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) {
    throw new Unimplemented(constNull.getClass().getSimpleName());
  }

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

  @Override
  public void print(CfConstClass constClass) {
    throw new Unimplemented(constClass.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) {
    throw new Unimplemented(monitor.getClass().getSimpleName());
  }

  @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) {
    String keys = join(",", frame.getLocals().keySet());
    String values = join(",", frame.getLocals().values(), this::frameTypeType);
    String stack = join(",", frame.getStack(), this::frameTypeType);
    printNewInstruction(
        "CfFrame",
        "new "
            + int2ReferenceAVLTreeMapType()
            + "<>("
            + "new int[] {"
            + keys
            + "},"
            + "new "
            + frameTypeType()
            + "[] { "
            + values
            + " })",
        "new " + arrayDequeType() + "<>(" + arraysType() + ".asList(" + stack + "))");
  }

  private String frameTypeType(FrameType frameType) {
    if (frameType.isTop()) {
      return frameTypeType() + ".top()";
    } else if (frameType.isUninitializedThis()) {
      return frameTypeType() + ".uninitializedThis()";
    } else if (frameType.isUninitializedNew()) {
      return frameTypeType() + ".uninitializedNew(new " + cfType("CfLabel") + "())";
    } else {
      assert frameType.isInitialized();
      if (frameType.getInitializedType() == DexItemFactory.nullValueType) {
        return frameTypeType() + ".initialized(" + dexItemFactoryType() + ".nullValueType)";
      } else {
        return frameTypeType() + ".initialized(" + dexType(frameType.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(CfFieldInstruction insn) {
    throw new Unimplemented(insn.getClass().getSimpleName());
  }

  @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;
  }
}
