// 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.ir.optimize;

import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.jasmin.JasminTestBase;
import com.android.tools.r8.utils.AbortException;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.BooleanUtils;
import com.google.common.collect.ImmutableList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class B116282409 extends JasminTestBase {

  private final Backend backend;

  private final boolean enableVerticalClassMerging;

  @Rule public ExpectedException exception = ExpectedException.none();

  @Parameters(name = "Backend: {0}, vertical class merging: {1}")
  public static Collection<Object[]> data() {
    return buildParameters(ToolHelper.getBackends(), BooleanUtils.values());
  }

  public B116282409(Backend backend, boolean enableVerticalClassMerging) {
    this.backend = backend;
    this.enableVerticalClassMerging = enableVerticalClassMerging;
  }

  @Test
  public void test() throws Exception {
    JasminBuilder jasminBuilder = new JasminBuilder();

    // Create a class A with a default constructor that prints "In A.<init>()".
    ClassBuilder classBuilder = jasminBuilder.addClass("A");
    classBuilder.addMethod(
        "public",
        "<init>",
        ImmutableList.of(),
        "V",
        ".limit stack 2",
        ".limit locals 1",
        "aload_0",
        "invokespecial java/lang/Object/<init>()V",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "ldc \"In A.<init>()\"",
        "invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V",
        "return");

    // Create a class B that inherits from A.
    classBuilder = jasminBuilder.addClass("B", "A");

    // Also add a simple method that the class inliner would inline.
    classBuilder.addVirtualMethod(
        "m", "I", ".limit stack 5", ".limit locals 5", "bipush 42", "ireturn");

    // Add a test class that initializes an instance of B using A.<init>.
    classBuilder = jasminBuilder.addClass("TestClass");
    classBuilder.addMainMethod(
        ".limit stack 5",
        ".limit locals 5",
        "getstatic java/lang/System/out Ljava/io/PrintStream;",
        "new B",
        "dup",
        "invokespecial A/<init>()V", // NOTE: usually B.<init>
        "invokevirtual B/m()I",
        "invokevirtual java/io/PrintStream/println(I)V",
        "return");

    // Build app.
    if (enableVerticalClassMerging) {
      exception.expect(CompilationFailedException.class);
      exception.expectCause(
          new CustomExceptionMatcher(
              "Unable to rewrite `invoke-direct A.<init>(new B, ...)` in method "
                  + "`void TestClass.main(java.lang.String[])` after type `A` was merged into `B`.",
              "Please add the following rule to your Proguard configuration file: "
                  + "`-keep,allowobfuscation class A`."));
    }

    AndroidApp output =
        compileWithR8(
            jasminBuilder.build(),
            keepMainProguardConfiguration("TestClass"),
            options -> options.enableVerticalClassMerging = enableVerticalClassMerging,
            backend);
    assertFalse(enableVerticalClassMerging);

    // Run app.
    ProcessResult vmResult = runOnVMRaw(output, "TestClass", backend);
    if (backend == Backend.CF) {
      // Verify that the input code does not run with java.
      ProcessResult javaResult = runOnJavaRaw(jasminBuilder, "TestClass");
      assertNotEquals(0, javaResult.exitCode);
      assertThat(javaResult.stderr, containsString("VerifyError"));
      assertThat(javaResult.stderr, containsString("Call to wrong initialization method"));

      // The same should be true for the generated program.
      assertNotEquals(0, vmResult.exitCode);
      assertThat(vmResult.stderr, containsString("VerifyError"));
      assertThat(vmResult.stderr, containsString("Call to wrong initialization method"));
    } else {
      assert backend == Backend.DEX;
      if (ToolHelper.getDexVm().isOlderThanOrEqual(DexVm.ART_4_4_4_HOST)) {
        assertNotEquals(0, vmResult.exitCode);
        assertThat(
            vmResult.stderr,
            containsString("VFY: invoke-direct <init> on super only allowed for 'this' in <init>"));
      } else {
        assertEquals(0, vmResult.exitCode);
        assertEquals(
            String.join(System.lineSeparator(), "In A.<init>()", "42", ""), vmResult.stdout);
      }
    }
  }

  private static class CustomExceptionMatcher extends BaseMatcher<Throwable> {

    private List<String> messages;

    public CustomExceptionMatcher(String... messages) {
      this.messages = Arrays.asList(messages);
    }

    @Override
    public void describeTo(Description description) {
      description
          .appendText("a string containing ")
          .appendText(
              String.join(
                  ", ", messages.stream().map(m -> "\"" + m + "\"").collect(Collectors.toList())));
    }

    @Override
    public boolean matches(Object o) {
      if (o instanceof AbortException) {
        AbortException exception = (AbortException) o;
        if (exception.getMessage() != null
            && messages.stream().allMatch(message -> exception.getMessage().contains(message))) {
          return true;
        }
        if (exception.getCause() != null) {
          return matches(exception.getCause());
        }
      }
      return false;
    }
  }
}
