/*
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */

package com.facebook.redexlinemap;

import static org.fest.assertions.api.Assertions.*;

import android.test.InstrumentationTestCase;
import java.io.*;
import java.util.ArrayList;
import java.util.Arrays;
import org.junit.*;

public class InlineMainV2 extends InstrumentationTestCase {

  LineMapperV2 lm;

  public void setUp() throws Exception {
    super.setUp();
    lm = new LineMapperV2(
      getInstrumentation().getTargetContext().getResources().getAssets().open(
        "redex-line-number-map-v2"));
  }

  /**
   * Check that the stack trace of a non-inlined function makes sense.
   */
  @Test
  public void testBasic() throws Exception {
    try {
      InlineSeparateFileV2.wrapsThrow();
    } catch (Exception e) {
      ArrayList<StackTraceElement> trace = lm.mapStackTrace(e.getStackTrace());
      assertEquals(TraceUtil.traceToString(trace, 2), Arrays.asList(
        "com.facebook.redexlinemap.InlineSeparateFileV2.wrapsThrow(InlineSeparateFileV2.java:12)",
        "com.facebook.redexlinemap.InlineMainV2.testBasic(InlineMainV2.java:35)"
      ));
    }
  }

  /**
   * Check the stack trace of a once-inlined function.
   */
  @Test
  public void testInlineOnce() throws Exception {
    try {
      InlineSeparateFileV2.inlineOnce();
    } catch (Exception e) {
      ArrayList<StackTraceElement> trace = lm.mapStackTrace(e.getStackTrace());
      assertEquals(TraceUtil.traceToString(trace, 3), Arrays.asList(
        "com.facebook.redexlinemap.InlineSeparateFileV2.wrapsThrow(InlineSeparateFileV2.java:12)",
        "com.facebook.redexlinemap.InlineSeparateFileV2.inlineOnce(InlineSeparateFileV2.java:16)",
        "com.facebook.redexlinemap.InlineMainV2.testInlineOnce(InlineMainV2.java:51)"
      ));
    }
  }

  /**
   * Check the stack trace of a multiply-inlined function.
   */
  @Test
  public void testInlineTwice() throws Exception {
    try {
      InlineSeparateFileV2.inlineTwice();
    } catch (Exception e) {
      ArrayList<StackTraceElement> trace = lm.mapStackTrace(e.getStackTrace());
      assertEquals(TraceUtil.traceToString(trace, 4), Arrays.asList(
        "com.facebook.redexlinemap.InlineSeparateFileV2.wrapsThrow(InlineSeparateFileV2.java:12)",
        "com.facebook.redexlinemap.InlineSeparateFileV2.inlineOnce1(InlineSeparateFileV2.java:20)",
        "com.facebook.redexlinemap.InlineSeparateFileV2.inlineTwice(InlineSeparateFileV2.java:24)",
        "com.facebook.redexlinemap.InlineMainV2.testInlineTwice(InlineMainV2.java:68)"
      ));
    }
  }

  private static int inlineMe() {
    return 1;
  }

  @NoInline
  private void ignoreAndThrow(Object x) throws Exception {
    throw new Exception("foo");
  }

  /**
   * Check that the line number is reset to the original for the code that
   * follows an inlined method. We expect the resulting stack trace *not*
   * to point to inlineMe().
   */
  @Test
  public void testPositionReset() throws Exception {
    try {
      ignoreAndThrow(inlineMe());
    } catch (Exception e) {
      ArrayList<StackTraceElement> trace = lm.mapStackTrace(e.getStackTrace());
      assertEquals(TraceUtil.traceToString(trace, 2), Arrays.asList(
       "com.facebook.redexlinemap.InlineMainV2.ignoreAndThrow(InlineMainV2.java:86)",
       "com.facebook.redexlinemap.InlineMainV2.testPositionReset(InlineMainV2.java:97)"
      ));
    }
  }

  private void elseThrows() throws Exception {
    if (lm == null) {
      System.out.println("");
    } else {
      InlineSeparateFileV2.wrapsThrow();
    }
  }

  @Test
  public void testElseThrows() throws Exception {
    try {
      elseThrows();
    } catch (Exception e) {
      ArrayList<StackTraceElement> trace = lm.mapStackTrace(e.getStackTrace());
      assertEquals(
          TraceUtil.traceToString(trace, 3),
          Arrays.asList(
            "com.facebook.redexlinemap.InlineSeparateFileV2.wrapsThrow(InlineSeparateFileV2.java:12)",
            "com.facebook.redexlinemap.InlineMainV2.elseThrows(InlineMainV2.java:111)",
            "com.facebook.redexlinemap.InlineMainV2.testElseThrows(InlineMainV2.java:118)"));
    }
  }
}

@@ -489,16 +489,26 @@
 V2 lm;%0A%0A
+  @Before%0A
   public
@@ -536,24 +536,24 @@
 Exception %7B%0A
-
     super.se
@@ -1248,17 +1248,17 @@
 2.java:3
-5
+6
 )%22%0A     
@@ -1906,17 +1906,17 @@
 2.java:5
-1
+2
 )%22%0A     
@@ -2672,17 +2672,17 @@
 2.java:6
-8
+9
 )%22%0A     
@@ -3411,17 +3411,17 @@
 2.java:8
-6
+7
 )%22,%0A    
@@ -3500,17 +3500,17 @@
 2.java:9
-7
+8
 )%22%0A     
@@ -4161,17 +4161,17 @@
 .java:11
-1
+2
 )%22,%0A    
@@ -4253,17 +4253,17 @@
 .java:11
-8
+9
 )%22));%0A  

add missing @Before to test set up, fix line numbers