// Copyright (c) 2020, 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.cf.stackmap;

import static com.android.tools.r8.DiagnosticsMatcher.diagnosticType;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.CfCodeDiagnostics;
import java.io.IOException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

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

  private final TestParameters parameters;

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

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

  @Test
  public void testJvm() throws Exception {
    assumeTrue(parameters.isCfRuntime());
    testForJvm()
        .addProgramClassFileData(SwitchStackFrameFallThroughTest$MainDump.dump())
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines("java.io.IOException");
  }

  @Test
  public void testD8() throws Exception {
    assumeTrue(parameters.isDexRuntime());
    testForD8(parameters.getBackend())
        .addProgramClassFileData(SwitchStackFrameFallThroughTest$MainDump.dump())
        .setMinApi(parameters.getApiLevel())
        .addOptionsModification(options -> options.testing.readInputStackMaps = true)
        .compileWithExpectedDiagnostics(
            diagnostics -> {
              diagnostics.assertWarningsMatch(diagnosticType(CfCodeDiagnostics.class));
            });
  }

  public static class Main {

    public static void main(String[] args) {
      Throwable throwable = null;
      switch (args.length) {
        case 0:
          throwable = new IOException();
          break;
        case 1:
          throwable = new RuntimeException();
          break;
      }
      System.out.println(throwable.toString());
    }
  }

  // The above is roughly the code that below, except we move the switch targets above the switch
  // and then jump over them. We do this to check the fall-through of the switch.
  public static class SwitchStackFrameFallThroughTest$MainDump implements Opcodes {

    public static byte[] dump() {

      ClassWriter classWriter = new ClassWriter(0);
      MethodVisitor methodVisitor;

      classWriter.visit(
          V1_8,
          ACC_PUBLIC | ACC_SUPER,
          "com/android/tools/r8/cf/stackmap/SwitchStackFrameFallThroughTest$Main",
          null,
          "java/lang/Object",
          null);

      classWriter.visitSource("SwitchStackFrameFallThroughTest.java", null);

      classWriter.visitInnerClass(
          "com/android/tools/r8/cf/stackmap/SwitchStackFrameFallThroughTest$Main",
          "com/android/tools/r8/cf/stackmap/SwitchStackFrameFallThroughTest",
          "Main",
          ACC_PUBLIC | ACC_STATIC);

      {
        methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
        methodVisitor.visitCode();
        methodVisitor.visitVarInsn(ALOAD, 0);
        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
        methodVisitor.visitInsn(RETURN);
        methodVisitor.visitMaxs(1, 1);
        methodVisitor.visitEnd();
      }
      {
        methodVisitor =
            classWriter.visitMethod(
                ACC_PUBLIC | ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
        methodVisitor.visitCode();
        // This is moved here without a jump.

        Label label0 = new Label();
        Label label1 = new Label();
        Label label2 = new Label();
        Label label3 = new Label();

        methodVisitor.visitJumpInsn(GOTO, label2);

        methodVisitor.visitLabel(label0);
        methodVisitor.visitFrame(
            Opcodes.F_FULL,
            1,
            new Object[] {"[Ljava/lang/String;"},
            1,
            new Object[] {Opcodes.NULL});
        methodVisitor.visitInsn(POP);
        methodVisitor.visitTypeInsn(NEW, "java/io/IOException");
        methodVisitor.visitInsn(DUP);
        methodVisitor.visitMethodInsn(INVOKESPECIAL, "java/io/IOException", "<init>", "()V", false);
        methodVisitor.visitVarInsn(ASTORE, 1);
        methodVisitor.visitJumpInsn(GOTO, label3);

        methodVisitor.visitLabel(label1);
        methodVisitor.visitFrame(
            Opcodes.F_FULL,
            1,
            new Object[] {"[Ljava/lang/String;"},
            1,
            new Object[] {Opcodes.NULL});
        methodVisitor.visitInsn(POP);
        methodVisitor.visitTypeInsn(NEW, "java/lang/RuntimeException");
        methodVisitor.visitInsn(DUP);
        methodVisitor.visitMethodInsn(
            INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "()V", false);
        methodVisitor.visitVarInsn(ASTORE, 1);
        methodVisitor.visitJumpInsn(GOTO, label3);

        methodVisitor.visitLabel(label2);
        methodVisitor.visitFrame(Opcodes.F_FULL, 1, new Object[] {"[Ljava/lang/String;"}, 0, null);
        methodVisitor.visitInsn(ACONST_NULL);
        methodVisitor.visitVarInsn(ALOAD, 0);
        methodVisitor.visitInsn(ARRAYLENGTH);
        methodVisitor.visitLookupSwitchInsn(label1, new int[] {0, 1}, new Label[] {label0, label1});
        methodVisitor.visitLabel(label3);
        methodVisitor.visitFrame(
            Opcodes.F_FULL,
            2,
            new Object[] {"[Ljava/lang/String;", "java/lang/Throwable"},
            0,
            null);
        methodVisitor.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
        methodVisitor.visitVarInsn(ALOAD, 1);
        methodVisitor.visitMethodInsn(
            INVOKEVIRTUAL, "java/lang/Throwable", "toString", "()Ljava/lang/String;", false);
        methodVisitor.visitMethodInsn(
            INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
        methodVisitor.visitInsn(RETURN);
        methodVisitor.visitMaxs(4, 2);
        methodVisitor.visitEnd();
      }
      classWriter.visitEnd();

      return classWriter.toByteArray();
    }
  }
}
