// Copyright 2018 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;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;

import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;

/**
 * Rewriter of default and static interface methods defined in some core libraries.
 *
 * <p>This is conceptually similar to call site rewriting in {@link InterfaceDesugaring} but here
 * we're doing it for certain bootclasspath methods and in particular for invokeinterface and
 * invokevirtual, which are ignored in regular {@link InterfaceDesugaring}.
 */
public class CoreLibraryInvocationRewriter extends ClassVisitor {

  private final CoreLibrarySupport support;

  @Override
  public void visit(
      int version,
      int access,
      String name,
      String signature,
      String superName,
      String[] interfaces) {
    super.visit(version, access, name, signature, superName, interfaces);
    if (support.getMoveTarget(superName, "<init>") != null) {
      throw new UnsupportedOperationException(
          String.format(
              "Subclassing %s is unsupported: Contains a desugared factory method.", superName));
    }
  }

  public CoreLibraryInvocationRewriter(ClassVisitor cv, CoreLibrarySupport support) {
    super(Opcodes.ASM7, cv);
    this.support = support;
  }

  @Override
  public MethodVisitor visitMethod(
      int access, String name, String desc, String signature, String[] exceptions) {
    MethodVisitor result = super.visitMethod(access, name, desc, signature, exceptions);
    return result != null ? new CoreLibraryMethodInvocationRewriter(result) : null;
  }

  private class CoreLibraryMethodInvocationRewriter extends MethodVisitor {

    public CoreLibraryMethodInvocationRewriter(MethodVisitor mv) {
      super(Opcodes.ASM7, mv);
    }

    @Override
    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
      Class<?> coreInterface =
          support.getCoreInterfaceRewritingTarget(opcode, owner, name, desc, itf);
      boolean replaceConstructorUseWithFactoryMethod = false;
      if (coreInterface != null) {
        String coreInterfaceName = coreInterface.getName().replace('.', '/');
        if (opcode == Opcodes.INVOKESTATIC) {
          checkState(owner.equals(coreInterfaceName));
        } else {
          desc = InterfaceDesugaring.companionDefaultMethodDescriptor(coreInterfaceName, desc);
        }

        if (opcode == Opcodes.INVOKESTATIC || opcode == Opcodes.INVOKESPECIAL) {
          checkArgument(
              itf || opcode == Opcodes.INVOKESPECIAL,
              "Expected interface to rewrite %s.%s : %s",
              owner,
              name,
              desc);
          if (coreInterface.isInterface()) {
            owner = InterfaceDesugaring.getCompanionClassName(coreInterfaceName);
            name =
                InterfaceDesugaring.normalizeInterfaceMethodName(
                    name, name.startsWith("lambda$"), opcode);
          } else {
            owner = checkNotNull(support.getMoveTarget(coreInterfaceName, name));
          }
        } else {
          checkState(coreInterface.isInterface());
          owner = coreInterfaceName + "$$Dispatch";
        }

        opcode = Opcodes.INVOKESTATIC;
        itf = false;
      } else {
        String newOwner = support.getMoveTarget(owner, name);
        if (newOwner != null) {
          if ("<init>".equals(name)) {
            // Replace the invocation of a constructor with that of a static factory method.
            replaceConstructorUseWithFactoryMethod = true;
            opcode = Opcodes.INVOKESTATIC;
            // Assumes the re-mapped factory method names are in the convention create$<simplename>
            // defined in the desugar runtime library.
            name = "create$" + owner.substring(owner.lastIndexOf('/') + 1);
            desc =
                Type.getMethodType(Type.getObjectType(owner), Type.getArgumentTypes(desc))
                    .getDescriptor();
          } else if (opcode != Opcodes.INVOKESTATIC) {
            // assuming a static method
            desc = InterfaceDesugaring.companionDefaultMethodDescriptor(owner, desc);
            opcode = Opcodes.INVOKESTATIC;
          }
          owner = newOwner;
          itf = false; // assuming a class
        }
      }
      super.visitMethodInsn(opcode, owner, name, desc, itf);

      // Compared with the constructor invocation, a factory method invocation pushes (areturn) the
      // constructed object reference onto the operand stack of the invoker frame, leaving the
      // operand stack in state {uninitialized 0, uninitialized 0, objectref}, the following
      // instructions clears the extra values on the stack.
      //
      // TODO(b/144304047): Remove these extra byte code instructions once the preceding consecutive
      // {new, dup} instructions are stripped out.
      if (replaceConstructorUseWithFactoryMethod) {
        super.visitInsn(Opcodes.DUP_X2);
        super.visitInsn(Opcodes.POP);
        super.visitInsn(Opcodes.POP2);
      }
    }
  }
}
