// Copyright 2017 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.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.objectweb.asm.Opcodes.ACC_STATIC;
import static org.objectweb.asm.Opcodes.ACC_SYNTHETIC;
import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
import static org.objectweb.asm.Opcodes.INVOKESTATIC;
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;

import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.devtools.build.android.desugar.BytecodeTypeInference.InferredType;
import com.google.devtools.build.android.desugar.io.BitFlags;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.Nullable;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.ClassRemapper;
import org.objectweb.asm.commons.Remapper;
import org.objectweb.asm.tree.MethodNode;

/**
 * Desugar try-with-resources. This class visitor intercepts calls to the following methods, and
 * redirect them to ThrowableExtension.
 * <li>{@code Throwable.addSuppressed(Throwable)}
 * <li>{@code Throwable.getSuppressed()}
 * <li>{@code Throwable.printStackTrace()}
 * <li>{@code Throwable.printStackTrace(PrintStream)}
 * <li>{@code Throwable.printStackTrace(PringWriter)}
 */
public class TryWithResourcesRewriter extends ClassVisitor {

  private static final String RUNTIME_PACKAGE_INTERNAL_NAME =
      "com/google/devtools/build/android/desugar/runtime";

  static final String THROWABLE_EXTENSION_INTERNAL_NAME =
      RUNTIME_PACKAGE_INTERNAL_NAME + '/' + "ThrowableExtension";

  /** The extension classes for java.lang.Throwable. */
  static final ImmutableSet<String> THROWABLE_EXT_CLASS_INTERNAL_NAMES =
      ImmutableSet.of(
          THROWABLE_EXTENSION_INTERNAL_NAME,
          THROWABLE_EXTENSION_INTERNAL_NAME + "$AbstractDesugaringStrategy",
          THROWABLE_EXTENSION_INTERNAL_NAME + "$ConcurrentWeakIdentityHashMap",
          THROWABLE_EXTENSION_INTERNAL_NAME + "$ConcurrentWeakIdentityHashMap$WeakKey",
          THROWABLE_EXTENSION_INTERNAL_NAME + "$MimicDesugaringStrategy",
          THROWABLE_EXTENSION_INTERNAL_NAME + "$NullDesugaringStrategy",
          THROWABLE_EXTENSION_INTERNAL_NAME + "$ReuseDesugaringStrategy");

  /** The extension classes for java.lang.Throwable. All the names end with ".class" */
  static final ImmutableSet<String> THROWABLE_EXT_CLASS_INTERNAL_NAMES_WITH_CLASS_EXT =
      FluentIterable.from(THROWABLE_EXT_CLASS_INTERNAL_NAMES)
          .transform(
              new Function<String, String>() {
                @Override
                public String apply(String s) {
                  return s + ".class";
                }
              })
          .toSet();

  static final ImmutableMultimap<String, String> TARGET_METHODS =
      ImmutableMultimap.<String, String>builder()
          .put("addSuppressed", "(Ljava/lang/Throwable;)V")
          .put("getSuppressed", "()[Ljava/lang/Throwable;")
          .put("printStackTrace", "()V")
          .put("printStackTrace", "(Ljava/io/PrintStream;)V")
          .put("printStackTrace", "(Ljava/io/PrintWriter;)V")
          .build();

  static final ImmutableMap<String, String> METHOD_DESC_MAP =
      ImmutableMap.<String, String>builder()
          .put("(Ljava/lang/Throwable;)V", "(Ljava/lang/Throwable;Ljava/lang/Throwable;)V")
          .put("()[Ljava/lang/Throwable;", "(Ljava/lang/Throwable;)[Ljava/lang/Throwable;")
          .put("()V", "(Ljava/lang/Throwable;)V")
          .put("(Ljava/io/PrintStream;)V", "(Ljava/lang/Throwable;Ljava/io/PrintStream;)V")
          .put("(Ljava/io/PrintWriter;)V", "(Ljava/lang/Throwable;Ljava/io/PrintWriter;)V")
          .build();

  static final String CLOSE_RESOURCE_METHOD_NAME = "$closeResource";
  static final String CLOSE_RESOURCE_METHOD_DESC =
      "(Ljava/lang/Throwable;Ljava/lang/AutoCloseable;)V";

