// 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,
        "-keeppackagenames adaptresourcefilenames**",
        "-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 *",
        "-nohorizontalclassmerging class adaptresourcefilenames.pkg.C",
        "-nohorizontalclassmerging class adaptresourcefilenames.pkg.innerpkg.D");
  }

  @Test
  public void testEnabled() throws Exception {
    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;
  }
}
