// 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.DiagnosticsMatcher.diagnosticMessage;
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())
                .allowDiagnosticWarningMessages()
                .compileWithExpectedDiagnostics(
                    diagnostics ->
                        diagnostics.assertAllWarningsMatch(
                            diagnosticMessage(
                                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();
    }
  }
}
