// Copyright (c) 2017, 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.

public class Locals {

  private static void noLocals() {
    System.out.println("There's no local here");
  }

  private static void unusedLocals() {
    int i = Integer.MAX_VALUE;
    System.out.println("Not using local variable");
  }

  private static void constantLocals(int p) {
    int c = 5;
    int v = c + p;
    System.out.println("c=" + c + ", v=" + v);
  }

  private static void zeroLocals() {
    int i = 0;
    float f = 0.0f;
    System.out.println("zeroLocals");
  }

  private static void noFlowOptimization() {
    int i = 0;
    if (i == 0) {
      System.out.println("i == 0");
    } else {
      System.out.println("i != 0");
    }
  }

  private static void manyLocals() {
    int i1 = 1;
    int i2 = 2;
    int i3 = 3;
    int i4 = 4;
    int i5 = 5;
    int i6 = 6;
    int i7 = 7;
    int i8 = 8;
    int i9 = 9;
    int i10 = 10;
    int i11 = 11;
    int i12 = 12;
    invokeRange(i6, i5, i4, i3, i2, i1, invokeRange(i12, i11, i10, i9, i8, i7, 0));
  }

  private static int reverseRange(int a, int b, int c, int d, int e, int f, int g) {
    return invokeRange(g, f, e, d, c, b, a);
  }

  private static int invokeRange(int a, int b, int c, int d, int e, int f, int g) {
    System.out.println(a + b + c + d + e + f + g);
    return a + b + c + d + e + f + g;
  }

  private void lotsOfArrayLength() {
    int lengthOfArray1 = 0;
    int lengthOfArray2 = 0;
    int lengthOfArray3 = 0;
    int lengthOfArray4 = 0;
    int lengthOfArray5 = 0;
    int lengthOfArray6 = 0;
    int lengthOfArray7 = 0;
    int lengthOfArray8 = 0;
    int lengthOfArray9 = 0;
    int lengthOfArray10 = 0;
    int lengthOfArray11 = 0;
    int lengthOfArray12 = 0;
    int lengthOfArray13 = 0;
    int lengthOfArray14 = 0;
    int lengthOfArray15 = 0;
    int lengthOfArray16 = 0;

    // These statements are compiled into new-array in DEX which stores the result in a 4bit
    // register (0..15).
    boolean[] array1 = new boolean[1];
    byte[] array2 = new byte[1];
    char[] array3 = new char[1];
    short[] array4 = new short[1];
    int[] array5 = new int[1];
    long[] array6 = new long[1];
    float[] array7 = new float[1];
    double[] array8 = new double[1];
    Object[] array9 = new Object[1];
    String[] array10 = new String[1];
    String[] array11 = new String[1];
    String[] array12 = new String[1];
    String[] array13 = new String[1];
    String[] array14 = new String[1];
    String[] array15 = new String[1];
    String[] array16 = new String[1];

    // 1st breakpoint to capture the IDs of each array.
    breakpoint();

    // Breakpoint at line below. In DEX, the array-length instruction expects a 4bit register
    // (0..15). By creating >16 locals, we should cause an intermediate move instruction to
    // copy/move a high register (>= 16) into a lower register (< 16).
    // A test should step instruction by instruction and make sure all locals have the correct
    // value.
    lengthOfArray1 = array1.length;
    lengthOfArray2 = array2.length;
    lengthOfArray3 = array3.length;
    lengthOfArray4 = array4.length;
    lengthOfArray5 = array5.length;
    lengthOfArray6 = array6.length;
    lengthOfArray7 = array7.length;
    lengthOfArray8 = array8.length;
    lengthOfArray9 = array9.length;
    lengthOfArray10 = array10.length;
    lengthOfArray11 = array11.length;
    lengthOfArray12 = array12.length;
    lengthOfArray13 = array13.length;
    lengthOfArray14 = array14.length;
    lengthOfArray15 = array15.length;
    lengthOfArray16 = array16.length;

    // Use all locals
    System.out.println(array1);
    System.out.println(array2);
    System.out.println(array3);
    System.out.println(array4);
    System.out.println(array5);
    System.out.println(array6);
    System.out.println(array7);
    System.out.println(array8);
    System.out.println(array9);
    System.out.println(array10);
    System.out.println(array11);
    System.out.println(array12);
    System.out.println(array13);
    System.out.println(array14);
    System.out.println(array15);
    System.out.println(array16);

    System.out.println(lengthOfArray1);
    System.out.println(lengthOfArray2);
    System.out.println(lengthOfArray3);
    System.out.println(lengthOfArray4);
    System.out.println(lengthOfArray5);
    System.out.println(lengthOfArray6);
    System.out.println(lengthOfArray7);
    System.out.println(lengthOfArray8);
    System.out.println(lengthOfArray9);
    System.out.println(lengthOfArray10);
    System.out.println(lengthOfArray11);
    System.out.println(lengthOfArray12);
    System.out.println(lengthOfArray13);
    System.out.println(lengthOfArray14);
    System.out.println(lengthOfArray15);
    System.out.println(lengthOfArray16);
  }

  // Utility method to set a breakpoint and inspect the stack.
  private static void breakpoint() {
  }

  public void foo(int x) {
    Integer obj = new Integer(x + x);
    long l = obj.longValue();
    try {
      l = obj.longValue();
      x = (int) l / x;
      invokerangeLong(l, l, l, l, l, l);
      sout(x);
    } catch (ArithmeticException e) {
      sout(l);
    } catch (RuntimeException e) {
      sout(l); // We should not attempt to read the previous definition of 'e' here or below.
    } catch (Throwable e) {
      sout(l);
    }
  }

  private void sout(long l) {
    System.out.print(l);
  }

  private void invokerangeLong(long a, long b, long c, long d, long e, long f) {
    if (a != d) {
      throw new RuntimeException("unexpected");
    }
  }

  public static int stepEmptyForLoopBody1(int n) {
    int i;
    for (i = 0; i < n; i++) ;
    return i;
  }

  public static int stepEmptyForLoopBody2(int n) {
    int i;
    for (i = 0; i < n; i++) {
      // has a line but still empty...
    }
    return i;
  }

  public static int stepNonEmptyForLoopBody(int n) {
    int i;
    for (i = 0; i < n; i++)
      nop();
    return i;
  }

  public static void nop() {}

  public static int tempInCase(int x) {
    int res = 0;
    for (int i = 0; i < x; ++i) {
      int rem = x - i;
      switch (rem) {
        case 1:
          return res;
        case 5:
          int tmp = res + x + i;
          res += tmp;
          break;
        case 10:
          i++;
          break;
        default:
          res += rem;
      }
      res += rem % 2;
    }
    res *= x;
    return res;
  }

  public static int localSwap(int x, int y) {
    int sum = x + y;
    {
      int t = x;
      x = y;
      y = t;
    }
    return sum + x + y;
  }

  public static void main(String[] args) {
    noLocals();
    unusedLocals();
    constantLocals(10);
    zeroLocals();
    noFlowOptimization();
    manyLocals();
    reverseRange(1,2,3,4,5,6,7);
    new Locals().lotsOfArrayLength();
    new Locals().foo(21);
    stepEmptyForLoopBody1(3);
    stepEmptyForLoopBody2(3);
    stepNonEmptyForLoopBody(3);
    tempInCase(42);
    localSwap(1, 2);
  }
}
