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

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

import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.bridgeremoval.bridgestoremove.Main;
import com.android.tools.r8.bridgeremoval.bridgestoremove.Outer;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import org.junit.Test;

public class RemoveVisibilityBridgeMethodsTest extends TestBase {

  private void run(boolean obfuscate) throws Exception {
    List<Class<?>> classes = ImmutableList.of(Outer.class, Main.class);
    String proguardConfig = keepMainProguardConfiguration(Main.class, true, obfuscate);
    CodeInspector inspector = new CodeInspector(compileWithR8(classes, proguardConfig));

    List<Method> removedMethods = ImmutableList.of(
        Outer.SubClass.class.getMethod("method"),
        Outer.StaticSubClass.class.getMethod("method"));

    removedMethods.forEach(method -> assertFalse(inspector.method(method).isPresent()));
  }

  @Test
  public void testWithObfuscation() throws Exception {
    run(true);
  }

  @Test
  public void testWithoutObfuscation() throws Exception {
    run(false);
  }

  @Test
  public void regressionTest_b76383728_WithObfuscation() throws Exception {
    runRegressionTest_b76383728(true);
  }

  @Test
  public void regressionTest_b76383728_WithoutObfuscation() throws Exception {
    runRegressionTest_b76383728(false);
  }

  /**
   * Regression test for b76383728 to make sure we correctly identify and remove real visibility
   * forward bridge methods synthesized by javac.
   */
  private void runRegressionTest_b76383728(boolean obfuscate) throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();

    ClassBuilder superClass = jasminBuilder.addClass("SuperClass");
    superClass.addDefaultConstructor();
    superClass.addVirtualMethod("method", Collections.emptyList(), "Ljava/lang/String;",
        ".limit stack 1",
        "ldc \"Hello World\"",
        "areturn");

    // Generate a subclass with a method with same
    ClassBuilder subclass = jasminBuilder.addClass("SubClass", superClass.name);
    subclass.addBridgeMethod("getMethod", Collections.emptyList(), "Ljava/lang/String;",
        ".limit stack 1",
        "aload_0",
        "invokespecial " + superClass.name + "/method()Ljava/lang/String;",
        "areturn");

    ClassBuilder mainClass = jasminBuilder.addClass("Main");
    mainClass.addMainMethod(
        ".limit stack 3",
        ".limit locals 2",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "new " + subclass.name,
        "dup",
        "invokespecial " + subclass.name + "/<init>()V",
        "invokevirtual " + subclass.name + "/getMethod()Ljava/lang/String;",
        "invokevirtual java/io/PrintStream/print(Ljava/lang/String;)V",
        "return"
    );

    final String mainClassName = mainClass.name;

    String proguardConfig = keepMainProguardConfiguration(mainClass.name, true, obfuscate);

    // Run input program on java.
    Path outputDirectory = temp.newFolder().toPath();
    jasminBuilder.writeClassFiles(outputDirectory);
    ProcessResult javaResult = ToolHelper.runJava(outputDirectory, mainClassName);
    assertEquals(0, javaResult.exitCode);

    AndroidApp optimizedApp = compileWithR8(jasminBuilder.build(), proguardConfig,
        // Disable inlining to avoid the (short) tested method from being inlined and then removed.
        internalOptions -> internalOptions.enableInlining = false);

    // Run optimized (output) program on ART
    String artResult = runOnArt(optimizedApp, mainClassName);
    assertEquals(javaResult.stdout, artResult);

    CodeInspector inspector = new CodeInspector(optimizedApp);

    ClassSubject classSubject = inspector.clazz(superClass.name);
    assertThat(classSubject, isPresent());
    MethodSubject methodSubject = classSubject
        .method("java.lang.String", "method", Collections.emptyList());
    assertThat(methodSubject, isPresent());

    classSubject = inspector.clazz(subclass.name);
    assertThat(classSubject, isPresent());
    methodSubject = classSubject.method("java.lang.String", "getMethod", Collections.emptyList());
    assertThat(methodSubject, isPresent());
  }
}
