// 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.debuginfo;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

public class InliningWithoutPositionsTestSourceDump implements Opcodes {

  public enum Location {
    MAIN(123),
    FOO1(234),
    BAR(345),
    FOO2(456);
    final int line;

    Location(int line) {
      this.line = line;
    }
  };

  /*
  This generator creates the class 'InliningWithoutPositionsTestSource' with three methods,
  'main', calling 'foo', which is calling 'bar'.

  Depending on the mainPos, foo1Pos, barPos and foo2Pos parameters, we insert line numbers in
  'main', in 'foo' before calling 'bar' (marked foo1), in 'foo' after calling 'bar' (marked foo2)
  and in 'bar'. The methods contain no other line numbers.

  The throwLocation parameter determines at which location will be an exception thrown.

  The generator code is based on the ASMifier dump of the following class:

      package com.android.tools.r8.debuginfo;

      public class InliningWithoutPositionsTestSource {

        private static void throwingBar() {
          throw new RuntimeException("<BAR-exception>");
        }

        private static void printingBar() {
          System.err.println("<in-BAR>");
        }

        private static void foo(boolean b) {
          if (b) throw new RuntimeException("<FOO1-exception>");
          throwingBar();
        }

        private static void foo2() {
          throwingBar();
          throw new RuntimeException("<FOO2-exception>");
        }

        public static void main(String[] args) {
          foo(true);
        }
      }
  */
  public static byte[] dump(
      boolean mainPos, boolean foo1Pos, boolean barPos, boolean foo2Pos, Location throwLocation) {
    ClassWriter cw = new ClassWriter(0);
    FieldVisitor fv;
    MethodVisitor mv;
    AnnotationVisitor av0;

    cw.visit(
        V1_8,
        ACC_PUBLIC + ACC_SUPER,
        "com/android/tools/r8/debuginfo/InliningWithoutPositionsTestSource",
        null,
        "java/lang/Object",
        null);

    cw.visitSource("InliningWithoutPositionsTestSource.java", null);

    {
      mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      mv.visitVarInsn(ALOAD, 0);
      mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
      mv.visitInsn(RETURN);
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitLocalVariable(
          "this",
          "Lcom/android/tools/r8/debuginfo/InliningWithoutPositionsTestSource;",
          null,
          l0,
          l1,
          0);
      mv.visitMaxs(1, 1);
      mv.visitEnd();
    }
    if (throwLocation == Location.BAR) {
      mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC, "bar", "()V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      if (barPos) {
        mv.visitLineNumber(Location.BAR.line, l0);
      }
      mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
      mv.visitInsn(DUP);
      mv.visitLdcInsn("<BAR-exception>");
      mv.visitMethodInsn(
          INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
      mv.visitInsn(ATHROW);
      mv.visitMaxs(3, 0);
      mv.visitEnd();
    } else {
      mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC, "bar", "()V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      if (barPos) {
        mv.visitLineNumber(Location.BAR.line, l0);
      }
      mv.visitFieldInsn(GETSTATIC, "java/lang/System", "err", "Ljava/io/PrintStream;");
      mv.visitLdcInsn("<in-BAR>");
      mv.visitMethodInsn(
          INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V", false);
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitInsn(RETURN);
      mv.visitMaxs(2, 0);
      mv.visitEnd();
    }
    if (throwLocation == Location.FOO2) {
      mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC, "foo", "()V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      if (foo1Pos) {
        mv.visitLineNumber(Location.FOO1.line, l0);
      }
      mv.visitMethodInsn(
          INVOKESTATIC,
          "com/android/tools/r8/debuginfo/InliningWithoutPositionsTestSource",
          "bar",
          "()V",
          false);
      Label l1 = new Label();
      mv.visitLabel(l1);
      if (foo2Pos) {
        mv.visitLineNumber(Location.FOO2.line, l1);
      }
      mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
      mv.visitInsn(DUP);
      mv.visitLdcInsn("<FOO2-exception>");
      mv.visitMethodInsn(
          INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
      mv.visitInsn(ATHROW);
      mv.visitMaxs(3, 0);
      mv.visitEnd();
    } else {
      mv = cw.visitMethod(ACC_PRIVATE + ACC_STATIC, "foo", "(Z)V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      if (foo1Pos) {
        mv.visitLineNumber(Location.FOO1.line, l0);
      }
      mv.visitVarInsn(ILOAD, 0);
      Label l1 = new Label();
      mv.visitJumpInsn(IFEQ, l1);
      mv.visitTypeInsn(NEW, "java/lang/RuntimeException");
      mv.visitInsn(DUP);
      mv.visitLdcInsn("<FOO1-exception>");
      mv.visitMethodInsn(
          INVOKESPECIAL, "java/lang/RuntimeException", "<init>", "(Ljava/lang/String;)V", false);
      mv.visitInsn(ATHROW);
      mv.visitLabel(l1);
      mv.visitFrame(Opcodes.F_SAME, 0, null, 0, null);
      mv.visitMethodInsn(
          INVOKESTATIC,
          "com/android/tools/r8/debuginfo/InliningWithoutPositionsTestSource",
          "bar",
          "()V",
          false);
      Label l2 = new Label();
      mv.visitLabel(l2);
      if (foo2Pos) {
        mv.visitLineNumber(Location.FOO2.line, l2);
      }
      mv.visitInsn(RETURN);
      Label l3 = new Label();
      mv.visitLabel(l3);
      mv.visitLocalVariable("b", "Z", null, l0, l3, 0);
      mv.visitMaxs(3, 1);
      mv.visitEnd();
    }

    {
      mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
      mv.visitCode();
      Label l0 = new Label();
      mv.visitLabel(l0);
      if (mainPos) {
        mv.visitLineNumber(Location.MAIN.line, l0);
      }
      if (throwLocation == Location.FOO2) {
        mv.visitMethodInsn(
            INVOKESTATIC,
            "com/android/tools/r8/debuginfo/InliningWithoutPositionsTestSource",
            "foo",
            "()V",
            false);
      } else {
        mv.visitInsn(throwLocation == Location.FOO1 ? ICONST_1 : ICONST_0);
        mv.visitMethodInsn(
            INVOKESTATIC,
            "com/android/tools/r8/debuginfo/InliningWithoutPositionsTestSource",
            "foo",
            "(Z)V",
            false);
      }
      Label l1 = new Label();
      mv.visitLabel(l1);
      mv.visitInsn(RETURN);
      Label l2 = new Label();
      mv.visitLabel(l2);
      mv.visitLocalVariable("args", "[Ljava/lang/String;", null, l0, l2, 0);
      if (throwLocation == Location.FOO2) {
        mv.visitMaxs(0, 1);
      } else {
        mv.visitMaxs(1, 1);
      }
      mv.visitEnd();
    }

    cw.visitEnd();

    return cw.toByteArray();
  }
}
