// Copyright (c) 2020, 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.utils.codeinspector.Matchers.isRenamed;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.naming.testclasses.A;
import com.android.tools.r8.naming.testclasses.B;
import com.android.tools.r8.utils.FileUtils;
import java.io.IOException;
import java.nio.file.Path;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/** This test is designed to test the workaround for b/149946708. */
@RunWith(Parameterized.class)
public class ClassNameMinifierOriginalClassNameTest extends TestBase {

  private final TestParameters parameters;

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimesAndApiLevels().build();
  }

  public ClassNameMinifierOriginalClassNameTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  private static Function<TestParameters, R8TestCompileResult> compilationResults =
      memoizeFunction(ClassNameMinifierOriginalClassNameTest::compile);

  private static R8TestCompileResult compile(TestParameters parameters)
      throws CompilationFailedException, IOException, ExecutionException {
    // Adding the obfuscation dictionary just ensures that we assign a name to B that will collide
    // independent of minification scheme.
    Path dictionary = getStaticTemp().newFolder().toPath().resolve("dictionary.txt");
    FileUtils.writeTextFile(dictionary, "A");
    return testForR8(getStaticTemp(), parameters.getBackend())
        .addProgramClasses(A.class, B.class)
        .addKeepClassAndMembersRulesWithAllowObfuscation(B.class)
        .addKeepRules("-classobfuscationdictionary " + dictionary.toString(), "-keeppackagenames")
        .setMinApi(parameters.getApiLevel())
        .compile()
        .inspect(
            inspector -> {
              assertEquals(1, inspector.allClasses().size());
              assertThat(inspector.clazz(B.class), isRenamed());
              assertEquals(A.class.getTypeName(), inspector.clazz(B.class).getFinalName());
            });
  }

  @Test
  public void testR8() throws ExecutionException, CompilationFailedException, IOException {
    R8TestCompileResult libraryCompileResult = compilationResults.apply(parameters);
    testForR8(parameters.getBackend())
        .addProgramClasses(Main.class)
        .setMinApi(parameters.getApiLevel())
        .addKeepMainRule(Main.class)
        .noMinification()
        .addClasspathClasses(A.class, B.class)
        .addApplyMapping(libraryCompileResult.getProguardMap())
        .compile()
        .addRunClasspathFiles(libraryCompileResult.writeToZip())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines("B.foo");
  }

  @Test
  public void testR8WithReferenceToNotMapped() {
    assumeTrue(parameters.isDexRuntime());
    R8TestCompileResult libraryCompileResult = compilationResults.apply(parameters);
    assertThrows(
        CompilationFailedException.class,
        () ->
            testForR8(parameters.getBackend())
                .addProgramClasses(MainWithReferenceToNotMapped.class)
                .setMinApi(parameters.getApiLevel())
                .addKeepMainRule(MainWithReferenceToNotMapped.class)
                .noMinification()
                .addClasspathClasses(A.class, B.class)
                .addApplyMapping(libraryCompileResult.getProguardMap())
                .compileWithExpectedDiagnostics(
                    diagnosticMessages ->
                        diagnosticMessages.assertErrorMessageThatMatches(
                            containsString(
                                "'"
                                    + B.class.getTypeName()
                                    + "' cannot be mapped to '"
                                    + A.class.getTypeName()
                                    + "' because it is in conflict"))));
  }

  public static class Main {

    public static void main(String[] args) {
      new B().foo();
    }
  }

  public static class MainWithReferenceToNotMapped {

    public static void main(String[] args) {
      System.out.println(new A());
      new B().foo();
    }
  }
}