  private final ClassLoader classLoader;
  private final Set<String> visitedExceptionTypes;
  private final AtomicInteger numOfTryWithResourcesInvoked;
  /** Stores the internal class names of resources that need to be closed. */
  private final LinkedHashSet<String> resourceTypeInternalNames = new LinkedHashSet<>();

  private final boolean hasCloseResourceMethod;

  private String internalName;
  /**
   * Indicate whether the current class being desugared should be ignored. If the current class is
   * one of the runtime extension classes, then it should be ignored.
   */
  private boolean shouldCurrentClassBeIgnored;
  /**
   * A method node for $closeResource(Throwable, AutoCloseable). At then end, we specialize this
   * method node.
   */
  @Nullable private MethodNode closeResourceMethod;

  public TryWithResourcesRewriter(
      ClassVisitor classVisitor,
      ClassLoader classLoader,
      Set<String> visitedExceptionTypes,
      AtomicInteger numOfTryWithResourcesInvoked,
      boolean hasCloseResourceMethod) {
    super(Opcodes.ASM7, classVisitor);
    this.classLoader = classLoader;
    this.visitedExceptionTypes = visitedExceptionTypes;
    this.numOfTryWithResourcesInvoked = numOfTryWithResourcesInvoked;
    this.hasCloseResourceMethod = hasCloseResourceMethod;
  }

  @Override
  public void visit(
      int version,
      int access,
      String name,
      String signature,
      String superName,
      String[] interfaces) {
    super.visit(version, access, name, signature, superName, interfaces);
    internalName = name;
    shouldCurrentClassBeIgnored = THROWABLE_EXT_CLASS_INTERNAL_NAMES.contains(name);
    Preconditions.checkState(
        !shouldCurrentClassBeIgnored || !hasCloseResourceMethod,
        "The current class which will be ignored "
            + "contains $closeResource(Throwable, AutoCloseable).");
  }

  @Override
  public void visitEnd() {
    if (!resourceTypeInternalNames.isEmpty()) {
      checkNotNull(closeResourceMethod);
      for (String resourceInternalName : resourceTypeInternalNames) {
        boolean isInterface = isInterface(resourceInternalName.replace('/', '.'));
        // We use "this" to desugar the body of the close resource method.
        closeResourceMethod.accept(
            new CloseResourceMethodSpecializer(cv, resourceInternalName, isInterface));
      }
    } else {
      // It is possible that all calls to $closeResources(...) are in dead code regions, and the
      // calls are eliminated, which leaving the method $closeResources() unused. (b/78030676).
      // In this case, we just discard the method body.
      checkState(
          !hasCloseResourceMethod || closeResourceMethod != null,
          "There should be $closeResources(...) in the class file.");
    }
    super.visitEnd();
  }

  @Override
  public MethodVisitor visitMethod(
      int access, String name, String desc, String signature, String[] exceptions) {
    if (exceptions != null && exceptions.length > 0) {
      // collect exception types.
      Collections.addAll(visitedExceptionTypes, exceptions);
    }
    if (isSyntheticCloseResourceMethod(access, name, desc)) {
      checkState(closeResourceMethod == null, "The TWR rewriter has been used.");
      closeResourceMethod = new MethodNode(Opcodes.ASM7, access, name, desc, signature, exceptions);
      // Run the TWR desugar pass over the $closeResource(Throwable, AutoCloseable) first, for
      // example, to rewrite calls to AutoCloseable.close()..
      TryWithResourceVisitor twrVisitor =
          new TryWithResourceVisitor(
              internalName, name + desc, closeResourceMethod, classLoader, null);
      return twrVisitor;
    }

    MethodVisitor visitor = super.cv.visitMethod(access, name, desc, signature, exceptions);
    if (visitor == null || shouldCurrentClassBeIgnored) {
      return visitor;
    }

    BytecodeTypeInference inference = null;
    if (hasCloseResourceMethod) {
      /*
       * BytecodeTypeInference will run after the TryWithResourceVisitor, because when we are
       * processing a bytecode instruction, we need to know the types in the operand stack, which
       * are inferred after the previous instruction.
       */
      inference = new BytecodeTypeInference(access, internalName, name, desc);
      inference.setDelegateMethodVisitor(visitor);
      visitor = inference;
    }

    TryWithResourceVisitor twrVisitor =
        new TryWithResourceVisitor(internalName, name + desc, visitor, classLoader, inference);
    return twrVisitor;
  }

