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

import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.cf.CfVersion;
import com.android.tools.r8.transformers.ClassFileTransformer.MethodPredicate;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import java.util.Arrays;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.objectweb.asm.Label;
import org.objectweb.asm.Opcodes;

@RunWith(Parameterized.class)
public class NopLineRegression230337727Test extends TestBase implements Opcodes {

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withDefaultRuntimes().withApiLevel(AndroidApiLevel.B).build();
  }

  private final TestParameters parameters;

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

  @Test
  public void test() throws Exception {
    testForRuntime(parameters)
        .addProgramClassFileData(getTestClassTransformed())
        .run(parameters.getRuntime(), TestClass.class)
        .inspect(
            inspector -> {
              MethodSubject foo = inspector.clazz(TestClass.class).uniqueMethodWithName("foo");
              assertTrue(
                  foo.getLineNumberTable().getLines().toString(),
                  foo.getLineNumberTable().getLines().contains(11));
            });
  }

  static class TestClass {

    public static boolean boo() {
      return true;
    }

    public static void foo(List<Integer> args) {
      System.nanoTime();
      // Code added by transformer for the kotlin code:
      //  if (boo()) {
      //    l.forEach {}
      //  }
      //  if (boo()) {}
    }

    public static void main(String[] args) {
      foo(Arrays.asList(1, 2, 3));
    }
  }

  private static byte[] getTestClassTransformed() throws Exception {
    // Code generated by kotlin but with frames, locals and checkNotNullParameter removed.
    String holder = binaryName(TestClass.class);
    return transformer(TestClass.class)
        .setVersion(CfVersion.V1_5) // Avoid need of stack frames
        .setMaxs(MethodPredicate.onName("foo"), 2, 7)
        .transformMethodInsnInMethod(
            "foo",
            (opcode, owner, name, descriptor, isInterface, visitor) -> {
              Label label1 = new Label();
              visitor.visitLabel(label1);
              visitor.visitLineNumber(4, label1);
              visitor.visitMethodInsn(INVOKESTATIC, holder, "boo", "()Z", false);
              Label label2 = new Label();
              visitor.visitJumpInsn(IFEQ, label2);
              Label label3 = new Label();
              visitor.visitLabel(label3);
              visitor.visitLineNumber(5, label3);
              visitor.visitVarInsn(ALOAD, 0);
              visitor.visitTypeInsn(CHECKCAST, "java/lang/Iterable");
              visitor.visitVarInsn(ASTORE, 1);
              visitor.visitInsn(ICONST_0);
              visitor.visitVarInsn(ISTORE, 2);
              Label label5 = new Label();
              visitor.visitLabel(label5);
              visitor.visitLineNumber(10, label5);
              visitor.visitVarInsn(ALOAD, 1);
              visitor.visitMethodInsn(
                  INVOKEINTERFACE,
                  "java/lang/Iterable",
                  "iterator",
                  "()Ljava/util/Iterator;",
                  true);
              visitor.visitVarInsn(ASTORE, 3);
              Label label6 = new Label();
              visitor.visitLabel(label6);
              visitor.visitVarInsn(ALOAD, 3);
              visitor.visitMethodInsn(
                  INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
              Label label7 = new Label();
              visitor.visitJumpInsn(IFEQ, label7);
              visitor.visitVarInsn(ALOAD, 3);
              visitor.visitMethodInsn(
                  INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
              visitor.visitVarInsn(ASTORE, 4);
              visitor.visitVarInsn(ALOAD, 4);
              visitor.visitTypeInsn(CHECKCAST, "java/lang/Number");
              visitor.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Number", "intValue", "()I", false);
              visitor.visitVarInsn(ISTORE, 5);
              visitor.visitInsn(ICONST_0);
              visitor.visitVarInsn(ISTORE, 6);
              Label label10 = new Label();
              visitor.visitLabel(label10);
              visitor.visitLineNumber(5, label10);
              visitor.visitInsn(NOP);
              visitor.visitJumpInsn(GOTO, label6);
              visitor.visitLabel(label7);
              visitor.visitLineNumber(11, label7);
              visitor.visitInsn(NOP);
              visitor.visitLabel(label2);
              visitor.visitLineNumber(7, label2);
              visitor.visitMethodInsn(INVOKESTATIC, holder, "boo", "()Z", false);
              Label label12 = new Label();
              visitor.visitJumpInsn(IFEQ, label12);
              visitor.visitLabel(label12);
              visitor.visitLineNumber(8, label12);
              visitor.visitInsn(RETURN);
            })
        .transform();
  }
}
