// Copyright (c) 2017, 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.naming;

import static com.android.tools.r8.naming.ClassNameMinifier.getParentPackagePrefix;
import static com.android.tools.r8.utils.DescriptorUtils.getPackageNameFromDescriptor;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.ListUtils;
import com.google.common.base.CharMatcher;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Sets;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
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 PackageNamingTest extends NamingTestBase {

  public PackageNamingTest(
      String test,
      List<String> keepRulesFiles,
      BiConsumer<DexItemFactory, NamingLens> inspection) {
    super(test, keepRulesFiles, inspection);
  }

  @Test
  public void packageNamingTest() throws Exception {
    NamingLens naming = runMinifier(ListUtils.map(keepRulesFiles, Paths::get));
    inspection.accept(naming);
  }

  private static final List<String> CLASSES_IN_NAMING044 = ImmutableList.of(
      "Lnaming044/A;", "Lnaming044/B;", "Lnaming044/sub/SubA;", "Lnaming044/sub/SubB;");

  private static final List<String> CLASSES_IN_NAMING101 = ImmutableList.of(
      "Lnaming101/c;", "Lnaming101/d;",
      "Lnaming101/a/a;", "Lnaming101/a/c;",
      "Lnaming101/a/b/c",
      "Lnaming101/b/a'", "Lnaming101/b/b;"
  );

  @Parameters(name = "test: {0} keep: {1}")
  public static Collection<Object[]> data() {
    List<String> tests = Arrays.asList("naming044", "naming101");

    Map<String, BiConsumer<DexItemFactory, NamingLens>> inspections = new HashMap<>();
    inspections.put("naming044:keep-rules-001.txt", PackageNamingTest::test044_rule001);
    inspections.put("naming044:keep-rules-002.txt", PackageNamingTest::test044_rule002);
    inspections.put("naming044:keep-rules-003.txt", PackageNamingTest::test044_rule003);
    inspections.put("naming044:keep-rules-004.txt", PackageNamingTest::test044_rule004);
    inspections.put("naming044:keep-rules-005.txt", PackageNamingTest::test044_rule005);
    inspections.put("naming101:keep-rules-001.txt", PackageNamingTest::test101_rule001);
    inspections.put("naming101:keep-rules-002.txt", PackageNamingTest::test101_rule002);
    inspections.put("naming101:keep-rules-003.txt", PackageNamingTest::test101_rule003);
    inspections.put("naming101:keep-rules-004.txt", PackageNamingTest::test101_rule004);
    inspections.put("naming101:keep-rules-005.txt", PackageNamingTest::test101_rule005);
    inspections.put("naming101:keep-rules-102.txt", PackageNamingTest::test101_rule102);
    inspections.put("naming101:keep-rules-104.txt", PackageNamingTest::test101_rule104);
    inspections.put("naming101:keep-rules-106.txt", PackageNamingTest::test101_rule106);

    return createTests(tests, inspections);
  }

  private static int countPackageDepth(String descriptor) {
    return CharMatcher.is('/').countIn(descriptor);
  }

  private static void verifyUniqueNaming(
      DexItemFactory dexItemFactory,
      NamingLens naming,
      List<String> klasses) {
    Set<String> renamedNames = Sets.newHashSet();
    for (String klass : klasses) {
      DexType k = dexItemFactory.createType(klass);
      String rename = naming.lookupDescriptor(k).toSourceString();
      assertFalse(renamedNames.contains(rename));
      renamedNames.add(rename);
    }
  }

  // repackageclasses ''
  private static void test044_rule001(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING044);

    // All classes are moved to the top-level package, hence no package separator.
    DexType b = dexItemFactory.createType("Lnaming044/B;");
    assertFalse(naming.lookupDescriptor(b).toSourceString().contains("/"));

    // Even classes in a sub-package are moved to the same top-level package.
    DexType sub = dexItemFactory.createType("Lnaming044/sub/SubB;");
    assertFalse(naming.lookupDescriptor(sub).toSourceString().contains("/"));

    // method naming044.B.m would be renamed.
    DexMethod m = dexItemFactory.createMethod(
        b, dexItemFactory.createProto(dexItemFactory.intType), "m");
    assertNotEquals("m", naming.lookupName(m).toSourceString());
  }

  // repackageclasses 'p44.x'
  private static void test044_rule002(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING044);

    // All classes are moved to a single package, so they all have the same package prefix.
    DexType a = dexItemFactory.createType("Lnaming044/A;");
    assertTrue(naming.lookupDescriptor(a).toSourceString().startsWith("Lp44/x/"));

    DexType b = dexItemFactory.createType("Lnaming044/B;");
    assertTrue(naming.lookupDescriptor(b).toSourceString().startsWith("Lp44/x/"));

    DexType sub = dexItemFactory.createType("Lnaming044/sub/SubB;");
    assertTrue(naming.lookupDescriptor(sub).toSourceString().startsWith("Lp44/x/"));
    // Even classes in a sub-package are moved to the same package.
    assertEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(sub).toSourceString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(b).toSourceString()));
  }

  // flattenpackagehierarchy ''
  private static void test044_rule003(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING044);

    // All packages are moved to the top-level package, hence only one package separator.
    DexType b = dexItemFactory.createType("Lnaming044/B;");
    assertEquals(1, countPackageDepth(naming.lookupDescriptor(b).toSourceString()));

    // Classes in a sub-package are moved to the top-level as well, but in a different one.
    DexType sub = dexItemFactory.createType("Lnaming044/sub/SubB;");
    assertEquals(1, countPackageDepth(naming.lookupDescriptor(sub).toSourceString()));
    assertNotEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(sub).toSourceString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(b).toSourceString()));

    // method naming044.B.m would be renamed.
    DexMethod m = dexItemFactory.createMethod(
        b, dexItemFactory.createProto(dexItemFactory.intType), "m");
    assertNotEquals("m", naming.lookupName(m).toSourceString());
  }

  // flattenpackagehierarchy 'p44.y'
  private static void test044_rule004(DexItemFactory dexItemFactory, NamingLens naming) {
    // All packages are moved to a single package.
    DexType a = dexItemFactory.createType("Lnaming044/A;");
    assertTrue(naming.lookupDescriptor(a).toSourceString().startsWith("Lp44/y/"));
    // naming004.A -> Lp44/y/a/a;
    assertEquals(3, countPackageDepth(naming.lookupDescriptor(a).toSourceString()));

    DexType b = dexItemFactory.createType("Lnaming044/B;");
    assertTrue(naming.lookupDescriptor(b).toSourceString().startsWith("Lp44/y/"));
    // naming004.B -> Lp44/y/a/b;
    assertEquals(3, countPackageDepth(naming.lookupDescriptor(b).toSourceString()));

    DexType sub = dexItemFactory.createType("Lnaming044/sub/SubB;");
    assertTrue(naming.lookupDescriptor(sub).toSourceString().startsWith("Lp44/y/"));
    // naming004.sub.SubB -> Lp44/y/b/b;
    assertEquals(3, countPackageDepth(naming.lookupDescriptor(sub).toSourceString()));

    // Classes in a sub-package should be in a different package.
    assertNotEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(sub).toSourceString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(b).toSourceString()));
  }

  private static void test044_rule005(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING044);

    // All packages are renamed somehow. Need to check package hierarchy is consistent.
    DexType a = dexItemFactory.createType("Lnaming044/A;");
    assertEquals(1, countPackageDepth(naming.lookupDescriptor(a).toSourceString()));
    DexType b = dexItemFactory.createType("Lnaming044/B;");
    assertEquals(1, countPackageDepth(naming.lookupDescriptor(b).toSourceString()));
    assertEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(a).toSourceString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(b).toSourceString()));

    DexType sub_a = dexItemFactory.createType("Lnaming044/sub/SubA;");
    assertEquals(2, countPackageDepth(naming.lookupDescriptor(sub_a).toSourceString()));
    DexType sub_b = dexItemFactory.createType("Lnaming044/sub/SubB;");
    assertEquals(2, countPackageDepth(naming.lookupDescriptor(sub_b).toSourceString()));
    assertEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(sub_a).toSourceString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(sub_b).toSourceString()));

    // Lnaming044/B -> La/c --prefix--> La
    // Lnaming044/sub/SubB -> La/b/b --prefix--> La/b --prefix--> La
    assertEquals(
        getParentPackagePrefix(naming.lookupDescriptor(b).toSourceString()),
        getParentPackagePrefix(
            getParentPackagePrefix(naming.lookupDescriptor(sub_b).toSourceString())));
  }

  private static void test101_rule001(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING101);

    // All classes are moved to the top-level package, hence no package separator.
    DexType c = dexItemFactory.createType("Lnaming101/c;");
    assertFalse(naming.lookupDescriptor(c).toSourceString().contains("/"));

    DexType abc = dexItemFactory.createType("Lnaming101/a/b/c;");
    assertFalse(naming.lookupDescriptor(abc).toSourceString().contains("/"));
    assertNotEquals(
        naming.lookupDescriptor(abc).toSourceString(),
        naming.lookupDescriptor(c).toSourceString());
  }

  private static void test101_rule002(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING101);

    // Check naming101.*.a is kept due to **.a
    DexType aa = dexItemFactory.createType("Lnaming101/a/a;");
    assertEquals("Lnaming101/a/a;", naming.lookupDescriptor(aa).toSourceString());
    DexType ba = dexItemFactory.createType("Lnaming101/b/a;");
    assertEquals("Lnaming101/b/a;", naming.lookupDescriptor(ba).toSourceString());

    // Repackaged to naming101.a, but naming101.a.a exists to make a name conflict.
    // Thus, everything else should not be renamed to 'a',
    // except for naming101.b.a, which is also kept due to **.a
    List<String> klasses = ImmutableList.of(
        "Lnaming101/c;",
        "Lnaming101/d;",
        "Lnaming101/a/c;",
        "Lnaming101/a/b/c;",
        "Lnaming101/b/b;");
    for (String klass : klasses) {
      DexType k = dexItemFactory.createType(klass);
      String renamedName = naming.lookupDescriptor(k).toSourceString();
      assertEquals("naming101.a", getPackageNameFromDescriptor(renamedName));
      assertNotEquals("Lnaming101/a/a;", renamedName);
    }
  }

  private static void test101_rule003(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING101);

    // All packages are moved to the top-level package, hence only one package separator.
    DexType aa = dexItemFactory.createType("Lnaming101/a/a;");
    assertEquals(1, countPackageDepth(naming.lookupDescriptor(aa).toSourceString()));

    DexType ba = dexItemFactory.createType("Lnaming101/b/a;");
    assertEquals(1, countPackageDepth(naming.lookupDescriptor(ba).toSourceString()));

    assertNotEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(aa).toSourceString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(ba).toSourceString()));
  }

  private static void test101_rule004(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING101);

    // Check naming101.*.a is kept due to **.a
    DexType aa = dexItemFactory.createType("Lnaming101/a/a;");
    assertEquals("Lnaming101/a/a;", naming.lookupDescriptor(aa).toSourceString());
    DexType ba = dexItemFactory.createType("Lnaming101/b/a;");
    assertEquals("Lnaming101/b/a;", naming.lookupDescriptor(ba).toSourceString());

    // Flattened to naming101, hence all other classes will be in naming101.* package.
    // Due to naming101.a.a, prefix naming101.a is already used. So, any other classes,
    // except for naming101.a.c, should not have naming101.a as package.
    List<String> klasses = ImmutableList.of(
        "Lnaming101/c;",
        "Lnaming101/d;",
        "Lnaming101/a/b/c;",
        "Lnaming101/b/a;",
        "Lnaming101/b/b;");
    for (String klass : klasses) {
      DexType k = dexItemFactory.createType(klass);
      String renamedName = naming.lookupDescriptor(k).toSourceString();
      assertNotEquals("naming101.a", getPackageNameFromDescriptor(renamedName));
    }
  }

  private static void test101_rule005(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING101);

    // All packages are renamed somehow. Need to check package hierarchy is consistent.
    DexType aa = dexItemFactory.createType("Lnaming101/a/a;");
    assertEquals(2, countPackageDepth(naming.lookupDescriptor(aa).toSourceString()));
    DexType abc = dexItemFactory.createType("Lnaming101/a/b/c;");
    assertEquals(3, countPackageDepth(naming.lookupDescriptor(abc).toSourceString()));

    // Lnaming101/a/a; -> La/a/a; --prefix--> La/a
    // Lnaming101/a/b/c; -> La/a/a/a; --prefix--> La/a/a --prefix--> La/a
    assertEquals(
        getParentPackagePrefix(naming.lookupDescriptor(aa).toSourceString()),
        getParentPackagePrefix(
            getParentPackagePrefix(naming.lookupDescriptor(abc).toSourceString())));
  }

  private static void test101_rule102(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING101);

    // Check naming101.*.a is kept due to **.a
    DexType aa = dexItemFactory.createType("Lnaming101/a/a;");
    assertEquals("Lnaming101/a/a;", naming.lookupDescriptor(aa).toSourceString());
    DexType ba = dexItemFactory.createType("Lnaming101/b/a;");
    assertEquals("Lnaming101/b/a;", naming.lookupDescriptor(ba).toSourceString());
    // Due to package-private access, classes in the same package should remain in the same package.
    DexType ac = dexItemFactory.createType("Lnaming101/a/c;");
    assertEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(aa).toString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(ac).toString()));
    DexType bb = dexItemFactory.createType("Lnaming101/b/b;");
    assertEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(ba).toString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(bb).toString()));

    // All other classes can be repackaged to naming101.a, but naming101.a.a exists to make a name
    // conflict. Thus, those should not be renamed to 'a'.
    List<String> klasses = ImmutableList.of(
        "Lnaming101/c;",
        "Lnaming101/d;",
        "Lnaming101/a/b/c;");
    for (String klass : klasses) {
      DexType k = dexItemFactory.createType(klass);
      String renamedName = naming.lookupDescriptor(k).toSourceString();
      assertEquals("naming101.a", getPackageNameFromDescriptor(renamedName));
      assertNotEquals("Lnaming101/a/a;", renamedName);
    }
  }

  private static void test101_rule104(DexItemFactory dexItemFactory, NamingLens naming) {
    verifyUniqueNaming(dexItemFactory, naming, CLASSES_IN_NAMING101);

    // Check naming101.*.a is kept due to **.a
    DexType aa = dexItemFactory.createType("Lnaming101/a/a;");
    assertEquals("Lnaming101/a/a;", naming.lookupDescriptor(aa).toSourceString());
    DexType ba = dexItemFactory.createType("Lnaming101/b/a;");
    assertEquals("Lnaming101/b/a;", naming.lookupDescriptor(ba).toSourceString());
    // Due to package-private access, classes in the same package should remain in the same package.
    DexType ac = dexItemFactory.createType("Lnaming101/a/c;");
    assertEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(aa).toString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(ac).toString()));
    DexType bb = dexItemFactory.createType("Lnaming101/b/b;");
    assertEquals(
        getPackageNameFromDescriptor(naming.lookupDescriptor(ba).toString()),
        getPackageNameFromDescriptor(naming.lookupDescriptor(bb).toString()));

    // All other packages are flattened to naming101, hence all other classes will be in
    // naming101.* package. Due to naming101.a.a, prefix naming101.a is already used. So,
    // remaining classes should not have naming101.a as package.
    List<String> klasses = ImmutableList.of(
        "Lnaming101/c;",
        "Lnaming101/d;",
        "Lnaming101/a/b/c;");
    for (String klass : klasses) {
      DexType k = dexItemFactory.createType(klass);
      String renamedName = naming.lookupDescriptor(k).toSourceString();
      assertNotEquals("naming101.a", getPackageNameFromDescriptor(renamedName));
    }
  }

  private static void test101_rule106(DexItemFactory dexItemFactory, NamingLens naming) {
    // Classes that end with either c or d will be kept and renamed.
    List<String> klasses =
        CLASSES_IN_NAMING101.stream()
            .filter(className -> className.endsWith("c;") || className.endsWith("d;"))
            .collect(Collectors.toList());
    verifyUniqueNaming(dexItemFactory, naming, klasses);

    // Check naming101.c is kept as-is.
    DexType topC = dexItemFactory.createType("Lnaming101/c;");
    assertEquals("Lnaming101/c;", naming.lookupDescriptor(topC).toSourceString());

    // naming101.d accesses to a package-private, static field in naming101.c.
    // Therefore, it should remain in the same package.
    DexType topD = dexItemFactory.createType("Lnaming101/d;");
    String renamedTopD = naming.lookupDescriptor(topD).toSourceString();
    assertEquals("naming101", getPackageNameFromDescriptor(renamedTopD));

    // Due to the keep rule for naming101.c, package prefix naming101 is reserved.
    // That is, every renamed class should have naming101 as parent package prefix.
    for (String klass : klasses) {
      DexType t = dexItemFactory.createType(klass);
      String rename = naming.lookupDescriptor(t).toSourceString();
      assertTrue(rename.startsWith("Lnaming101/"));
    }
  }
}
