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

import static org.hamcrest.core.StringContains.containsString;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.AndroidApiLevel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
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 NoBackportForAndroidPlatform extends TestBase implements Opcodes {

  private final TestParameters parameters;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    // The use of high API level will produce dex files with high DEX version, so only run on high
    // API level VMs.
    return getTestParameters()
        .withDexRuntimes()
        .withApiLevelsStartingAtIncluding(AndroidApiLevel.P)
        .build();
  }

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

  @Test
  public void backportSucceedsOnSupportedApiLevel() throws Exception {
    testForD8()
        .addProgramClassFileData(mainWithMathMultiplyExactLongInt())
        .setMinApi(AndroidApiLevel.B)
        .run(parameters.getRuntime(), "Test")
        .assertSuccessWithOutputLines("4");
  }

  @Test
  public void warningForNonPlatformBuild() throws Exception {
    testForD8()
        .addProgramClassFileData(mainWithMathMultiplyExactLongInt())
        .setMinApi(30)
        .compile()
        .assertOnlyWarnings()
        .assertWarningMessageThatMatches(
            containsString("An API level of 30 is not supported by this compiler"))
        .run(parameters.getRuntime(), "Test")
        .assertFailureWithErrorThatMatches(
            containsString("java.lang.NoSuchMethodError: No static method multiplyExact(JI)J"));
  }

  @Test
  public void noWarningForPlatformBuild() throws Exception {
    testForD8()
        .addProgramClassFileData(mainWithMathMultiplyExactLongInt())
        .setMinApi(AndroidApiLevel.magicApiLevelUsedByAndroidPlatformBuild)
        .run(parameters.getRuntime(), "Test")
        .assertFailureWithErrorThatMatches(
            containsString("java.lang.NoSuchMethodError: No static method multiplyExact(JI)J"));
  }

  // Code for:
  //
  // class Test {
  //   public static void main(String[] args) {
  //     // Call Math.multiplyExact(long, int), which is not in Android Q.
  //     System.out.println(Math.multiplyExact(2L, 2));
  //   }
  // }
  //
  private byte[] mainWithMathMultiplyExactLongInt() {

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

    classWriter.visit(V1_8, ACC_SUPER, "Test", null, "java/lang/Object", null);

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

    {
      methodVisitor = classWriter.visitMethod(0, "<init>", "()V", null, null);
      methodVisitor.visitCode();
      Label label0 = new Label();
      methodVisitor.visitLabel(label0);
      methodVisitor.visitLineNumber(1, label0);
      methodVisitor.visitVarInsn(ALOAD, 0);
      methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
      methodVisitor.visitInsn(RETURN);
      methodVisitor.visitMaxs(1, 1);
      methodVisitor.visitEnd();
    }
    {
      methodVisitor =
          classWriter.visitMethod(
              ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
      methodVisitor.visitCode();
      Label label0 = new Label();
      methodVisitor.visitLabel(label0);
      methodVisitor.visitLineNumber(3, label0);
      methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
      methodVisitor.visitLdcInsn(Long.valueOf(2L));
      methodVisitor.visitLdcInsn(Integer.valueOf(2));
      methodVisitor.visitMethodInsn(
          INVOKESTATIC, "java/lang/Math", "multiplyExact", "(JI)J", false);
      methodVisitor.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(J)V", false);
      Label label1 = new Label();
      methodVisitor.visitLabel(label1);
      methodVisitor.visitLineNumber(4, label1);
      methodVisitor.visitInsn(RETURN);
      methodVisitor.visitMaxs(5, 1);
      methodVisitor.visitEnd();
    }
    classWriter.visitEnd();

    return classWriter.toByteArray();
  }
}
