// 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.graph.genericsignature;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.genericsignature.testclasses.Foo;
import com.android.tools.r8.graph.genericsignature.testclasses.I;
import com.android.tools.r8.graph.genericsignature.testclasses.J;
import com.android.tools.r8.graph.genericsignature.testclasses.K;
import com.android.tools.r8.graph.genericsignature.testclasses.L;
import com.android.tools.r8.graph.genericsignature.testclasses.Main;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.util.List;
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 GenericSignatureKeepReferencesPruneTest extends TestBase {

  private final TestParameters parameters;
  private final boolean isCompat;
  private final boolean minify;

  @Parameters(name = "{0}, isCompat: {1}, minify: {2}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(),
        BooleanUtils.values(),
        BooleanUtils.values());
  }

  public GenericSignatureKeepReferencesPruneTest(
      TestParameters parameters, boolean isCompat, boolean minify) {
    this.parameters = parameters;
    this.isCompat = isCompat;
    this.minify = minify;
  }

  @Test
  public void testJvm() throws Exception {
    assumeTrue(parameters.isCfRuntime());
    assumeTrue(isCompat);
    assumeTrue(!minify);
    testForJvm()
        .addProgramClasses(I.class, Foo.class, J.class, K.class, L.class)
        .addProgramClassesAndInnerClasses(Main.class)
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(getExpected(Foo.class.getTypeName(), I.class.getTypeName()));
  }

  @Test
  public void testR8() throws Exception {
    R8TestRunResult runResult =
        (isCompat ? testForR8Compat(parameters.getBackend()) : testForR8(parameters.getBackend()))
            .addProgramClasses(I.class, Foo.class, J.class, K.class, L.class)
            .addProgramClassesAndInnerClasses(Main.class)
            .addKeepClassAndMembersRules(Main.class)
            .setMinApi(parameters.getApiLevel())
            .addKeepAttributeSignature()
            .addKeepAttributeInnerClassesAndEnclosingMethod()
            .enableInliningAnnotations()
            .enableNeverClassInliningAnnotations()
            .compile()
            .inspect(this::inspectSignatures)
            .run(parameters.getRuntime(), Main.class);
    runResult.assertSuccess();
    CodeInspector inspector = runResult.inspector();
    // Foo and I exists due to the assertions in the inspection.
    runResult.assertSuccessWithOutputLines(
        getExpected(
            inspector.clazz(Foo.class).getFinalName(), inspector.clazz(I.class).getFinalName()));
  }

  private String[] getExpected(String fooName, String iName) {
    if (isCompat) {
      return new String[] {
        fooName + "<java.lang.String>",
        iName + "<java.lang.Integer, " + fooName + "<java.lang.Integer>>",
        iName + "<java.lang.String, " + fooName + "<java.lang.String>>",
        "Hello world"
      };
    } else {
      return new String[] {
        "class " + fooName, "interface " + iName, "interface " + iName, "Hello world"
      };
    }
  }

  private void inspectSignatures(CodeInspector inspector) {
    ClassSubject fooClass = inspector.clazz(Foo.class);
    assertThat(fooClass, isPresent());
    assertEquals(
        isCompat ? "<T::Ljava/lang/Comparable<TT;>;>Ljava/lang/Object;" : null,
        fooClass.getFinalSignatureAttribute());
    ClassSubject iClass = inspector.clazz(I.class);
    assertThat(iClass, isPresent());
    assertEquals(
        isCompat
            ? "<T::Ljava/lang/Comparable<TT;>;R:L"
                + fooClass.getFinalBinaryName()
                + "<TT;>;>Ljava/lang/Object;"
            : null,
        iClass.getFinalSignatureAttribute());
    ClassSubject fooInnerClass = inspector.clazz(Main.class.getTypeName() + "$1");
    assertThat(fooInnerClass, isPresent());
    assertEquals(
        isCompat
            ? "Ljava/lang/Object;L"
                + iClass.getFinalBinaryName()
                + "<Ljava/lang/String;L"
                + fooClass.getFinalBinaryName()
                + "<Ljava/lang/String;>;>;"
            : null,
        fooInnerClass.getFinalSignatureAttribute());
  }
}
