// 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.ir.optimize.outliner;

import static org.junit.Assert.assertEquals;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.NoHorizontalClassMerging;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.naming.retrace.StackTrace;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.codeinspector.HorizontallyMergedClassesInspector;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;

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

  @Parameter(0)
  public TestParameters parameters;

  @Parameter(1)
  public boolean throwInFirstOutline;

  @Parameter(2)
  public boolean throwOnFirstCall;

  @Parameterized.Parameters(name = "{0}, throwInFirstOutline: {1}, throwOnFirstCall: {2}")
  public static List<Object[]> data() {
    return buildParameters(
        getTestParameters().withAllRuntimesAndApiLevels().build(),
        BooleanUtils.values(),
        BooleanUtils.values());
  }

  StackTrace expectedStackTrace;

  @Before
  public void setup() throws Exception {
    expectedStackTrace =
        testForRuntime(parameters)
            .addProgramClasses(TestClass.class, TestClass2.class, Greeter.class)
            .run(
                parameters.getRuntime(),
                TestClass.class,
                throwInFirstOutline ? "0" : "1",
                throwOnFirstCall ? "0" : "1")
            .assertFailureWithErrorThatThrows(ArrayStoreException.class)
            .getStackTrace();
  }

  @Test
  public void test() throws Exception {
    testForR8(parameters.getBackend())
        .addProgramClasses(TestClass.class, TestClass2.class, Greeter.class)
        .addKeepMainRule(TestClass.class)
        .addOptionsModification(
            options -> {
              options.outline.threshold = 2;
              options.outline.minSize = 2;
            })
        .addKeepAttributeLineNumberTable()
        .addKeepAttributeSourceFile()
        .enableNoHorizontalClassMergingAnnotations()
        .noHorizontalClassMergingOfSynthetics()
        .addHorizontallyMergedClassesInspector(
            HorizontallyMergedClassesInspector::assertNoClassesMerged)
        .enableInliningAnnotations()
        .setMinApi(parameters.getApiLevel())
        .enableExperimentalMapFileVersion()
        .compile()
        .run(
            parameters.getRuntime(),
            TestClass.class,
            throwInFirstOutline ? "0" : "1",
            throwOnFirstCall ? "0" : "1")
        .assertFailureWithErrorThatThrows(ArrayStoreException.class)
        .inspectStackTrace(
            (stackTrace, inspector) -> {
              // Two outlines are created, one for
              //   Greeter.throwExceptionFirst();
              //   Greeter.throwExceptionSecond();
              // and one for
              //   new ArrayStoreException("Foo")
              assertEquals(5, inspector.allClasses().size());
              assertEquals(expectedStackTrace, stackTrace);
            });
  }

  @NoHorizontalClassMerging
  static class TestClass {

    public static boolean shouldThrowInGreeter;
    public static boolean throwOnFirst;

    public static void main(String... args) {
      shouldThrowInGreeter = args[0].equals("0");
      throwOnFirst = args[1].equals("0");
      greet();
      shouldThrowInGreeter = true;
      TestClass2.greet();
    }

    @NeverInline
    static void greet() {
      Greeter.throwExceptionFirst();
      inlinee();
    }

    static void inlinee() {
      Greeter.throwExceptionSecond();
    }
  }

  @NoHorizontalClassMerging
  static class TestClass2 {

    @NeverInline
    static void greet() {
      // Keep on same line
      inlinee(); Greeter.throwExceptionSecond();
    }

    static void inlinee() {
      Greeter.throwExceptionFirst();
    }
  }

  @NoHorizontalClassMerging
  public static class Greeter {

    @NeverInline
    public static void throwExceptionFirst() {
      if (TestClass.shouldThrowInGreeter && TestClass.throwOnFirst) {
        throw new ArrayStoreException("Foo");
      }
    }

    @NeverInline
    public static void throwExceptionSecond() {
      if (TestClass.shouldThrowInGreeter && !TestClass.throwOnFirst) {
        throw new ArrayStoreException("Foo");
      }
    }
  }
}
