// 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.annotations;

import static org.junit.Assert.assertEquals;
import static org.junit.Assume.assumeTrue;
import static org.objectweb.asm.Opcodes.ASM7;

import com.android.tools.r8.ClassFileResourceProvider;
import com.android.tools.r8.ProgramResource;
import com.android.tools.r8.ProgramResource.Kind;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.transformers.MethodTransformer;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableSet;
import java.io.IOException;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.objectweb.asm.AnnotationVisitor;

@RunWith(Parameterized.class)
public class DalvikAnnotationOptimizationTest extends TestBase {

  @Parameter(0)
  public TestParameters parameters;

  @Parameter(1)
  public boolean optimizationPackage;

  @Parameter(2)
  public boolean addAnnotationsOnLibraryPath;

  @Parameters(name = "{0}, optimizationPackage = {1}, addAnnotationsOnLibraryPath = {2}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimes().withAllApiLevels().build(),
        BooleanUtils.values(),
        BooleanUtils.values());
  }

  private static final String dalvikOptimizationPrefix =
      DexItemFactory.dalvikAnnotationOptimizationPrefixString;
  private static final String dalvikCodegenPrefix = "Ldalvik/annotation/codegen/";
  private static final String ourClassName =
      DescriptorUtils.javaTypeToDescriptor(DalvikAnnotationOptimizationTest.class.getTypeName());
  private static final String innerClassPrefix =
      ourClassName.substring(0, ourClassName.length() - 1) + "$";

  private static String changePackage(boolean optimizationPackage, String descriptor) {
    return (optimizationPackage ? dalvikOptimizationPrefix : dalvikCodegenPrefix)
        + descriptor.substring(innerClassPrefix.length());
  }

  private void checkExpectedAnnotations(CodeInspector inspector) {
    Set<String> expected =
        optimizationPackage
            ? ImmutableSet.of(
                dalvikOptimizationPrefix + "CriticalNative;",
                dalvikOptimizationPrefix + "FastNative;",
                dalvikOptimizationPrefix + "NeverCompile;",
                dalvikOptimizationPrefix + "AndAnotherOne;")
            : ImmutableSet.of();
    assertEquals(
        expected,
        inspector.clazz(TestClass.class).uniqueMethodWithName("main").annotations().stream()
            .map(s -> s.getAnnotation().type.getDescriptor().toSourceString())
            .collect(Collectors.toSet()));
  }

  @Test
  public void testD8() throws Exception {
    assumeTrue(parameters.isDexRuntime());
    testForD8(parameters.getBackend())
        .addProgramClassFileData(
            transformer(TestClass.class).addMethodTransformer(getMethodTransformer()).transform())
        .setMinApi(parameters.getApiLevel())
        .applyIf(
            addAnnotationsOnLibraryPath,
            b -> {
              b.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST));
              b.addLibraryProvider(new ClassPathProviderForAnnotations(optimizationPackage));
            })
        .compile()
        .inspect(this::checkExpectedAnnotations);
  }

  private MethodTransformer getMethodTransformer() {
    return new MethodTransformer() {
      @Override
      public AnnotationVisitor visitAnnotation(final String descriptor, final boolean visible) {
        assert descriptor.startsWith(innerClassPrefix);
        return new AnnotationVisitor(
            ASM7,
            super.visitAnnotation(changePackage(optimizationPackage, descriptor), visible)) {};
      }
    };
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClassFileData(
            transformer(TestClass.class).addMethodTransformer(getMethodTransformer()).transform())
        .applyIf(
            addAnnotationsOnLibraryPath,
            b -> {
              b.addLibraryFiles(ToolHelper.getAndroidJar(AndroidApiLevel.LATEST));
              b.addLibraryProvider(new ClassPathProviderForAnnotations(optimizationPackage));
            },
            b ->
                b.addDontWarn(
                    optimizationPackage
                        ? "dalvik.annotation.optimization.*"
                        : "dalvik.annotation.codegen.*"))
        .setMinApi(parameters.getApiLevel())
        .addKeepMainRule(TestClass.class)
        .compile()
        .inspect(this::checkExpectedAnnotations);
  }

  static class ClassPathProviderForAnnotations implements ClassFileResourceProvider {
    private final boolean optimizationPackage;
    private final Map<String, byte[]> resources = new HashMap<>();

    ClassPathProviderForAnnotations(boolean optimizationPackage) throws IOException {
      this.optimizationPackage = optimizationPackage;
      for (Class<?> clazz :
          new Class<?>[] {
            CriticalNative.class, FastNative.class, NeverCompile.class, AndAnotherOne.class
          }) {
        resources.put(
            changePackage(
                optimizationPackage, DescriptorUtils.javaTypeToDescriptor(clazz.getTypeName())),
            transformPackageName(clazz));
      }
    }

    @Override
    public Set<String> getClassDescriptors() {
      return resources.keySet();
    }

    @Override
    public ProgramResource getProgramResource(String descriptor) {
      byte[] bytes = resources.get(descriptor);
      return bytes == null
          ? null
          : ProgramResource.fromBytes(
              Origin.unknown(), Kind.CF, bytes, Collections.singleton(descriptor));
    }

    private byte[] transformPackageName(Class<?> clazz) throws IOException {
      return transformer(clazz)
          .setClassDescriptor(
              changePackage(
                  optimizationPackage, DescriptorUtils.javaTypeToDescriptor(clazz.getTypeName())))
          .transform();
    }
  }

  // Keep all CLASS retention annotations in the dalvik.annotation.optimization package.
  // See b/209701182
  @Retention(RetentionPolicy.CLASS)
  @interface CriticalNative {}

  @Retention(RetentionPolicy.CLASS)
  @interface FastNative {}

  @Retention(RetentionPolicy.CLASS)
  @interface NeverCompile {}

  @Retention(RetentionPolicy.CLASS)
  @interface AndAnotherOne {}

  static class TestClass {
    @CriticalNative
    @FastNative
    @NeverCompile
    @AndAnotherOne
    public static void main(String[] args) {}
  }
}
