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

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.NeverPropagateValue;
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.ToolHelper;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
import java.io.IOException;
import java.nio.file.Path;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import org.junit.Assume;
import org.junit.ClassRule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.BeforeParam;

@RunWith(Parameterized.class)
public class ApplyMappingAfterVerticalMergingMethodTest extends TestBase {

  private static final String OUTPUT = "LibraryBase::foo";
  private static final String EXPECTED_SUCCESS = StringUtils.lines(OUTPUT);

  // Base class will be vertical class merged into subclass
  public static class LibraryBase {

    @NeverPropagateValue
    @NeverInline
    public String foo() {
      return OUTPUT;
    }
  }

  // Subclass targeted via vertical class merging. The main method ensures a reference to foo.
  public static class LibrarySubclass extends LibraryBase {

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

  // Program class that uses LibrarySubclass and accesses foo via its main.
  public static class ProgramClass extends LibrarySubclass {

    public static void main(String[] args) {
      LibrarySubclass.main(args);
    }
  }

  // Test runner code follows.

  // Result of the shared compilation.
  private static class CompilationResult {
    final R8TestCompileResult library;
    final R8TestCompileResult program;
    final Path libraryPath;

    public CompilationResult(
        R8TestCompileResult library, R8TestCompileResult program, Path libraryPath) {
      this.library = library;
      this.program = program;
      this.libraryPath = libraryPath;
    }
  }

  private static final Class<?>[] LIBRARY_CLASSES = {
    NeverMerge.class, LibraryBase.class, LibrarySubclass.class
  };

  private static final Class<?>[] PROGRAM_CLASSES = {
      ProgramClass.class
  };

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

  private static Function<Backend, CompilationResult> compilationResults =
      memoizeFunction(ApplyMappingAfterVerticalMergingMethodTest::compile);

  @ClassRule
  public static TemporaryFolder staticTemp = ToolHelper.getTemporaryFolderForTest();

  @BeforeParam
  public static void forceCompilation(TestParameters parameters) {
    compilationResults.apply(parameters.getBackend());
  }

  public static CompilationResult compile(Backend backend)
      throws ExecutionException, CompilationFailedException, IOException {
    R8TestCompileResult library = compileLibrary(backend);
    R8TestCompileResult program = compileProgram(backend, library.getProguardMap());
    return new CompilationResult(library, program, library.writeToZip());
  }

  private static R8TestCompileResult compileLibrary(Backend backend)
      throws CompilationFailedException, IOException, ExecutionException {
    return testForR8(staticTemp, backend)
        .enableInliningAnnotations()
        .enableMemberValuePropagationAnnotations()
        .addProgramClasses(LIBRARY_CLASSES)
        .addKeepMainRule(LibrarySubclass.class)
        .addKeepClassAndDefaultConstructor(LibrarySubclass.class)
        .setMinApi(AndroidApiLevel.B)
        .compile()
        .inspect(
            inspector -> {
              assertThat(inspector.clazz(LibraryBase.class), not(isPresent()));
              assertThat(inspector.clazz(LibrarySubclass.class), isPresent());
              List<FoundMethodSubject> methods =
                  inspector.clazz(LibrarySubclass.class).allMethods();
              assertEquals(3, methods.size());
              assertEquals(1, methods.stream().filter(m -> m.isInstanceInitializer()).count());
              assertEquals(
                  1, methods.stream().filter(m -> m.getFinalName().contains("main")).count());
              assertEquals(
                  1, methods.stream().filter(m -> m.getOriginalName().contains("foo")).count());
            });
  }

  private static R8TestCompileResult compileProgram(Backend backend, String proguardMap)
      throws CompilationFailedException {
    return testForR8(staticTemp, backend)
        .noTreeShaking()
        .noMinification()
        .addProgramClasses(PROGRAM_CLASSES)
        .addApplyMapping(proguardMap)
        .addLibraryClasses(LIBRARY_CLASSES)
        .addLibraryFiles(runtimeJar(backend))
        .setMinApi(AndroidApiLevel.B)
        .compile();
  }

  private TestParameters parameters;

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

  @Test
  public void runOnJvm() throws Throwable {
    Assume.assumeTrue(parameters.isCfRuntime());
    testForJvm()
        .addProgramClasses(LIBRARY_CLASSES)
        .addProgramClasses(PROGRAM_CLASSES)
        .run(parameters.getRuntime(), ProgramClass.class)
        .assertSuccessWithOutput(EXPECTED_SUCCESS);
  }

  @Test
  public void b121042934() throws Exception {
    CompilationResult compilationResult = compilationResults.apply(parameters.getBackend());
    compilationResult
        .program
        .addRunClasspathFiles(compilationResult.libraryPath)
        .run(parameters.getRuntime(), ProgramClass.class)
        .assertSuccessWithOutput(EXPECTED_SUCCESS);
  }
}
