// Copyright (c) 2018, 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.shaking.annotations;

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertFalse;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.NeverClassInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.graph.DexAnnotationSet;
import com.android.tools.r8.graph.DexEncodedAnnotation;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.DexValue;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
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 PrunedOrMergedAnnotationTest extends TestBase {

  private final boolean enableProguardCompatibilityMode;
  private final boolean keepForAnnotations;
  private final TestParameters parameters;

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

  public PrunedOrMergedAnnotationTest(
      boolean enableProguardCompatibilityMode,
      boolean keepForAnnotations,
      TestParameters parameters) {
    this.enableProguardCompatibilityMode = enableProguardCompatibilityMode;
    this.keepForAnnotations = keepForAnnotations;
    this.parameters = parameters;
  }

  @Test
  public void testRewritingInFactory()
      throws IOException, CompilationFailedException, ExecutionException {
    // No need to add extra keep rules for retaining annotations in compat mode.
    assumeTrue(!enableProguardCompatibilityMode || !keepForAnnotations);
    testForR8Compat(parameters.getBackend(), enableProguardCompatibilityMode)
        .addInnerClasses(PrunedOrMergedAnnotationTest.class)
        .addKeepMainRule(Main.class)
        .addKeepClassAndMembersRules(Factory.class)
        .addKeepRuntimeInvisibleAnnotations()
        .addKeepRuntimeInvisibleParameterAnnotations()
        .addVerticallyMergedClassesInspector(
            inspector -> inspector.assertMergedIntoSubtype(A.class))
        .applyIf(
            keepForAnnotations,
            builder -> {
              assertFalse(enableProguardCompatibilityMode);
              builder.addKeepRules(
                  "-keep,allowshrinking,allowobfuscation class " + C.class.getTypeName());
            })
        .enableInliningAnnotations()
        .enableNeverClassInliningAnnotations()
        .enableNoHorizontalClassMergingAnnotations()
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines("Hello", "World!")
        .inspect(
            inspector -> {
              assertThat(inspector.clazz(A.class), not(isPresent()));
              DexType mergedType = inspector.clazz(B.class).getDexProgramClass().type;
              ClassSubject classC = inspector.clazz(C.class);
              assertThat(classC, isPresent());

              MethodSubject mainMethod = inspector.clazz(Main.class).mainMethod();
              if (enableProguardCompatibilityMode || keepForAnnotations) {
                DexEncodedAnnotation annotation =
                    classC.annotation(Factory.class.getTypeName()).getAnnotation();
                assertTrue(valueIsDexType(mergedType, annotation.elements[0].value));
                assertTrue(
                    Arrays.stream(annotation.elements[1].value.asDexValueArray().getValues())
                        .allMatch(value -> valueIsDexType(mergedType, value)));
              } else {
                assertTrue(classC.getDexProgramClass().annotations().isEmpty());
              }

              // Check that method parameter annotations are rewritten.
              DexAnnotationSet annotationSet = mainMethod.getMethod().getParameterAnnotation(0);
              DexEncodedAnnotation parameterAnnotation = annotationSet.annotations[0].annotation;
              assertTrue(valueIsDexType(mergedType, parameterAnnotation.elements[0].value));
            });
  }

  private boolean valueIsDexType(DexType type, DexValue value) {
    assertTrue(value.isDexValueType());
    assertEquals(type, value.asDexValueType().value);
    return true;
  }

  @Retention(RetentionPolicy.CLASS)
  public @interface Factory {

    Class<?> extending() default Object.class;

    Class<?>[] other() default Object[].class;
  }

  public static class A {}

  @NeverClassInline
  @NoHorizontalClassMerging
  public static class B extends A {
    @NeverInline
    public void world() {
      System.out.println("World!");
    }
  }

  @Factory(
      extending = A.class,
      other = {A.class, B.class})
  @NoHorizontalClassMerging
  public static class C {
    @NeverInline
    public static void hello() {
      System.out.println("Hello");
    }
  }

  public static class Main {

    public static void main(@Factory(extending = A.class) String[] args) {
      C.hello();
      new B().world();
    }
  }
}
