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

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.DataDirectoryResource;
import com.android.tools.r8.DataEntryResource;
import com.android.tools.r8.DataResourceConsumer;
import com.android.tools.r8.DataResourceProvider.Visitor;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.StringConsumer;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.forceproguardcompatibility.ProguardCompatibilityTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.ArchiveResourceProvider;
import com.android.tools.r8.utils.DataResourceConsumerForTesting;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.KeepingDiagnosticHandler;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class AdaptResourceFileNamesTest extends ProguardCompatibilityTestBase {

  private Backend backend;

  @Parameterized.Parameters(name = "Backend: {0}")
  public static Backend[] data() {
    return ToolHelper.getBackends();
  }

  public AdaptResourceFileNamesTest(Backend backend) {
    this.backend = backend;
  }

  private static final Path CF_DIR =
      Paths.get(ToolHelper.EXAMPLES_CF_DIR).resolve("adaptresourcefilenames");
  private static final Path TEST_JAR =
      Paths.get(ToolHelper.EXAMPLES_BUILD_DIR)
          .resolve("adaptresourcefilenames" + FileUtils.JAR_EXTENSION);

  private KeepingDiagnosticHandler diagnosticsHandler;
  private ClassNameMapper mapper = null;

  @Before
  public void reset() {
    diagnosticsHandler = new KeepingDiagnosticHandler();
    mapper = null;
  }

  private static String getProguardConfig(
      boolean enableAdaptResourceFileNames, String adaptResourceFileNamesPathFilter) {
    String adaptResourceFilenamesRule;
    if (enableAdaptResourceFileNames) {
      adaptResourceFilenamesRule = "-adaptresourcefilenames";
      if (adaptResourceFileNamesPathFilter != null) {
        adaptResourceFilenamesRule += " " + adaptResourceFileNamesPathFilter;
      }
    } else {
      adaptResourceFilenamesRule = "";
    }
    return String.join(
        System.lineSeparator(),
        adaptResourceFilenamesRule,
        "-keep class adaptresourcefilenames.TestClass {",
        "  public static void main(...);",
        "}");
  }

  private static String getProguardConfigWithNeverInline(
      boolean enableAdaptResourceFileNames, String adaptResourceFileNamesPathFilter) {
    return StringUtils.lines(
        getProguardConfig(enableAdaptResourceFileNames, adaptResourceFileNamesPathFilter),
        "-neverinline class adaptresourcefilenames.A {",
        "  public void method();",
        "}",
        "-neverinline class adaptresourcefilenames.B$Inner {",
        "  public void method();",
        "}",
        "-assumemayhavesideeffects class adaptresourcefilenames.pkg.C {",
        "  void <init>();",
        "}",
        "-assumemayhavesideeffects class adaptresourcefilenames.pkg.innerpkg.D {",
        "  void <init>();",
        "}",
        "-neverclassinline class *");
  }

  @Test
  public void testEnabled() throws Exception {
    expectThrowsWithHorizontalClassMerging();
    DataResourceConsumerForTesting dataResourceConsumer = new DataResourceConsumerForTesting();
    compileWithR8(
        getProguardConfigWithNeverInline(true, null),
        dataResourceConsumer,
        ToolHelper.consumeString(this::checkR8Renamings));
    // Check that the generated resources have the expected names.
    for (DataEntryResource dataResource : getOriginalDataResources()) {
      assertNotNull(
          "Resource not renamed as expected: " + dataResource.getName(),
          dataResourceConsumer.get(getExpectedRenamingFor(dataResource.getName(), mapper)));
    }
  }

  @Test
  public void testEnabledWithFilter() throws Exception {
    DataResourceConsumerForTesting dataResourceConsumer = new DataResourceConsumerForTesting();
    compileWithR8(
        getProguardConfigWithNeverInline(true, "**.md"),
        dataResourceConsumer,
        ToolHelper.consumeString(this::checkR8Renamings));
    // Check that the generated resources have the expected names.
    Map<String, String> expectedRenamings =
        ImmutableMap.of("adaptresourcefilenames/B.md", "adaptresourcefilenames/b.md");
    for (DataEntryResource dataResource : getOriginalDataResources()) {
      assertNotNull(
          "Resource not renamed as expected: " + dataResource.getName(),
          dataResourceConsumer.get(
              expectedRenamings.getOrDefault(dataResource.getName(), dataResource.getName())));
    }
  }

  @Test
  public void testDisabled() throws Exception {
    DataResourceConsumerForTesting dataResourceConsumer = new DataResourceConsumerForTesting();
    compileWithR8(getProguardConfigWithNeverInline(false, null), dataResourceConsumer);
    // Check that none of the resources were renamed.
    for (DataEntryResource dataResource : getOriginalDataResources()) {
      assertNotNull(
          "Resource not renamed as expected: " + dataResource.getName(),
          dataResourceConsumer.get(dataResource.getName()));
    }
  }

  @Test
  public void testCollisionBehavior() throws Exception {
    DataResourceConsumerForTesting dataResourceConsumer = new DataResourceConsumerForTesting();
    compileWithR8(
        getProguardConfigWithNeverInline(true, null),
        dataResourceConsumer,
        ToolHelper.consumeString(this::checkR8Renamings),
        ImmutableList.<DataEntryResource>builder()
            .addAll(getOriginalDataResources())
            .add(
                DataEntryResource.fromBytes(
                    new byte[0], "adaptresourcefilenames/b.txt", Origin.unknown()))
            .build());
    assertEquals(1, diagnosticsHandler.warnings.size());
    assertThat(
        diagnosticsHandler.warnings.get(0).getDiagnosticMessage(),
        containsString("Resource 'adaptresourcefilenames/b.txt' already exists."));
    assertEquals(getOriginalDataResources().size(), dataResourceConsumer.size());
  }

  @Test
  public void testProguardBehavior() throws Exception {
    Path inputJar = addDataResourcesToExistingJar(TEST_JAR, getOriginalDataResources());
    Path proguardedJar =
        File.createTempFile("proguarded", FileUtils.JAR_EXTENSION, temp.getRoot()).toPath();
    Path proguardMapFile = File.createTempFile("mapping", ".txt", temp.getRoot()).toPath();
    runProguard6Raw(proguardedJar, inputJar, getProguardConfig(true, null), proguardMapFile);
    // Extract the names of the generated resources.
    Set<String> filenames = new HashSet<>();
    ArchiveResourceProvider.fromArchive(proguardedJar, true)
        .accept(
            new Visitor() {
              @Override
              public void visit(DataDirectoryResource directory) {}

              @Override
              public void visit(DataEntryResource file) {
                filenames.add(file.getName());
              }
            });
    // Check that the generated resources have the expected names.
    ClassNameMapper mapper = ClassNameMapper.mapperFromFile(proguardMapFile);
    for (DataEntryResource dataResource : getOriginalDataResources()) {
      String expectedName = getExpectedRenamingFor(dataResource.getName(), mapper);
      assertTrue(
          "Resource not renamed to '" + expectedName + "' as expected: " + dataResource.getName(),
          filenames.contains(expectedName));
    }
  }

  @Test
  public void testProguardCollisionBehavior() throws Exception {
    List<DataEntryResource> originalDataResources = getOriginalDataResources();
    Path inputJar =
        addDataResourcesToExistingJar(
            TEST_JAR,
            ImmutableList.<DataEntryResource>builder()
                .addAll(originalDataResources)
                .add(
                    DataEntryResource.fromBytes(
                        new byte[0], "adaptresourcefilenames/b.txt", Origin.unknown()))
                .build());
    Path proguardedJar =
        File.createTempFile("proguarded", FileUtils.JAR_EXTENSION, temp.getRoot()).toPath();
    runProguard6Raw(
        proguardedJar,
        inputJar,
        getProguardConfig(true, null),
        null,
        processResult -> {
          assertEquals(0, processResult.exitCode);
          assertThat(
              processResult.stderr,
              containsString(
                  "Warning: can't write resource [adaptresourcefilenames/b.txt] "
                      + "(Duplicate jar entry [adaptresourcefilenames/b.txt])"));
        });
    assertEquals(
        originalDataResources.size(),
        getDataResources(ArchiveResourceProvider.fromArchive(proguardedJar, true))
            .stream()
            .filter(dataResource -> !dataResource.getName().equals("META-INF/MANIFEST.MF"))
            .count());
  }

  private AndroidApp compileWithR8(String proguardConfig, DataResourceConsumer dataResourceConsumer)
      throws CompilationFailedException, IOException {
    return compileWithR8(proguardConfig, dataResourceConsumer, null);
  }

  private AndroidApp compileWithR8(
      String proguardConfig,
      DataResourceConsumer dataResourceConsumer,
      StringConsumer proguardMapConsumer)
      throws CompilationFailedException, IOException {
    return compileWithR8(
        proguardConfig, dataResourceConsumer, proguardMapConsumer, getOriginalDataResources());
  }

  private AndroidApp compileWithR8(
      String proguardConfig,
      DataResourceConsumer dataResourceConsumer,
      StringConsumer proguardMapConsumer,
      List<DataEntryResource> dataResources)
      throws CompilationFailedException, IOException {
    R8Command command =
        ToolHelper.allowTestProguardOptions(
                ToolHelper.prepareR8CommandBuilder(
                        getAndroidApp(dataResources), emptyConsumer(backend), diagnosticsHandler)
                    .addProguardConfiguration(ImmutableList.of(proguardConfig), Origin.unknown()))
            .addLibraryFiles(runtimeJar(backend))
            .build();
    return ToolHelper.runR8(
        command,
        options -> {
          options.dataResourceConsumer = dataResourceConsumer;
          options.proguardMapConsumer = proguardMapConsumer;
        });
  }

  private void checkR8Renamings(String proguardMap) {
    try {
      // Check that the renamings are as expected. These exact renamings are not important as
      // such, but the test expectations rely on them.
      mapper = ClassNameMapper.mapperFromString(proguardMap);
      assertEquals(
          "adaptresourcefilenames.TestClass",
          mapper.deobfuscateClassName("adaptresourcefilenames.TestClass"));
      assertEquals(
          "adaptresourcefilenames.B", mapper.deobfuscateClassName("adaptresourcefilenames.b"));
      assertEquals(
          "adaptresourcefilenames.B$Inner",
          mapper.deobfuscateClassName("adaptresourcefilenames.a"));
    } catch (IOException e) {
      throw new RuntimeException(e);
    }
  }

  private AndroidApp getAndroidApp(List<DataEntryResource> dataResources) throws IOException {
    AndroidApp.Builder builder = AndroidApp.builder();
    builder.addProgramFiles(ToolHelper.getClassFilesForTestDirectory(CF_DIR));
    dataResources.forEach(builder::addDataResource);
    return builder.build();
  }

  private static List<DataEntryResource> getOriginalDataResources() {
    List<String> filenames =
        ImmutableList.of(
            // Filename with simple name in root directory.
            "TestClass",
            "B",
            // Filename with qualified name in root directory.
            "adaptresourcefilenames.TestClass",
            "adaptresourcefilenames.B",
            // Filename with qualified directory name in root directory.
            "adaptresourcefilenames/TestClass",
            "adaptresourcefilenames/B",
            // Filename with simple name in sub directory.
            "foo/bar/baz/TestClass",
            "foo/bar/baz/B",
            // Filename with qualified name in sub directory.
            "foo/bar/baz/adaptresourcefiles.TestClass",
            "foo/bar/baz/adaptresourcefiles.B",
            // Filename with qualified directory name in sub directory.
            "foo/bar/baz/adaptresourcefilenames/TestClass",
            "foo/bar/baz/adaptresourcefilenames/B",
            //
            // SUFFIX VARIANTS:
            //
            // Filename with simple name and extension in root directory.
            "TestClass.txt",
            "B.txt",
            // Filename with qualified name and extension in root directory.
            "adaptresourcefilenames.TestClass.txt",
            "adaptresourcefilenames.B.txt",
            // Filename with qualified directory name and extension in root directory.
            "adaptresourcefilenames/TestClass.txt",
            "adaptresourcefilenames/B.txt",
            // Filename with simple name and extension in sub directory.
            "foo/bar/baz/TestClass.txt",
            "foo/bar/baz/B.txt",
            // Filename with qualified name and extension in sub directory.
            "foo/bar/baz/adaptresourcefiles.TestClass.txt",
            "foo/bar/baz/adaptresourcefiles.B.txt",
            // Filename with qualified directory name and extension in sub directory.
            "foo/bar/baz/adaptresourcefilenames/TestClass.txt",
            "foo/bar/baz/adaptresourcefilenames/B.txt",
            // Filename with other extension (used to test filtering).
            "adaptresourcefilenames/TestClass.md",
            "adaptresourcefilenames/B.md",
            // Filename with dot suffix only.
            "adaptresourcefilenames/TestClass.",
            "adaptresourcefilenames/B.",
            // Filename with dot suffix and extension.
            "adaptresourcefilenames/TestClass.suffix.txt",
            "adaptresourcefilenames/B.suffix.txt",
            // Filename with dash suffix and extension.
            "adaptresourcefilenames/TestClass-suffix.txt",
            "adaptresourcefilenames/B-suffix.txt",
            // Filename with dollar suffix and extension.
            "adaptresourcefilenames/TestClass$suffix.txt",
            "adaptresourcefilenames/B$suffix.txt",
            // Filename with dollar suffix matching inner class and extension.
            "adaptresourcefilenames/TestClass$Inner.txt",
            "adaptresourcefilenames/B$Inner.txt",
            // Filename with underscore suffix and extension.
            "adaptresourcefilenames/TestClass_suffix.txt",
            "adaptresourcefilenames/B_suffix.txt",
            // Filename with whitespace suffix and extension.
            "adaptresourcefilenames/TestClass suffix.txt",
            "adaptresourcefilenames/B suffix.txt",
            // Filename with identifier suffix and extension.
            "adaptresourcefilenames/TestClasssuffix.txt",
            "adaptresourcefilenames/Bsuffix.txt",
            // Filename with numeric suffix and extension.
            "adaptresourcefilenames/TestClass42.txt",
            "adaptresourcefilenames/B42.txt",
            //
            // PREFIX VARIANTS:
            //
            // Filename with dot prefix and extension.
            "adaptresourcefilenames/prefix.TestClass.txt",
            "adaptresourcefilenames/prefix.B.txt",
            // Filename with dash prefix and extension.
            "adaptresourcefilenames/prefix-TestClass.txt",
            "adaptresourcefilenames/prefix-B.txt",
            // Filename with dollar prefix and extension.
            "adaptresourcefilenames/prefix$TestClass.txt",
            "adaptresourcefilenames/prefix$B.txt",
            // Filename with identifier prefix and extension.
            "adaptresourcefilenames/prefixTestClass.txt",
            "adaptresourcefilenames/prefixB.txt",
            // Filename with numeric prefix and extension.
            "adaptresourcefilenames/42TestClass.txt",
            "adaptresourcefilenames/42B.txt",
            //
            // PACKAGE RENAMING TESTS:
            //
            // Filename that matches a type, but only the directory should be renamed.
            "adaptresourcefilenames/pkg/C",
            // Filename that matches a type that should be renamed.
            "adaptresourcefilenames/pkg/C.txt",
            // Filename that does not match a type, but where the directory should be renamed.
            "adaptresourcefilenames/pkg/file.txt",
            // Filename that does not match a type, but where a directory-prefix should be renamed.
            "adaptresourcefilenames/pkg/directory/file.txt",
            // Filename that matches a type, but only the directory should be renamed.
            "adaptresourcefilenames/pkg/innerpkg/D",
            // Filename that matches a type that should be renamed.
            "adaptresourcefilenames/pkg/innerpkg/D.txt",
            // Filename that does not match a type, but where the directory should be renamed.
            "adaptresourcefilenames/pkg/innerpkg/file.txt",
            // Filename that does not match a type, but where a directory-prefix should be renamed.
            "adaptresourcefilenames/pkg/innerpkg/directory/file.txt"
            );
    return filenames
        .stream()
        .map(filename -> DataEntryResource.fromBytes(new byte[0], filename, Origin.unknown()))
        .collect(Collectors.toList());
  }

  private static String getExpectedRenamingFor(String filename, ClassNameMapper mapper) {
    String typeName = null;
    String suffix = null;
    switch (filename) {
        // Filename with dot only.
      case "adaptresourcefilenames/B.":
        typeName = "adaptresourcefilenames.B";
        suffix = ".";
        break;
        // Filename with extension.
      case "adaptresourcefilenames/B.txt":
        typeName = "adaptresourcefilenames.B";
        suffix = ".txt";
        break;
        // Filename with other extension (used to test filtering).
      case "adaptresourcefilenames/B.md":
        typeName = "adaptresourcefilenames.B";
        suffix = ".md";
        break;
        // Filename with dot suffix and extension.
      case "adaptresourcefilenames/B.suffix.txt":
        typeName = "adaptresourcefilenames.B";
        suffix = ".suffix.txt";
        break;
        // Filename with dash suffix and extension.
      case "adaptresourcefilenames/B-suffix.txt":
        typeName = "adaptresourcefilenames.B";
        suffix = "-suffix.txt";
        break;
        // Filename with dollar suffix and extension.
      case "adaptresourcefilenames/B$suffix.txt":
        typeName = "adaptresourcefilenames.B";
        suffix = "$suffix.txt";
        break;
        // Filename with dollar suffix matching inner class and extension.
      case "adaptresourcefilenames/B$Inner.txt":
        typeName = "adaptresourcefilenames.B$Inner";
        suffix = ".txt";
        break;
        // Filename with underscore suffix and extension.
      case "adaptresourcefilenames/B_suffix.txt":
        typeName = "adaptresourcefilenames.B";
        suffix = "_suffix.txt";
        break;
        // Filename with whitespace suffix and extension.
      case "adaptresourcefilenames/B suffix.txt":
        typeName = "adaptresourcefilenames.B";
        suffix = " suffix.txt";
        break;
        //
        // PACKAGE RENAMING TESTS
        //
      case "adaptresourcefilenames/pkg/C.txt":
        typeName = "adaptresourcefilenames.pkg.C";
        suffix = ".txt";
        break;
      case "adaptresourcefilenames/pkg/innerpkg/D.txt":
        typeName = "adaptresourcefilenames.pkg.innerpkg.D";
        suffix = ".txt";
        break;
    }
    if (typeName != null) {
      String renamedName = mapper.getObfuscatedToOriginalMapping().inverse.get(typeName);
      assertNotNull(renamedName);
      assertNotEquals(typeName, renamedName);
      return renamedName.replace('.', '/') + suffix;
    }
    // Renamings for files in directories that match packages that have been renamed,
    // but where the filename itself should not be renamed.
    String samePackageAsType = null;
    switch (filename) {
      case "adaptresourcefilenames/pkg/C":
        samePackageAsType = "adaptresourcefilenames.pkg.C";
        suffix = "C";
        break;
      case "adaptresourcefilenames/pkg/file.txt":
        samePackageAsType = "adaptresourcefilenames.pkg.C";
        suffix = "file.txt";
        break;
      case "adaptresourcefilenames/pkg/directory/file.txt":
        samePackageAsType = "adaptresourcefilenames.pkg.C";
        suffix = "directory/file.txt";
        break;
      case "adaptresourcefilenames/pkg/innerpkg/D":
        samePackageAsType = "adaptresourcefilenames.pkg.innerpkg.D";
        suffix = "D";
        break;
      case "adaptresourcefilenames/pkg/innerpkg/file.txt":
        samePackageAsType = "adaptresourcefilenames.pkg.innerpkg.D";
        suffix = "file.txt";
        break;
      case "adaptresourcefilenames/pkg/innerpkg/directory/file.txt":
        samePackageAsType = "adaptresourcefilenames.pkg.innerpkg.D";
        suffix = "directory/file.txt";
        break;
    }
    if (samePackageAsType != null) {
      String renamedName = mapper.getObfuscatedToOriginalMapping().inverse.get(samePackageAsType);
      assertNotNull(renamedName);
      assertNotEquals(samePackageAsType, renamedName);
      if (renamedName.contains(".")) {
        String renamedPackageName = renamedName.substring(0, renamedName.lastIndexOf('.'));
        return renamedPackageName.replace('.', '/') + "/" + suffix;
      }
    }
    return filename;
  }
}
