// Copyright (c) 2019, 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.backports;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRuntime.CfVm;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cfmethodgeneration.MethodGenerationBase;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.FileUtils;
import com.google.common.collect.ImmutableList;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class GenerateBackportMethods extends MethodGenerationBase {

  private final DexType GENERATED_TYPE =
      factory.createType("Lcom/android/tools/r8/ir/desugar/backports/BackportedMethods;");
  private final List<Class<?>> METHOD_TEMPLATE_CLASSES =
      ImmutableList.of(
          AtomicReferenceFieldUpdaterMethods.class,
          BooleanMethods.class,
          ByteMethods.class,
          CharSequenceMethods.class,
          CharacterMethods.class,
          CloseResourceMethod.class,
          CollectionMethods.class,
          CollectionsMethods.class,
          DoubleMethods.class,
          FloatMethods.class,
          IntegerMethods.class,
          LongMethods.class,
          MathMethods.class,
          ObjectsMethods.class,
          OptionalMethods.class,
          ShortMethods.class,
          StreamMethods.class,
          StringMethods.class,
          ThrowableMethods.class,
          UnsafeMethods.class);

  protected final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withCfRuntime(CfVm.JDK9).build();
  }

  public GenerateBackportMethods(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Override
  protected DexType getGeneratedType() {
    return GENERATED_TYPE;
  }

  @Override
  protected List<Class<?>> getMethodTemplateClasses() {
    return METHOD_TEMPLATE_CLASSES;
  }

  @Override
  protected int getYear() {
    return 2021;
  }

  private static CfInstruction rewriteToJava9API(
      DexItemFactory itemFactory, CfInstruction instruction) {
    // Rewrite static invoke of javaUtilLongParseUnsignedLongStub to j.l.Long.parseUnsignedLong.
    if (instruction.isInvoke()
        && instruction
            .asInvoke()
            .getMethod()
            .getName()
            .toString()
            .equals("javaLangLongParseUnsignedLongStub")) {
      CfInvoke invoke = instruction.asInvoke();
      return new CfInvoke(
          invoke.getOpcode(),
          itemFactory.createMethod(
              itemFactory.createType("Ljava/lang/Long;"),
              invoke.getMethod().getProto(),
              itemFactory.createString("parseUnsignedLong")),
          invoke.isInterface());
    } else {
      return instruction;
    }
  }

  private static CfInstruction rewriteToUnsafe(
      DexItemFactory itemFactory, CfInstruction instruction) {
    // Rewrite references to UnsafeStub to sun.misc.Unsafe.
    if (instruction.isInvoke()) {
      String name = instruction.asInvoke().getMethod().getName().toString();
      if (name.equals("compareAndSwapObject") || name.equals("getObject")) {
        CfInvoke invoke = instruction.asInvoke();
        return new CfInvoke(
            invoke.getOpcode(),
            itemFactory.createMethod(
                itemFactory.createType("Lsun/misc/Unsafe;"),
                invoke.getMethod().getProto(),
                itemFactory.createString(name)),
            invoke.isInterface());
      }
    }
    if (instruction.isFrame()) {
      return instruction
          .asFrame()
          .map(
              type ->
                  (type.getTypeName().endsWith("$UnsafeStub"))
                      ? itemFactory.createType("Lsun/misc/Unsafe;")
                      : type);
    }
    return instruction;
  }

  @Override
  protected CfCode getCode(String holderName, String methodName, CfCode code) {
    if (methodName.endsWith("Stub")) {
      // Don't include stubs targeted only for rewriting in the generated code.
      return null;
    }
    if (holderName.equals("LongMethods") && methodName.equals("parseUnsignedLongWithRadix")) {
      code.setInstructions(
          code.getInstructions().stream()
              .map(instruction -> rewriteToJava9API(factory, instruction))
              .collect(Collectors.toList()));
    }
    if (holderName.equals("UnsafeMethods") && methodName.equals("compareAndSwapObject")) {
      code.setInstructions(
          code.getInstructions().stream()
              .map(instruction -> rewriteToUnsafe(factory, instruction))
              .collect(Collectors.toList()));
    }
    return code;
  }

  @Test
  public void testBackportsGenerated() throws Exception {
    ArrayList<Class<?>> sorted = new ArrayList<>(getMethodTemplateClasses());
    sorted.sort(Comparator.comparing(Class::getTypeName));
    assertEquals("Classes should be listed in sorted order", sorted, getMethodTemplateClasses());
    assertEquals(
        FileUtils.readTextFile(getGeneratedFile(), StandardCharsets.UTF_8), generateMethods());
  }

  public static void main(String[] args) throws Exception {
    new GenerateBackportMethods(null).generateMethodsAndWriteThemToFile();
  }
}
