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

import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ir.desugar.desugaredlibrary.legacyspecification.LegacyDesugaredLibrarySpecification;
import com.android.tools.r8.ir.desugar.desugaredlibrary.legacyspecification.LegacyRewritingFlags;
import com.android.tools.r8.ir.desugar.desugaredlibrary.legacyspecification.LegacyTopLevelFlags;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import java.io.IOException;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

@RunWith(Parameterized.class)
public class RetargetAndBackportTest extends DesugaredLibraryTestBase implements Opcodes {

  Backend backend;

  @Parameters(name = "{0} {1}")
  public static List<Object[]> data() {
    return buildParameters(getTestParameters().withNoneRuntime().build(), Backend.values());
  }

  public RetargetAndBackportTest(TestParameters parameters, Backend backend) {
    this.backend = backend;
  }

  /**
   * Add this library desugaring configuration:
   * "library_flags": [
   *  {
   *    "rewrite_prefix":{"java.time.": "j$.time."},
   *    "backport": {"java.lang.DesugarMath": "java.lang.Math"},
   *  }
   * ],
   */
  private static void specifyDesugaredLibrary(InternalOptions options) {
    LegacyRewritingFlags rewritingFlags =
        LegacyRewritingFlags.builder(options.itemFactory, options.reporter, Origin.unknown())
            .putRewritePrefix("java.time.", "j$.time.")
            .putBackportCoreLibraryMember("java.lang.DesugarMath", "java.lang.Math")
            .build();
    try {
      options.setDesugaredLibrarySpecificationForTesting(
          new LegacyDesugaredLibrarySpecification(
              LegacyTopLevelFlags.testing(), rewritingFlags, true),
          ToolHelper.getDesugarJDKLibs(),
          ToolHelper.getAndroidJar(AndroidApiLevel.R));
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  @Test
  public void test() throws Exception {
    testForL8(AndroidApiLevel.B, backend)
        .noDefaultDesugarJDKLibs()
        .addProgramClassFileData(dump())
        .addLibraryFiles(getLibraryFile())
        .addOptionsModifier(RetargetAndBackportTest::specifyDesugaredLibrary)
        .compile()
        .inspect(
            inspector -> {
              assertTrue(
                  inspector
                      .clazz("j$.time.Duration")
                      .uniqueMethodWithName("toMillis")
                      .streamInstructions()
                      .filter(InstructionSubject::isInvokeStatic)
                      .map(InstructionSubject::toString)
                      .allMatch(s -> s.contains("Backport")));
            });
  }

  // Dump of java.time.Duration from JDK 11 based desugared library input built from
  // https://github.com/google/desugar_jdk_libs/commit/a2a0a26c06cbee9144eceaefd8c65e1bae2b611c.
  public static byte[] dump() {

    ClassWriter classWriter = new ClassWriter(0);
    MethodVisitor methodVisitor;

    classWriter.visit(
        V11,
        ACC_PUBLIC | ACC_FINAL | ACC_SUPER,
        "java/time/Duration",
        "Ljava/lang/Object;Ljava/time/temporal/TemporalAmount;Ljava/lang/Comparable<Ljava/time/Duration;>;Ljava/io/Serializable;",
        "java/lang/Object",
        new String[] {
          "java/time/temporal/TemporalAmount", "java/lang/Comparable", "java/io/Serializable"
        });

    classWriter.visitSource("Duration.java", null);

    {
      methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "toMillis", "()J", null, null);
      methodVisitor.visitCode();
      Label label0 = new Label();
      methodVisitor.visitLabel(label0);
      methodVisitor.visitLineNumber(1217, label0);
      methodVisitor.visitVarInsn(ALOAD, 0);
      methodVisitor.visitFieldInsn(GETFIELD, "java/time/Duration", "seconds", "J");
      methodVisitor.visitVarInsn(LSTORE, 1);
      Label label1 = new Label();
      methodVisitor.visitLabel(label1);
      methodVisitor.visitLineNumber(1218, label1);
      methodVisitor.visitVarInsn(ALOAD, 0);
      methodVisitor.visitFieldInsn(GETFIELD, "java/time/Duration", "nanos", "I");
      methodVisitor.visitInsn(I2L);
      methodVisitor.visitVarInsn(LSTORE, 3);
      Label label2 = new Label();
      methodVisitor.visitLabel(label2);
      methodVisitor.visitLineNumber(1219, label2);
      methodVisitor.visitVarInsn(LLOAD, 1);
      methodVisitor.visitInsn(LCONST_0);
      methodVisitor.visitInsn(LCMP);
      Label label3 = new Label();
      methodVisitor.visitJumpInsn(IFGE, label3);
      Label label4 = new Label();
      methodVisitor.visitLabel(label4);
      methodVisitor.visitLineNumber(1222, label4);
      methodVisitor.visitVarInsn(LLOAD, 1);
      methodVisitor.visitInsn(LCONST_1);
      methodVisitor.visitInsn(LADD);
      methodVisitor.visitVarInsn(LSTORE, 1);
      Label label5 = new Label();
      methodVisitor.visitLabel(label5);
      methodVisitor.visitLineNumber(1223, label5);
      methodVisitor.visitVarInsn(LLOAD, 3);
      methodVisitor.visitLdcInsn(new Long(1000000000L));
      methodVisitor.visitInsn(LSUB);
      methodVisitor.visitVarInsn(LSTORE, 3);
      methodVisitor.visitLabel(label3);
      methodVisitor.visitLineNumber(1225, label3);
      methodVisitor.visitFrame(
          Opcodes.F_APPEND, 2, new Object[] {Opcodes.LONG, Opcodes.LONG}, 0, null);
      methodVisitor.visitVarInsn(LLOAD, 1);
      methodVisitor.visitIntInsn(SIPUSH, 1000);
      methodVisitor.visitMethodInsn(
          INVOKESTATIC, "java/lang/DesugarMath", "multiplyExact", "(JI)J", false);
      methodVisitor.visitVarInsn(LSTORE, 5);
      Label label6 = new Label();
      methodVisitor.visitLabel(label6);
      methodVisitor.visitLineNumber(1226, label6);
      methodVisitor.visitVarInsn(LLOAD, 5);
      methodVisitor.visitVarInsn(LLOAD, 3);
      methodVisitor.visitLdcInsn(new Long(1000000L));
      methodVisitor.visitInsn(LDIV);
      methodVisitor.visitMethodInsn(
          INVOKESTATIC, "java/lang/DesugarMath", "addExact", "(JJ)J", false);
      methodVisitor.visitVarInsn(LSTORE, 5);
      Label label7 = new Label();
      methodVisitor.visitLabel(label7);
      methodVisitor.visitLineNumber(1227, label7);
      methodVisitor.visitVarInsn(LLOAD, 5);
      methodVisitor.visitInsn(LRETURN);
      Label label8 = new Label();
      methodVisitor.visitLabel(label8);
      methodVisitor.visitLocalVariable("this", "Ljava/time/Duration;", null, label0, label8, 0);
      methodVisitor.visitLocalVariable("tempSeconds", "J", null, label1, label8, 1);
      methodVisitor.visitLocalVariable("tempNanos", "J", null, label2, label8, 3);
      methodVisitor.visitLocalVariable("millis", "J", null, label6, label8, 5);
      methodVisitor.visitMaxs(6, 7);
      methodVisitor.visitEnd();
    }
    classWriter.visitEnd();

    return classWriter.toByteArray();
  }
}
