// 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 static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersBuilder;
import com.android.tools.r8.debuginfo.InliningWithoutPositionsTestSourceDump.Location;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.naming.retrace.StackTrace.StackTraceLine;
import com.android.tools.r8.utils.AndroidApiLevel;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.hamcrest.CoreMatchers;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

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

  private static final String TEST_SIMPLE_NAME = "InliningWithoutPositionsTestSource";
  private static final String TEST_PACKAGE = "com.android.tools.r8.debuginfo";
  private static final String TEST_FILE = TEST_SIMPLE_NAME + ".java";
  private static final String TEST_CLASS = TEST_PACKAGE + "." + TEST_SIMPLE_NAME;

  private final TestParameters parameters;
  private final boolean mainPos;
  private final boolean foo1Pos;
  private final boolean barPos;
  private final boolean foo2Pos;
  private final Location throwLocation;

  @Parameters(name = "{0}: main/foo1/bar/foo2 positions: {1}/{2}/{3}/{4}, throwLocation: {5}")
  public static Collection<Object[]> data() {
    List<Object[]> testCases = new ArrayList<>();
    for (TestParameters parameters :
        TestParametersBuilder.builder().withAllRuntimes().withApiLevel(AndroidApiLevel.B).build()) {
      for (int i = 0; i < 16; ++i) {
        for (Location throwLocation : Location.values()) {
          if (throwLocation != Location.MAIN) {
            testCases.add(
                new Object[] {
                  parameters, (i & 1) != 0, (i & 2) != 0, (i & 4) != 0, (i & 8) != 0, throwLocation
                });
          }
        }
      }
    }
    return testCases;
  }

  public InliningWithoutPositionsTestRunner(
      TestParameters parameters,
      boolean mainPos,
      boolean foo1Pos,
      boolean barPos,
      boolean foo2Pos,
      Location throwLocation) {
    this.parameters = parameters;
    this.mainPos = mainPos;
    this.foo1Pos = foo1Pos;
    this.barPos = barPos;
    this.foo2Pos = foo2Pos;
    this.throwLocation = throwLocation;
  }

  @Test
  public void testStackTrace() throws Exception {
    testForR8(parameters.getBackend())
        .setMinApi(parameters.getApiLevel())
        .addProgramClassFileData(
            InliningWithoutPositionsTestSourceDump.dump(
                mainPos, foo1Pos, barPos, foo2Pos, throwLocation))
        .addKeepMainRule(TEST_CLASS)
        .addKeepAttributeSourceFile()
        .addKeepAttributeLineNumberTable()
        .addOptionsModification(
            options -> options.inlinerOptions().simpleInliningInstructionLimit = 40)
        .run(parameters.getRuntime(), TEST_CLASS)
        .assertFailure()
        .inspectOriginalStackTrace(
            rawStackTrace -> {
              assertThat(
                  rawStackTrace.getExceptionLine(),
                  CoreMatchers.containsString("<" + throwLocation + "-exception>"));
              assertTrue(rawStackTrace.size() > 1);
              StackTraceLine line = rawStackTrace.get(0);
              assertEquals(TEST_CLASS, line.className);
              assertEquals("main", line.methodName);
              // Expected line number could be PC based or increments.
              // The test need not check what it is, just that all methods have been fully inlined.
              assertEquals(2, rawStackTrace.size());
            })
        .inspectStackTrace(
            retracedStackTrace -> {
              assertThat(
                  retracedStackTrace.getExceptionLine(),
                  CoreMatchers.containsString("<" + throwLocation + "-exception>"));
              switch (throwLocation) {
                case FOO1:
                  assertThat(
                      retracedStackTrace,
                      StackTrace.isSame(
                          StackTrace.builder()
                              .add(line("foo", Location.FOO1, foo1Pos))
                              .add(line("main", Location.MAIN, mainPos))
                              .build()));
                  break;
                case BAR:
                  assertThat(
                      retracedStackTrace,
                      StackTrace.isSame(
                          StackTrace.builder()
                              .add(line("bar", Location.BAR, barPos))
                              .add(line("foo", Location.FOO1, foo1Pos))
                              .add(line("main", Location.MAIN, mainPos))
                              .build()));
                  break;
                case FOO2:
                  assertThat(
                      retracedStackTrace,
                      StackTrace.isSame(
                          StackTrace.builder()
                              .add(
                                  line(
                                      "foo",
                                      foo2Pos ? Location.FOO2 : Location.FOO1,
                                      foo2Pos || foo1Pos))
                              .add(line("main", Location.MAIN, mainPos))
                              .build()));
                  break;
                default:
                  fail();
              }
            });
  }

  private StackTraceLine line(String methodName, Location location, boolean hasPosition) {
    return StackTraceLine.builder()
        .setClassName(TEST_CLASS)
        .setFileName(TEST_FILE)
        .setMethodName(methodName)
        .setLineNumber(hasPosition ? location.line : 0)
        .build();
  }
}
