// 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 com.android.tools.r8.utils.codeinspector.Matchers.isRenamed;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.KotlinTestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper.KotlinTargetVersion;
import com.android.tools.r8.graph.DexAnnotationElement;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.AnnotationSubject;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ReflectiveAnnotationUseTest extends KotlinTestBase {
  private static final String FOLDER = "internal_annotation";
  private static final String MAIN_CLASS_NAME = "internal_annotation.MainKt";
  private static final String ANNOTATION_NAME = "internal_annotation.Annotation";
  private static final String IMPL_CLASS_NAME = "internal_annotation.Impl";
  private static final String KEEP_ANNOTATIONS = "-keepattributes *Annotation*";

  private static final String JAVA_OUTPUT = StringUtils.lines(
      "Impl::toString",
      "Impl::Annotation::field2.Impl::Annotation::field2(Impl::Annotation::field2:2)"
  );

  private static final String OUTPUT_WITHOUT_ANNOTATION = StringUtils.lines(
      "Impl::toString",
      "null"
  );

  private static final Map<String, String> EXPECTED_ANNOTATION_VALUES = ImmutableMap.of(
      "f1", "2",
      "f2", "Impl::Annotation::field2",
      "f3", "3]",
      "f4", "field4]"
  );

  private final TestParameters parameters;
  private final boolean minify;

  @Parameterized.Parameters(name = "{0} target: {1} minify: {2}")
  public static Collection<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimes().build(),
        KotlinTargetVersion.values(),
        BooleanUtils.values());
  }

  public ReflectiveAnnotationUseTest(
      TestParameters parameters, KotlinTargetVersion targetVersion, boolean minify) {
    super(targetVersion);
    this.parameters = parameters;
    this.minify = minify;
  }

  @Test
  public void b120951621_JVMOutput() throws Exception {
    assumeTrue("Only run JVM reference on CF runtimes", parameters.isCfRuntime());
    AndroidApp app = AndroidApp.builder()
        .addProgramFile(getKotlinJarFile(FOLDER))
        .addProgramFile(getJavaJarFile(FOLDER))
        .build();
    String result = runOnJava(app, MAIN_CLASS_NAME);
    assertEquals(JAVA_OUTPUT, result);
  }

  @Test
  public void b120951621_keepAll() throws Exception {
    CodeInspector inspector = testForR8(parameters.getBackend())
        .addProgramFiles(getKotlinJarFile(FOLDER))
        .addProgramFiles(getJavaJarFile(FOLDER))
        .addKeepMainRule(MAIN_CLASS_NAME)
        .addKeepRules(KEEP_ANNOTATIONS)
        .addKeepRules(
            "-keep @interface " + ANNOTATION_NAME + " {",
            "  *;",
            "}"
        )
        .minification(minify)
        .setMinApi(parameters.getRuntime())
        .run(parameters.getRuntime(), MAIN_CLASS_NAME)
        .assertSuccessWithOutput(JAVA_OUTPUT).inspector();
    ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
    assertThat(clazz, isPresent());
    assertThat(clazz, not(isRenamed()));
    MethodSubject f1 = clazz.uniqueMethodWithName("f1");
    assertThat(f1, isPresent());
    assertThat(f1, not(isRenamed()));
    MethodSubject f2 = clazz.uniqueMethodWithName("f2");
    assertThat(f2, isPresent());
    assertThat(f2, not(isRenamed()));
    MethodSubject f3 = clazz.uniqueMethodWithName("f3");
    assertThat(f3, isPresent());
    assertThat(f3, not(isRenamed()));
    MethodSubject f4 = clazz.uniqueMethodWithName("f4");
    assertThat(f4, isPresent());
    assertThat(f4, not(isRenamed()));

    ClassSubject impl = inspector.clazz(IMPL_CLASS_NAME);
    assertThat(impl, isPresent());
    AnnotationSubject anno = impl.annotation(ANNOTATION_NAME);
    assertThat(anno, isPresent());
    inspectAnnotationInstantiation(anno, ImmutableSet.of("f1", "f2", "f3", "f4"));
  }

  @Test
  public void b120951621_partiallyKeep() throws Exception {
    CodeInspector inspector = testForR8(parameters.getBackend())
        .addProgramFiles(getKotlinJarFile(FOLDER))
        .addProgramFiles(getJavaJarFile(FOLDER))
        .addKeepMainRule(MAIN_CLASS_NAME)
        .addKeepRules(KEEP_ANNOTATIONS)
        .addKeepRules(
            "-keep,allowobfuscation @interface " + ANNOTATION_NAME + " {",
            "  java.lang.String *f2();",
            "}"
        )
        .minification(minify)
        .setMinApi(parameters.getRuntime())
        .run(parameters.getRuntime(), MAIN_CLASS_NAME)
        .assertSuccessWithOutput(JAVA_OUTPUT).inspector();
    ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
    assertThat(clazz, isPresent());
    assertEquals(minify, clazz.isRenamed());
    MethodSubject f1 = clazz.uniqueMethodWithName("f1");
    assertThat(f1, isPresent());
    assertThat(f1, not(isRenamed()));
    MethodSubject f2 = clazz.uniqueMethodWithName("f2");
    assertThat(f2, isPresent());
    assertThat(f2, not(isRenamed()));
    MethodSubject f3 = clazz.uniqueMethodWithName("f3");
    assertThat(f3, not(isPresent()));
    MethodSubject f4 = clazz.uniqueMethodWithName("f4");
    assertThat(f4, not(isPresent()));

    ClassSubject impl = inspector.clazz(IMPL_CLASS_NAME);
    assertThat(impl, isPresent());
    AnnotationSubject anno = impl.annotation(ANNOTATION_NAME);
    assertThat(anno, isPresent());
    inspectAnnotationInstantiation(anno, ImmutableSet.of("f1", "f2"));
  }

  @Test
  public void b120951621_keepAnnotation() throws Exception {
    CodeInspector inspector = testForR8(parameters.getBackend())
        .addProgramFiles(getKotlinJarFile(FOLDER))
        .addProgramFiles(getJavaJarFile(FOLDER))
        .addKeepMainRule(MAIN_CLASS_NAME)
        .addKeepRules(KEEP_ANNOTATIONS)
        .minification(minify)
        .setMinApi(parameters.getRuntime())
        .run(parameters.getRuntime(), MAIN_CLASS_NAME)
        .assertSuccessWithOutput(JAVA_OUTPUT).inspector();
    ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
    assertThat(clazz, isPresent());
    assertEquals(minify, clazz.isRenamed());
    MethodSubject f1 = clazz.uniqueMethodWithName("f1");
    assertThat(f1, isPresent());
    assertThat(f1, not(isRenamed()));
    MethodSubject f2 = clazz.uniqueMethodWithName("f2");
    assertThat(f2, isPresent());
    assertThat(f2, not(isRenamed()));
    MethodSubject f3 = clazz.uniqueMethodWithName("f3");
    assertThat(f3, not(isPresent()));
    MethodSubject f4 = clazz.uniqueMethodWithName("f4");
    assertThat(f4, not(isPresent()));

    ClassSubject impl = inspector.clazz(IMPL_CLASS_NAME);
    assertThat(impl, isPresent());
    AnnotationSubject anno = impl.annotation(ANNOTATION_NAME);
    assertThat(anno, isPresent());
    inspectAnnotationInstantiation(anno, ImmutableSet.of("f1", "f2"));
  }

  @Test
  public void b120951621_noKeep() throws Exception {
    CodeInspector inspector = testForR8(parameters.getBackend())
        .addProgramFiles(getKotlinJarFile(FOLDER))
        .addProgramFiles(getJavaJarFile(FOLDER))
        .addKeepMainRule(MAIN_CLASS_NAME)
        .minification(minify)
        .setMinApi(parameters.getRuntime())
        .run(parameters.getRuntime(), MAIN_CLASS_NAME)
        .assertSuccessWithOutput(OUTPUT_WITHOUT_ANNOTATION).inspector();
    ClassSubject clazz = inspector.clazz(ANNOTATION_NAME);
    assertThat(clazz, isPresent());
    assertEquals(minify, clazz.isRenamed());
    MethodSubject f1 = clazz.uniqueMethodWithName("f1");
    assertThat(f1, isPresent());
    MethodSubject f2 = clazz.uniqueMethodWithName("f2");
    assertThat(f2, isPresent());
    MethodSubject f3 = clazz.uniqueMethodWithName("f3");
    assertThat(f3, not(isPresent()));
    MethodSubject f4 = clazz.uniqueMethodWithName("f4");
    assertThat(f4, not(isPresent()));

    ClassSubject impl = inspector.clazz(IMPL_CLASS_NAME);
    assertThat(impl, isPresent());
    AnnotationSubject anno = impl.annotation(ANNOTATION_NAME);
    assertThat(anno, not(isPresent()));
  }

  private void inspectAnnotationInstantiation(
      AnnotationSubject annotationSubject, Set<String> expectedFields) {
    int count = 0;
    for (DexAnnotationElement element : annotationSubject.getAnnotation().elements) {
      String fieldName = element.name.toString();
      if (expectedFields.contains(fieldName)) {
        count++;
        String expectedValue = EXPECTED_ANNOTATION_VALUES.get(fieldName);
        assertThat(element.value.toString(), containsString(expectedValue));
      }
    }
    assertEquals(expectedFields.size(), count);
  }

}
