// Copyright (c) 2017, 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 stringconcat;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.ArrayList;
import java.util.List;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Handle;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class TestGenerator {
  private static final String RECIPE_PREFIX = "RECIPE:";

  private static final String STRING_CONCAT_FACTORY = "java/lang/invoke/StringConcatFactory";

  private static final Handle MAKE_CONCAT_WITH_CONSTANTS = new Handle(
      Opcodes.H_INVOKESTATIC, STRING_CONCAT_FACTORY, "makeConcatWithConstants",
      MethodType.methodType(CallSite.class, MethodHandles.Lookup.class, String.class,
          MethodType.class, String.class, Object[].class).toMethodDescriptorString(),
      false);

  private static final Handle MAKE_CONCAT = new Handle(
      Opcodes.H_INVOKESTATIC, STRING_CONCAT_FACTORY, "makeConcat",
      MethodType.methodType(CallSite.class, MethodHandles.Lookup.class,
          String.class, MethodType.class).toMethodDescriptorString(),
      false);

  public static void main(String[] args) throws IOException {
    assert args.length == 2;
    String fileName = StringConcat.class.getSimpleName() + ".class";
    Path inputFile = Paths.get(args[0], TestGenerator.class.getPackage().getName(), fileName);
    Path outputFile = Paths.get(args[1], fileName);
    generateTests(inputFile, outputFile);
  }

  private static void generateTests(Path classNamePath, Path outputClassNamePath)
      throws IOException {
    Files.createDirectories(outputClassNamePath.getParent());
    try (InputStream input = Files.newInputStream(classNamePath)) {
      ClassReader cr = new ClassReader(input);
      ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
      cr.accept(
          new ClassVisitor(Opcodes.ASM7, cw) {
            @Override
            public MethodVisitor visitMethod(int access,
                final String methodName, String desc, String signature, String[] exceptions) {
              MethodVisitor mv = super.visitMethod(access, methodName, desc, signature, exceptions);
              return new MethodVisitor(Opcodes.ASM7, mv) {
                private List<Object> recentConstants = new ArrayList<>();

                @Override
                public void visitLdcInsn(Object cst) {
                  if (!recentConstants.isEmpty() ||
                      (cst instanceof String && ((String) cst).startsWith(RECIPE_PREFIX))) {
                    // Add the constant, don't push anything on stack.
                    recentConstants.add(cst);
                    return;
                  }
                  super.visitLdcInsn(cst);
                }

                @Override
                public void visitMethodInsn(
                    int opcode, String owner, String name, String desc, boolean itf) {
                  // Replace calls to 'makeConcat(...)' with appropriate `invokedynamic`.
                  if (opcode == Opcodes.INVOKESTATIC && name.equals("makeConcat")) {
                    mv.visitInvokeDynamicInsn(MAKE_CONCAT.getName(), desc, MAKE_CONCAT);
                    recentConstants.clear();
                    return;
                  }

                  // Replace calls to 'makeConcat(...)' with appropriate `invokedynamic`.
                  if (opcode == Opcodes.INVOKESTATIC && name.equals("makeConcatWithConstants")) {
                    if (recentConstants.isEmpty()) {
                      throw new AssertionError("No constants detected in `" +
                          methodName + "`: call to " + name + desc);
                    }
                    recentConstants.set(0,
                        ((String) recentConstants.get(0)).substring(RECIPE_PREFIX.length()));

                    mv.visitInvokeDynamicInsn(
                        MAKE_CONCAT_WITH_CONSTANTS.getName(),
                        removeLastParams(desc, recentConstants.size()),
                        MAKE_CONCAT_WITH_CONSTANTS,
                        recentConstants.toArray());
                    recentConstants.clear();
                    return;
                  }

                  // Otherwise fall back to default implementation.
                  super.visitMethodInsn(opcode, owner, name, desc, itf);
                }

                private String removeLastParams(String descr, int paramsToRemove) {
                  MethodType methodType =
                      MethodType.fromMethodDescriptorString(
                          descr, this.getClass().getClassLoader());
                  return methodType
                      .dropParameterTypes(
                          methodType.parameterCount() - paramsToRemove,
                          methodType.parameterCount())
                      .toMethodDescriptorString();
                }

                @Override
                public void visitInsn(int opcode) {
                  switch (opcode) {
                    case Opcodes.ICONST_0:
                      if (!recentConstants.isEmpty()) {
                        recentConstants.add(0);
                        return;
                      }
                      break;
                    case Opcodes.ICONST_1:
                      if (!recentConstants.isEmpty()) {
                        recentConstants.add(1);
                        return;
                      }
                      break;
                    case Opcodes.ICONST_2:
                      if (!recentConstants.isEmpty()) {
                        recentConstants.add(2);
                        return;
                      }
                      break;
                    case Opcodes.ICONST_3:
                      if (!recentConstants.isEmpty()) {
                        recentConstants.add(3);
                        return;
                      }
                      break;
                    case Opcodes.ICONST_4:
                      if (!recentConstants.isEmpty()) {
                        recentConstants.add(4);
                        return;
                      }
                      break;
                    case Opcodes.ICONST_5:
                      if (!recentConstants.isEmpty()) {
                        recentConstants.add(5);
                        return;
                      }
                      break;
                    case Opcodes.ICONST_M1:
                      if (!recentConstants.isEmpty()) {
                        recentConstants.add(-1);
                        return;
                      }
                      break;
                    default:
                      recentConstants.clear();
                      break;
                  }
                  super.visitInsn(opcode);
                }

                @Override
                public void visitIntInsn(int opcode, int operand) {
                  recentConstants.clear();
                  super.visitIntInsn(opcode, operand);
                }

                @Override
                public void visitVarInsn(int opcode, int var) {
                  recentConstants.clear();
                  super.visitVarInsn(opcode, var);
                }

                @Override
                public void visitTypeInsn(int opcode, String type) {
                  recentConstants.clear();
                  super.visitTypeInsn(opcode, type);
                }

                @Override
                public void visitFieldInsn(int opcode, String owner, String name, String desc) {
                  recentConstants.clear();
                  super.visitFieldInsn(opcode, owner, name, desc);
                }

                @Override
                public void visitJumpInsn(int opcode, Label label) {
                  recentConstants.clear();
                  super.visitJumpInsn(opcode, label);
                }

                @Override
                public void visitIincInsn(int var, int increment) {
                  recentConstants.clear();
                  super.visitIincInsn(var, increment);
                }

                @Override
                public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) {
                  recentConstants.clear();
                  super.visitTableSwitchInsn(min, max, dflt, labels);
                }

                @Override
                public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) {
                  recentConstants.clear();
                  super.visitLookupSwitchInsn(dflt, keys, labels);
                }

                @Override
                public void visitMultiANewArrayInsn(String desc, int dims) {
                  recentConstants.clear();
                  super.visitMultiANewArrayInsn(desc, dims);
                }
              };
            }
          }, 0);
      try (OutputStream output =
          Files.newOutputStream(outputClassNamePath, StandardOpenOption.CREATE)) {
        output.write(cw.toByteArray());
      }
    }
  }
}
