// Copyright (c) 2018, 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.ir.desugar;

import com.android.tools.r8.dex.Constants;
import com.android.tools.r8.graph.AppInfo;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.ClassAccessFlags;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexApplication.Builder;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexTypeList;
import com.android.tools.r8.graph.MethodAccessFlags;
import com.android.tools.r8.graph.ParameterAnnotationsList;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionIterator;
import com.android.tools.r8.ir.code.InvokeStatic;
import com.android.tools.r8.ir.conversion.IRConverter;
import com.android.tools.r8.ir.synthetic.TemplateMethodCode;
import com.android.tools.r8.origin.SynthesizedOrigin;
import com.android.tools.r8.utils.InternalOptions;
import com.google.common.collect.Sets;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;

// Try with resources outlining processor. Handles $closeResource methods
// synthesized by java 9 compiler.
//
// Works in two phases:
//   a. during method code processing finds all references to $closeResource(...) synthesized
//      by java compiler, and replaces them with references to a special utility class method.
//   b. after all methods are processed and if there was at least one method referencing
//      $closeResource(...), it synthesizes utility class with appropriate methods.
//
// Note that we don't remove $closeResource(...) synthesized by java compiler, relying on
// tree shaking to remove them since now they should not be referenced.
//
public final class TwrCloseResourceRewriter {

  public static final String UTILITY_CLASS_NAME = "$r8$twr$utility";
  public static final String UTILITY_CLASS_DESCRIPTOR = "L$r8$twr$utility;";

  private final AppView<? extends AppInfo> appView;
  private final IRConverter converter;

  private final DexMethod twrCloseResourceMethod;

  private final Set<DexProgramClass> referencingClasses = Sets.newConcurrentHashSet();

  public TwrCloseResourceRewriter(AppView<? extends AppInfo> appView, IRConverter converter) {
    this.appView = appView;
    this.converter = converter;

    DexItemFactory dexItemFactory = appView.dexItemFactory();
    DexType twrUtilityClass = dexItemFactory.createType(UTILITY_CLASS_DESCRIPTOR);
    DexProto twrCloseResourceProto =
        dexItemFactory.createProto(
            dexItemFactory.voidType, dexItemFactory.throwableType, dexItemFactory.objectType);
    this.twrCloseResourceMethod =
        dexItemFactory.createMethod(
            twrUtilityClass, twrCloseResourceProto, dexItemFactory.twrCloseResourceMethodName);
  }

  // Rewrites calls to $closeResource() method. Can be invoked concurrently.
  public void rewriteMethodCode(IRCode code) {
    InstructionIterator iterator = code.instructionIterator();
    AppInfo appInfo = appView.appInfo();
    while (iterator.hasNext()) {
      Instruction instruction = iterator.next();
      if (!instruction.isInvokeStatic()) {
        continue;
      }
      InvokeStatic invoke = instruction.asInvokeStatic();
      if (!isSynthesizedCloseResourceMethod(invoke.getInvokedMethod(), appView)) {
        continue;
      }

      // Replace with a call to a synthetic utility with the only
      // implementation of the method $closeResource.
      assert invoke.outValue() == null;
      assert invoke.inValues().size() == 2;
      iterator.replaceCurrentInstruction(
          new InvokeStatic(twrCloseResourceMethod, null, invoke.inValues()));

      // Mark as a class referencing utility class.
      referencingClasses.add(appInfo.definitionFor(code.method.method.holder).asProgramClass());
    }
  }

  public static boolean isSynthesizedCloseResourceMethod(
      DexMethod method, AppView<? extends AppInfo> appView) {
    DexMethod original = appView.graphLense().getOriginalMethodSignature(method);
    assert original != null;
    // We consider all methods of *any* class with expected name and signature
    // to be synthesized by java 9 compiler for try-with-resources, reasoning:
    //
    //  * we need to look to all potential classes because the calls might be
    //    moved by inlining.
    //  * theoretically we could check appropriate encoded method for having
    //    right attributes, but it still does not guarantee much since we also
    //    need to look into code and doing this seems an overkill
    //
    DexItemFactory dexItemFactory = appView.dexItemFactory();
    return original.name == dexItemFactory.twrCloseResourceMethodName
        && original.proto == dexItemFactory.twrCloseResourceMethodProto;
  }

