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

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticException;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.NeverMerge;
import com.android.tools.r8.R8TestCompileResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.base.Throwables;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

/** Test for b/130211035. */
@RunWith(Parameterized.class)
public class MissingClassesJoinTest extends TestBase {

  private static final String expectedOutput = StringUtils.lines("Hello world!");

  private final boolean allowTypeErrors;
  private final TestParameters parameters;

  @Parameters(name = "{1}, allow type errors: {0}")
  public static List<Object[]> data() {
    return buildParameters(
        BooleanUtils.values(), getTestParameters().withAllRuntimesAndApiLevels().build());
  }

  public MissingClassesJoinTest(boolean allowTypeErrors, TestParameters parameters) {
    this.allowTypeErrors = allowTypeErrors;
    this.parameters = parameters;
  }

  @Test
  public void test() throws Exception {
    if (parameters.isDexRuntime() && !allowTypeErrors) {
      D8TestCompileResult compileResult =
          testForD8()
              // Intentionally not adding ASub2 as a program class.
              .addProgramClasses(A.class, ASub1.class, Box.class, TestClass.class)
              .setMinApi(parameters.getApiLevel())
              .compile();

      testForRuntime(parameters)
          .addProgramFiles(compileResult.writeToZip())
          .addProgramClasses(ASub2.class)
          .run(parameters.getRuntime(), TestClass.class)
          .assertSuccessWithOutput(expectedOutput);
    }

    try {
      R8TestCompileResult compileResult =
          testForR8(parameters.getBackend())
              // Intentionally not adding ASub2 as a program class.
              .addProgramClasses(A.class, ASub1.class, Box.class, TestClass.class)
              .addKeepAllClassesRule()
              .addOptionsModification(options -> options.testing.allowTypeErrors = allowTypeErrors)
              .allowDiagnosticWarningMessages()
              .enableMergeAnnotations()
              .setMinApi(parameters.getApiLevel())
              .compileWithExpectedDiagnostics(
                  diagnostics -> {
                    if (!allowTypeErrors) {
                      diagnostics.assertErrorThatMatches(diagnosticException(AssertionError.class));
                    }
                  })
              .assertAllWarningMessagesMatch(
                  equalTo(
                      "The method `void "
                          + TestClass.class.getTypeName()
                          + ".main(java.lang.String[])` does not type check and will be assumed to"
                          + " be unreachable."));

      // Compilation fails unless type errors are allowed.
      assertTrue(allowTypeErrors);

      testForRuntime(parameters)
          .addProgramFiles(compileResult.writeToZip())
          .addProgramClasses(ASub2.class)
          .run(parameters.getRuntime(), TestClass.class)
          // TestClass.main() does not type check, so it should have been replaced by `throw null`.
          // Note that, even if we do not replace the body of main() with `throw null`, the code
          // would still not work for the CF backend:
          //
          //     java.lang.VerifyError: Bad type on operand stack
          //     Exception Details:
          //       Location:
          //         MissingClassesJoinTest$TestClass.main([Ljava/lang/String;)V @28: putstatic
          //       Reason:
          //         Type 'java/lang/Object' (current frame, stack[0]) is not assignable to
          //         'com/android/tools/r8/ir/analysis/type/MissingClassesJoinTest$A'
          //       Current Frame:
          //         bci: @28
          //         flags: { }
          //         locals: { 'java/lang/Object' }
          //         stack: { 'java/lang/Object' }
          .assertFailureWithErrorThatMatches(containsString("NullPointerException"));

    } catch (CompilationFailedException e) {
      // Compilation should only fail when type errors are not allowed.
      assertFalse(
          StringUtils.joinLines(
              "Test should only throw when type errors are not allowed",
              Throwables.getStackTraceAsString(e)),
          allowTypeErrors);
    }
  }

  static class TestClass {

    public static void main(String[] args) {
      A a;
      if (System.currentTimeMillis() < 0) {
        a = new ASub1();
      } else {
        a = new ASub2();
      }
      Box.field = a;
    }
  }

  @NeverMerge
  abstract static class A {}

  static class ASub1 extends A {}

  static class ASub2 extends A {}

  static class Box {

    static {
      System.out.println("Hello world!");
    }

    static A field;
  }
}
