// Copyright (c) 2021, 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.desugar.lambdas;

import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ToolHelper.DexVm.Version;
import com.android.tools.r8.utils.StringUtils;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

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

  static final String fileName = "LambdaInStacktraceTest.java";

  static final String EXPECTED_JAVAC =
      StringUtils.lines(
          "getStacktraceWithFileNames(" + fileName + ")",
          "lambda$main$0(" + fileName + ")",
          "main(" + fileName + ")",
          "getStacktraceWithFileNames(" + fileName + ")",
          "lambda$main$1(" + fileName + ")",
          "main(" + fileName + ")");

  // TODO(b/187491007): The "call" frame should have a file name.
  static final String EXPECTED_D8 =
      StringUtils.lines(
          "getStacktraceWithFileNames(" + fileName + ")",
          "lambda$main$0(" + fileName + ")",
          "call(D8$$SyntheticClass)",
          "main(" + fileName + ")",
          "getStacktraceWithFileNames(" + fileName + ")",
          "lambda$main$1(" + fileName + ")",
          "call(D8$$SyntheticClass)",
          "main(" + fileName + ")");

  static final String EXPECTED_D8_ANDROID_O =
      StringUtils.lines(
          "getStacktraceWithFileNames(" + fileName + ")",
          "lambda$main$0(" + fileName + ")",
          "call(NULL)",
          "main(" + fileName + ")",
          "getStacktraceWithFileNames(" + fileName + ")",
          "lambda$main$1(" + fileName + ")",
          "call(NULL)",
          "main(" + fileName + ")");

  private final TestParameters parameters;
  private final boolean isAndroidOOrLater;
  private final boolean isDalvik;

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withAllRuntimes().withAllApiLevelsAlsoForCf().build();
  }

  public LambdaInStacktraceTest(TestParameters parameters) {
    this.parameters = parameters;
    isDalvik = parameters.isDexRuntime() && parameters.getDexRuntimeVersion().isDalvik();
    isAndroidOOrLater =
        parameters.isDexRuntime()
            && parameters.getDexRuntimeVersion().isNewerThanOrEqual(Version.V8_1_0);
  }

  @Test
  public void testJvm() throws Exception {
    assumeTrue("Only run JVM reference on CF runtimes", parameters.isCfRuntime());
    testForJvm()
        .addInnerClasses(LambdaInStacktraceTest.class)
        .run(parameters.getRuntime(), TestRunner.class, Boolean.toString(false))
        .assertSuccess()
        .assertSuccessWithOutput(EXPECTED_JAVAC);
  }

  @Test
  public void testD8() throws Exception {
    testForD8(parameters.getBackend())
        .addInnerClasses(LambdaInStacktraceTest.class)
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), TestRunner.class, Boolean.toString(isDalvik))
        .assertSuccessWithOutput(isAndroidOOrLater ? EXPECTED_D8_ANDROID_O : EXPECTED_D8);
  }

  @Test
  public void testR8() throws Exception {
    assumeTrue(parameters.getRuntime().isDex());
    String stdout =
        testForR8(parameters.getBackend())
            .addInnerClasses(LambdaInStacktraceTest.class)
            .setMinApi(parameters.getApiLevel())
            .addKeepMainRule(TestRunner.class)
            .addKeepAttributeSourceFile()
            .addKeepRules("-renamesourcefileattribute SourceFile")
            .noTreeShaking()
            .run(parameters.getRuntime(), TestRunner.class, Boolean.toString(isDalvik))
            .assertSuccess()
            .getStdOut();
    assertTrue(
        StringUtils.splitLines(stdout).stream()
            .allMatch(s -> s.contains(isAndroidOOrLater ? "NULL" : "SourceFile")));
  }

  static class TestRunner {

    public static List<String> getStacktraceWithFileNames(boolean isDalvik) {
      Throwable stackTrace = new RuntimeException().fillInStackTrace();

      // Dalvik has an additional "main(NativeStart.java)" bottom frame.
      List<String> frames = new ArrayList<>();
      for (int i = 0; i < stackTrace.getStackTrace().length - (isDalvik ? 1 : 0); i++) {
        StackTraceElement stackTraceElement = stackTrace.getStackTrace()[i];
        String fileName = stackTraceElement.getFileName();
        frames.add(
            stackTraceElement.getMethodName() + "(" + (fileName != null ? fileName : "NULL") + ")");
      }
      return frames;
    }

    public static void main(String[] args) throws Exception {
      boolean isDalvik = Boolean.parseBoolean(args[0]);
      Callable<List<String>> callable = () -> getStacktraceWithFileNames(isDalvik);
      System.out.println(String.join(System.lineSeparator(), callable.call()));

      Callable<Callable<List<String>>> callableNested =
          () -> () -> getStacktraceWithFileNames(isDalvik);
      System.out.println(String.join(System.lineSeparator(), callableNested.call().call()));
    }
  }
}
