/*
 * Copyright 2019 The Bazel Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.devtools.build.android.desugar.strconcat;

import static com.google.common.collect.ImmutableList.toImmutableList;
import static com.google.devtools.build.android.desugar.langmodel.LangModelHelper.visitPushInstr;

import com.google.common.collect.ImmutableList;
import com.google.devtools.build.android.desugar.langmodel.ClassMemberUse;
import com.google.devtools.build.android.desugar.langmodel.ClassMemberUseCounter;
import com.google.devtools.build.android.desugar.langmodel.ClassName;
import com.google.devtools.build.android.desugar.langmodel.LangModelHelper;
import com.google.devtools.build.android.desugar.langmodel.MemberUseKind;
import com.google.devtools.build.android.desugar.langmodel.MethodKey;
import java.util.Arrays;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Handle;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

/** Desugars indy string concatenations by replacement with string builders. */
public final class IndyStringConcatDesugaring extends ClassVisitor {

  public static final ClassMemberUse INVOKE_JDK11_STRING_CONCAT =
      ClassMemberUse.create(
          MethodKey.create(
              ClassName.create("java/lang/invoke/StringConcatFactory"),
              "makeConcatWithConstants",
              "(Ljava/lang/invoke/MethodHandles$Lookup;"
                  + "Ljava/lang/String;"
                  + "Ljava/lang/invoke/MethodType;"
                  + "Ljava/lang/String;"
                  + "[Ljava/lang/Object;)"
                  + "Ljava/lang/invoke/CallSite;"),
          MemberUseKind.INVOKEDYNAMIC);

  private static final ClassMemberUse INVOKE_STRING_CONCAT_REPLACEMENT_METHOD =
      ClassMemberUse.create(
          MethodKey.create(
              ClassName.create("com/google/devtools/build/android/desugar/runtime/StringConcats"),
              "concat",
              "([Ljava/lang/Object;"
                  + "Ljava/lang/String;"
                  + "[Ljava/lang/Object;)"
                  + "Ljava/lang/String;"),
          MemberUseKind.INVOKESTATIC);

  private final ClassMemberUseCounter classMemberUseCounter;

  public IndyStringConcatDesugaring(
      ClassMemberUseCounter classMemberUseCounter, ClassVisitor classVisitor) {
    super(Opcodes.ASM7, classVisitor);
    this.classMemberUseCounter = classMemberUseCounter;
  }

  @Override
  public MethodVisitor visitMethod(
      int access, String name, String descriptor, String signature, String[] exceptions) {
    MethodVisitor mv = super.visitMethod(access, name, descriptor, signature, exceptions);
    return mv == null
        ? null
        : new IndifiedStringConcatInvocationConverter(classMemberUseCounter, api, mv);
  }

  static final class IndifiedStringConcatInvocationConverter extends MethodVisitor {

    private final ClassMemberUseCounter classMemberUseCounter;

    IndifiedStringConcatInvocationConverter(
        ClassMemberUseCounter classMemberUseCounter, int api, MethodVisitor methodVisitor) {
      super(api, methodVisitor);
      this.classMemberUseCounter = classMemberUseCounter;
    }

    @Override
    public void visitInvokeDynamicInsn(
        String name,
        String descriptor,
        Handle bootstrapMethodHandle,
        Object... bootstrapMethodArguments) {
      ClassMemberUse bootstrapMethodInvocation =
          ClassMemberUse.create(
              MethodKey.create(
                  ClassName.create(bootstrapMethodHandle.getOwner()),
                  bootstrapMethodHandle.getName(),
                  bootstrapMethodHandle.getDesc()),
              MemberUseKind.INVOKEDYNAMIC);
      if (INVOKE_JDK11_STRING_CONCAT.equals(bootstrapMethodInvocation)) {
        // Increment the counter for the bootstrap method invocation of
        // StringConcatFactory#makeConcatWithConstants
        classMemberUseCounter.incrementMemberUseCount(bootstrapMethodInvocation);

        LangModelHelper.collapseStackValuesToObjectArray(
            this,
            ImmutableList.of(LangModelHelper::anyPrimitiveToStringInvocationSite),
            Arrays.stream(Type.getArgumentTypes(descriptor))
                .map(ClassName::create)
                .collect(toImmutableList()));

        String recipe = (String) bootstrapMethodArguments[0];
        visitLdcInsn(recipe);

        // Stores the constants into an array.
        visitPushInstr(mv, bootstrapMethodArguments.length - 1);
        visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
        for (int i = 1; i < bootstrapMethodArguments.length; i++) {
          visitPushInstr(mv, i - 1);
          visitLdcInsn(bootstrapMethodArguments[i]);
          visitInsn(Opcodes.AASTORE);
        }

        INVOKE_STRING_CONCAT_REPLACEMENT_METHOD.acceptClassMethodInsn(this);
        return;
      }
      super.visitInvokeDynamicInsn(
          name, descriptor, bootstrapMethodHandle, bootstrapMethodArguments);
    }
  }
}
