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

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

import com.android.tools.r8.R8CompatTestBuilder;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.HorizontallyMergedClassesInspector;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

/* This is a reproduction of b/196406764 where a collision will appear when repackaging */
@RunWith(Parameterized.class)
public class RepackageMissingTypeCollisionTest extends RepackageTestBase {

  public RepackageMissingTypeCollisionTest(
      String flattenPackageHierarchyOrRepackageClasses, TestParameters parameters) {
    super(flattenPackageHierarchyOrRepackageClasses, parameters);
  }

  @Test
  public void testJvm() throws Exception {
    assumeTrue(parameters.isCfRuntime());
    String newMissingTypeName =
        getRepackagePackage() + (isFlattenPackageHierarchy() ? ".a.a" : ".a");
    String newMissingDescriptor = DescriptorUtils.javaTypeToDescriptor(newMissingTypeName);
    String newATypeName = A.class.getPackage().getName() + ".a";
    String newADescriptor = DescriptorUtils.javaTypeToDescriptor(newATypeName);
    testForJvm()
        .addProgramClassFileData(
            transformer(A.class).setClassDescriptor(newADescriptor).transform(),
            transformer(Anno.class)
                .replaceClassDescriptorInMembers(descriptor(Missing.class), newMissingDescriptor)
                .replaceClassDescriptorInAnnotationDefault(
                    descriptor(Missing.class), newMissingDescriptor)
                .transform(),
            transformer(Main.class)
                .replaceClassDescriptorInMethodInstructions(descriptor(A.class), newADescriptor)
                .replaceClassDescriptorInMethodInstructions(
                    descriptor(Missing.class), newMissingDescriptor)
                .transform())
        .run(parameters.getRuntime(), Main.class)
        .assertFailureWithErrorThatThrows(NoClassDefFoundError.class);
  }

  @Test
  public void testRepackageMissingCollision() throws Exception {
    testMissingReference(true)
        .compile()
        .inspect(
            inspector -> {
              ClassSubject clazz = inspector.clazz(getNewATypeName());
              assertThat(clazz, isPresentAndRenamed());
              assertEquals(
                  getRepackagePackage() + (isFlattenPackageHierarchy() ? ".a.b" : ".b"),
                  clazz.getFinalName());
            })
        .run(parameters.getRuntime(), Main.class)
        .assertFailureWithErrorThatThrows(NoClassDefFoundError.class);
  }

  @Test
  public void testNoRepackage() throws Exception {
    testMissingReference(false)
        .run(parameters.getRuntime(), Main.class)
        .assertFailureWithErrorThatThrows(NoClassDefFoundError.class);
  }

  private String getNewMissingTypeName() {
    return getRepackagePackage() + (isFlattenPackageHierarchy() ? ".a.a" : ".a");
  }

  private String getNewATypeName() {
    return A.class.getPackage().getName() + ".a";
  }

  private R8CompatTestBuilder testMissingReference(boolean repackage) throws Exception {
    // The references to Missing will be rewritten to <repackage>.a but the definition will not be
    // present.
    String newMissingDescriptor = DescriptorUtils.javaTypeToDescriptor(getNewMissingTypeName());
    String newADescriptor = DescriptorUtils.javaTypeToDescriptor(getNewATypeName());
    return testForR8Compat(parameters.getBackend())
        .addProgramClassFileData(
            transformer(A.class).setClassDescriptor(newADescriptor).transform(),
            transformer(Anno.class)
                .replaceClassDescriptorInMembers(descriptor(Missing.class), newMissingDescriptor)
                .replaceClassDescriptorInAnnotationDefault(
                    descriptor(Missing.class), newMissingDescriptor)
                .transform(),
            transformer(Main.class)
                .replaceClassDescriptorInMethodInstructions(descriptor(A.class), newADescriptor)
                .replaceClassDescriptorInMethodInstructions(
                    descriptor(Missing.class), newMissingDescriptor)
                .transform())
        .addKeepMainRule(Main.class)
        .addKeepClassAndMembersRules(Anno.class)
        .addKeepRuntimeVisibleAnnotations()
        .applyIf(repackage, this::configureRepackaging)
        .setMinApi(parameters.getApiLevel())
        .addDontWarn(getNewMissingTypeName())
        .addOptionsModification(internalOptions -> internalOptions.enableEnumUnboxing = false)
        .addHorizontallyMergedClassesInspector(
            HorizontallyMergedClassesInspector::assertNoClassesMerged);
  }

  /* Will be missing on input */
  public enum Missing {
    foo;
  }

  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.TYPE)
  public @interface Anno {

    /* Renamed to <repackage>.a */ Missing missing() default Missing.foo;
  }

  @Anno
  public enum /* renamed to a */ A {
    foo;
  }

  public static class Main {

    public static void main(String[] args) {
      Anno annotation = A.class.getAnnotation(Anno.class);
      System.out.println(annotation.missing());
    }
  }
}