  public static boolean isSyntheticCloseResourceMethod(int access, String name, String desc) {
    return BitFlags.isSet(access, ACC_SYNTHETIC | ACC_STATIC)
        && CLOSE_RESOURCE_METHOD_NAME.equals(name)
        && CLOSE_RESOURCE_METHOD_DESC.equals(desc);
  }

  private boolean isInterface(String className) {
    // A generated class from desugaring a lambda expression or member reference isn't an interface.
    if (isDesugaredLambdaClass(className)) {
      return false;
    }
    try {
      Class<?> klass = classLoader.loadClass(className);
      return klass.isInterface();
    } catch (ClassNotFoundException e) {
      throw new AssertionError("Failed to load class when desugaring class " + internalName);
    }
  }

  public static boolean isCallToSyntheticCloseResource(
      String currentClassInternalName, int opcode, String owner, String name, String desc) {
    if (opcode != INVOKESTATIC) {
      return false;
    }
    if (!currentClassInternalName.equals(owner)) {
      return false;
    }
    if (!CLOSE_RESOURCE_METHOD_NAME.equals(name)) {
      return false;
    }
    if (!CLOSE_RESOURCE_METHOD_DESC.equals(desc)) {
      return false;
    }
    return true;
  }

  private class TryWithResourceVisitor extends MethodVisitor {

    private final ClassLoader classLoader;
    /** For debugging purpose. Enrich exception information. */
    private final String internalName;

    private final String methodSignature;
    @Nullable private final BytecodeTypeInference typeInference;

    public TryWithResourceVisitor(
        String internalName,
        String methodSignature,
        MethodVisitor methodVisitor,
        ClassLoader classLoader,
        @Nullable BytecodeTypeInference typeInference) {
      super(Opcodes.ASM7, methodVisitor);
      this.classLoader = classLoader;
      this.internalName = internalName;
      this.methodSignature = methodSignature;
      this.typeInference = typeInference;
    }

    @Override
    public void visitTryCatchBlock(Label start, Label end, Label handler, String type) {
      if (type != null) {
        visitedExceptionTypes.add(type); // type in a try-catch block must extend Throwable.
      }
      super.visitTryCatchBlock(start, end, handler, type);
    }

    @Override
    public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) {
      if (isCallToSyntheticCloseResource(internalName, opcode, owner, name, desc)) {
        checkNotNull(
            typeInference,
            "This method %s.%s has a call to $closeResource(Throwable, AutoCloseable) method, "
                + "but the type inference is null.",
            internalName,
            methodSignature);
        {
          // Check the exception type.
          InferredType exceptionClass = typeInference.getTypeOfOperandFromTop(1);
          if (!exceptionClass.isNull()) {
            Optional<String> exceptionClassInternalName = exceptionClass.getInternalName();
            checkState(
                exceptionClassInternalName.isPresent(),
                "The exception %s is not a reference type in %s.%s",
                exceptionClass,
                internalName,
                methodSignature);
            checkState(
                isAssignableFrom(
                    "java.lang.Throwable", exceptionClassInternalName.get().replace('/', '.')),
                "The exception type %s in %s.%s should be a subclass of java.lang.Throwable.",
                exceptionClassInternalName,
                internalName,
                methodSignature);
          }
        }

        InferredType resourceType = typeInference.getTypeOfOperandFromTop(0);
        Optional<String> resourceClassInternalName = resourceType.getInternalName();
        {
          // Check the resource type.
          checkState(
              resourceClassInternalName.isPresent(),
              "The resource class %s is not a reference type in %s.%s",
              resourceType,
              internalName,
              methodSignature);
          String resourceClassName = resourceClassInternalName.get().replace('/', '.');
          checkState(
              // For a resource class initialized from a lambda expression or an member reference,
              // it can implicitly be resolved with a close method.
              isDesugaredLambdaClass(resourceClassName) || hasCloseMethod(resourceClassName),
              "The resource class %s should have a close() method.",
              resourceClassName);
        }
        resourceTypeInternalNames.add(resourceClassInternalName.get());
        super.visitMethodInsn(
            opcode,
            owner,
            "$closeResource",
            "(Ljava/lang/Throwable;L" + resourceClassInternalName.get() + ";)V",
            itf);
        return;
      }

      if (!isMethodCallTargeted(opcode, owner, name, desc)) {
        super.visitMethodInsn(opcode, owner, name, desc, itf);
        return;
      }
      numOfTryWithResourcesInvoked.incrementAndGet();
      visitedExceptionTypes.add(checkNotNull(owner)); // owner extends Throwable.
      super.visitMethodInsn(
          INVOKESTATIC, THROWABLE_EXTENSION_INTERNAL_NAME, name, METHOD_DESC_MAP.get(desc), false);
    }

