// 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.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThat;

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;
    }
  }
}
