// 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.naming.arraytypes;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.StringUtils;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.function.Consumer;
import org.junit.BeforeClass;
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 ArrayTypesTest extends TestBase {

  private final TestParameters parameters;

  private static String packageName;
  private static String arrayBaseTypeDescriptor;
  private static String arrayTypeDescriptor;
  private static String generatedTestClassName;
  private static String expectedOutput;

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

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimesAndApiLevels().build();
  }

  @BeforeClass
  public static void setup() {
    packageName = ArrayTypesTest.class.getPackage().getName();
    arrayBaseTypeDescriptor =
        DescriptorUtils.getDescriptorFromClassBinaryName(
            DescriptorUtils.getBinaryNameFromJavaType(
                A.class.getTypeName()));
    arrayTypeDescriptor = "[" + arrayBaseTypeDescriptor;
    generatedTestClassName = packageName + "." + "GeneratedTestClass";
    expectedOutput = StringUtils.lines(
        "javac code:",
        "Length: EQ",
        "Hashcode: EQ",
        "toString: EQ",
        "ASM code:",
        "Clones: NE",
        "Hashcode: EQ",
        "Compare with Object: true",
        "Compare with array type: true",
        "toString: true",
        "Got expected exception",
        "Done");
  }

  private void runR8Test(boolean enableMinification) throws Exception {
    testForR8(parameters.getBackend())
        .minification(enableMinification)
        .addProgramClasses(Main.class, A.class)
        .addProgramClassFileData(generateTestClass())
        .addKeepMainRule(Main.class)
        .addKeepRules("-keep class " + generatedTestClassName + " { test(...); }")
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutput(expectedOutput);
  }

  @Test
  public void testR8() throws Exception {
    runR8Test(true);
  }

  @Test
  public void testR8NoMinification() throws Exception {
    runR8Test(false);
  }

  @Test
  public void testR8ApplyMapping() throws Exception {
    // Rename the array type (keep it in the same package for access reasons).
    Path mappingFile = temp.newFile("mapping.txt").toPath();
    FileUtils.writeTextFile(
        mappingFile,
        StringUtils.lines(
            A.class.getTypeName() + " -> " + packageName + ".a:"));

    testForR8(parameters.getBackend())
        .addProgramClasses(Main.class, A.class)
        .addProgramClassFileData(generateTestClass())
        .addKeepMainRule(Main.class)
        .addKeepRules("-applymapping " + mappingFile.toAbsolutePath())
        .noMinification()
        .noTreeShaking()
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutput(expectedOutput);
  }

  @Test
  public void testRuntime() throws Exception {
    testForRuntime(parameters)
        .addProgramClasses(Main.class, A.class)
        .addProgramClassFileData(generateTestClass())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutput(expectedOutput);
  }

  public static byte[] generateTestClass() {

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

    classWriter.visit(
        Opcodes.V1_6,
        Opcodes.ACC_PUBLIC | Opcodes.ACC_FINAL | Opcodes.ACC_SUPER | Opcodes.ACC_ENUM,
        DescriptorUtils.getBinaryNameFromJavaType(generatedTestClassName),
        null,
        "java/lang/Object",
        null);

    {
      mv = classWriter.visitMethod(
          Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC,
          "test", "(" + arrayTypeDescriptor + ")V",
          null,
          null);

      mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
      mv.visitLdcInsn("ASM code:");
      mv.visitMethodInsn(
          Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);

      // Invoke clone using both java.lang.Object and array type an holder.
      mv.visitVarInsn(Opcodes.ALOAD, 0);
      mv.visitMethodInsn(
          Opcodes.INVOKEVIRTUAL, "java/lang/Object", "clone", "()Ljava/lang/Object;", false);
      mv.visitVarInsn(Opcodes.ASTORE, 1);

      mv.visitVarInsn(Opcodes.ALOAD, 0);
      mv.visitMethodInsn(
          Opcodes.INVOKEVIRTUAL, arrayTypeDescriptor, "clone", "()Ljava/lang/Object;", false);
      mv.visitVarInsn(Opcodes.ASTORE, 2);

      printCompareObjectsIdentical("Clones: ", mv, (mvCopy) -> {
        assert mv == mvCopy;
        mv.visitVarInsn(Opcodes.ALOAD, 1);
        mv.visitVarInsn(Opcodes.ALOAD, 2);
      });

      printCompareIntegers(
          "Hashcode: ",
          mv,
          (mvCopy) -> {
            assert mv == mvCopy;
            // Invoke hashCode using both java.lang.Object and array type an holder.
            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Object", "hashCode", "()I", false);

            mv.visitVarInsn(Opcodes.ALOAD, 0);
            mv.visitMethodInsn(
                Opcodes.INVOKEVIRTUAL, arrayTypeDescriptor, "hashCode", "()I", false);
          });

      printBoolean("Compare with Object: ", mv, (mvCopy) -> {
        assert mv == mvCopy;
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(
            Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false);
      });

      printBoolean("Compare with array type: ", mv, (mvCopy) -> {
        assert mv == mvCopy;
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(
            Opcodes.INVOKEVIRTUAL, arrayTypeDescriptor, "equals", "(Ljava/lang/Object;)Z", false);
      });

      printBoolean("toString: ", mv, (mvCopy) -> {
        assert mv == mvCopy;
        // Invoke toString using both java.lang.Object and array type an holder.
        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(
            Opcodes.INVOKEVIRTUAL, "java/lang/Object", "toString", "()Ljava/lang/String;", false);

        mv.visitVarInsn(Opcodes.ALOAD, 0);
        mv.visitMethodInsn(
            Opcodes.INVOKEVIRTUAL, arrayTypeDescriptor, "toString", "()Ljava/lang/String;", false);

        // Compare the toString strings.
        mv.visitMethodInsn(
            Opcodes.INVOKEVIRTUAL, "java/lang/Object", "equals", "(Ljava/lang/Object;)Z", false);
      });

      // Finally invoke a method not present on an array type.
      mv.visitVarInsn(Opcodes.ALOAD, 0);
      mv.visitMethodInsn(
          Opcodes.INVOKEVIRTUAL, arrayTypeDescriptor, "notPresent", "()Ljava/lang/String;", false);

      mv.visitInsn(Opcodes.RETURN);
      mv.visitMaxs(10, 10);
      mv.visitEnd();
    }

    classWriter.visitEnd();

    return classWriter.toByteArray();
  }

  public static void printCompareIntegers(
      String header, MethodVisitor mv, Consumer<MethodVisitor> consumer) {
    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
    mv.visitLdcInsn(header);
    mv.visitMethodInsn(
        Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", false);

    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");

    consumer.accept(mv);

    Label neLabel = new Label();
    Label printLabel = new Label();
    mv.visitJumpInsn(Opcodes.IF_ICMPNE, neLabel);
    mv.visitLdcInsn("EQ");
    mv.visitJumpInsn(Opcodes.GOTO, printLabel);
    mv.visitLabel(neLabel);
    mv.visitLdcInsn("NE");
    mv.visitLabel(printLabel);
    mv.visitMethodInsn(
        Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
  }

  public static void printCompareObjectsIdentical(
      String header, MethodVisitor mv, Consumer<MethodVisitor> consumer) {
    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
    mv.visitLdcInsn(header);
    mv.visitMethodInsn(
        Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", false);

    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");

    consumer.accept(mv);

    Label neLabel = new Label();
    Label printLabel = new Label();
    mv.visitJumpInsn(Opcodes.IF_ACMPNE, neLabel);
    mv.visitLdcInsn("EQ");
    mv.visitJumpInsn(Opcodes.GOTO, printLabel);
    mv.visitLabel(neLabel);
    mv.visitLdcInsn("NE");
    mv.visitLabel(printLabel);
    mv.visitMethodInsn(
        Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
  }

  public static void printBoolean(
      String header, MethodVisitor mv, Consumer<MethodVisitor> consumer) {
    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
    mv.visitLdcInsn(header);
    mv.visitMethodInsn(
        Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V", false);

    mv.visitFieldInsn(Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");

    consumer.accept(mv);

    Label neLabel = new Label();
    Label printLabel = new Label();
    mv.visitJumpInsn(Opcodes.IFNE, neLabel);
    mv.visitLdcInsn("false");
    mv.visitJumpInsn(Opcodes.GOTO, printLabel);
    mv.visitLabel(neLabel);
    mv.visitLdcInsn("true");
    mv.visitLabel(printLabel);
    mv.visitMethodInsn(
        Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
  }
}

class A {

}

class Main {

  public static void main(String[] args) throws Exception {
    A[] array = new A[2];
    A[] clone = array.clone();

    System.out.println("javac code:");

    if (array.length == clone.length) {
      System.out.println("Length: EQ");
    }

    if (array.hashCode() == array.hashCode()) {
      System.out.println("Hashcode: EQ");
    }

    if (array.toString().equals(array.toString())) {
      System.out.println("toString: EQ");
    }

    Class<?> generatedTestClass =
        Class.forName(Main.class.getPackage().getName() + "." + "GeneratedTestClass");
    Method testMethod = generatedTestClass.getDeclaredMethod("test", array.getClass());
    try {
      testMethod.invoke(null, new Object[]{array});
    } catch (java.lang.reflect.InvocationTargetException e) {
      System.out.println("Got expected exception");
    }
    System.out.println("Done");
  }
}