    private boolean isMethodCallTargeted(int opcode, String owner, String name, String desc) {
      if (opcode != INVOKEVIRTUAL) {
        return false;
      }
      if (!TARGET_METHODS.containsEntry(name, desc)) {
        return false;
      }
      if (visitedExceptionTypes.contains(owner)) {
        return true; // The owner is an exception that has been visited before.
      }
      return isAssignableFrom("java.lang.Throwable", owner.replace('/', '.'));
    }

    private boolean hasCloseMethod(String resourceClassName) {
      try {
        Class<?> klass = classLoader.loadClass(resourceClassName);
        klass.getMethod("close");
        return true;
      } catch (ClassNotFoundException e) {
        throw new AssertionError(
            "Failed to load class "
                + resourceClassName
                + " when desugaring method "
                + internalName
                + "."
                + methodSignature,
            e);
      } catch (NoSuchMethodException e) {
        // There is no close() method in the class, so return false.
        return false;
      }
    }

    private boolean isAssignableFrom(String baseClassName, String subClassName) {
      try {
        Class<?> baseClass = classLoader.loadClass(baseClassName);
        Class<?> subClass = classLoader.loadClass(subClassName);
        return baseClass.isAssignableFrom(subClass);
      } catch (ClassNotFoundException e) {
        throw new AssertionError(
            "Failed to load class when desugaring method "
                + internalName
                + "."
                + methodSignature
                + " when checking the assignable relation for class "
                + baseClassName
                + " and "
                + subClassName,
            e);
      }
    }
  }

  /**
   * A class to specialize the method $closeResource(Throwable, AutoCloseable), which does
   *
   * <ul>
   *   <li>Rename AutoCloseable to the given concrete resource type.
   *   <li>Adjust the invoke instruction that calls AutoCloseable.close()
   * </ul>
   */
  private static class CloseResourceMethodSpecializer extends ClassRemapper {

    private final boolean isResourceAnInterface;
    private final String targetResourceInternalName;

    public CloseResourceMethodSpecializer(
        ClassVisitor cv, String targetResourceInternalName, boolean isResourceAnInterface) {
      super(
          cv,
          new Remapper() {
            @Override
            public String map(String typeName) {
              if (typeName.equals("java/lang/AutoCloseable")) {
                return targetResourceInternalName;
              } else {
                return typeName;
              }
            }
          });
      this.targetResourceInternalName = targetResourceInternalName;
      this.isResourceAnInterface = isResourceAnInterface;
    }

    @Override
    public MethodVisitor visitMethod(
        int access, String name, String desc, String signature, String[] exceptions) {
      MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions);
      return new MethodVisitor(Opcodes.ASM7, mv) {
        @Override
        public void visitMethodInsn(
            int opcode, String owner, String name, String desc, boolean itf) {
          if (opcode == INVOKEINTERFACE
              && owner.endsWith("java/lang/AutoCloseable")
              && name.equals("close")
              && desc.equals("()V")
              && itf) {
            opcode = isResourceAnInterface ? INVOKEINTERFACE : INVOKEVIRTUAL;
            owner = targetResourceInternalName;
            itf = isResourceAnInterface;
          }
          super.visitMethodInsn(opcode, owner, name, desc, itf);
        }
      };
    }
  }

  private static boolean isDesugaredLambdaClass(String qualifiedClassName) {
    return qualifiedClassName.contains("$$Lambda$");
  }
}