  public void synthesizeUtilityClass(
      Builder<?> builder, ExecutorService executorService, InternalOptions options)
      throws ExecutionException {
    if (referencingClasses.isEmpty()) {
      return;
    }

    // The only encoded method.
    TemplateMethodCode code = new CloseResourceMethodCode(options, twrCloseResourceMethod);
    MethodAccessFlags flags = MethodAccessFlags.fromSharedAccessFlags(
        Constants.ACC_PUBLIC | Constants.ACC_STATIC | Constants.ACC_SYNTHETIC, false);
    DexEncodedMethod method = new DexEncodedMethod(twrCloseResourceMethod,
        flags, DexAnnotationSet.empty(), ParameterAnnotationsList.empty(), code);

    // Create utility class.
    DexProgramClass utilityClass =
        new DexProgramClass(
            twrCloseResourceMethod.holder,
            null,
            new SynthesizedOrigin("twr utility class", getClass()),
            ClassAccessFlags.fromSharedAccessFlags(Constants.ACC_PUBLIC | Constants.ACC_SYNTHETIC),
            appView.dexItemFactory().objectType,
            DexTypeList.empty(),
            null,
            null,
            Collections.emptyList(),
            null,
            Collections.emptyList(),
            DexAnnotationSet.empty(),
            DexEncodedField.EMPTY_ARRAY,
            DexEncodedField.EMPTY_ARRAY,
            new DexEncodedMethod[] {method},
            DexEncodedMethod.EMPTY_ARRAY,
            appView.dexItemFactory().getSkipNameValidationForTesting(),
            referencingClasses);

    code.setUpContext(utilityClass);

    // Process created class and method.
    AppInfo appInfo = appView.appInfo();
    boolean addToMainDexList =
        referencingClasses.stream().anyMatch(clazz -> appInfo.isInMainDexList(clazz.type));
    appInfo.addSynthesizedClass(utilityClass);
    converter.optimizeSynthesizedClass(utilityClass, executorService);
    builder.addSynthesizedClass(utilityClass, addToMainDexList);
  }

  private static final class CloseResourceMethodCode extends TemplateMethodCode {
    private static final String TEMPLATE_METHOD_NAME = "closeResourceImpl";
    private static final String TEMPLATE_METHOD_DESC = "(Ljava/lang/Throwable;Ljava/lang/Object;)V";

    CloseResourceMethodCode(InternalOptions options, DexMethod method) {
      super(options, method, TEMPLATE_METHOD_NAME, TEMPLATE_METHOD_DESC);
    }

    // The following method defines the code of
    //
    //     public static void $closeResource(Throwable throwable, Object resource)
    //
    // method to be inserted into utility class, and will be used instead
    // of the following implementation added by java 9 compiler:
    //
    //     private static void $closeResource(Throwable, AutoCloseable);
    //        0: aload_0
    //        1: ifnull        22
    //        4: aload_1
    //        5: invokeinterface #1,  1  // java/lang/AutoCloseable.close:()V
    //       10: goto          28
    //       13: astore_2
    //       14: aload_0
    //       15: aload_2
    //       16: invokevirtual #3 // java/lang/Throwable.addSuppressed:(Ljava/lang/Throwable;)V
    //       19: goto          28
    //       22: aload_1
    //       23: invokeinterface #1,  1  // java/lang/AutoCloseable.close:()V
    //       28: return
    //
    public static void closeResourceImpl(Throwable throwable, Object resource) throws Throwable {
      try {
        if (resource instanceof AutoCloseable) {
          ((AutoCloseable) resource).close();
        } else {
          try {
            Method method = resource.getClass().getMethod("close");
            method.invoke(resource);
          } catch (NoSuchMethodException | SecurityException e) {
            throw new AssertionError(resource.getClass() + " does not have a close() method.", e);
          } catch (IllegalAccessException
              | IllegalArgumentException | ExceptionInInitializerError e) {
            throw new AssertionError("Fail to call close() on " + resource.getClass(), e);
          } catch (InvocationTargetException e) {
            throw e.getCause();
          }
        }
      } catch (Throwable e) {
        // NOTE: we don't call addSuppressed(...) since the call will be removed
        // by try-with-resource desugar anyways.
        throw throwable != null ? throwable : e;
      }
    }
  }
}
