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

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNot.not;
import static org.junit.Assert.assertEquals;

import com.android.tools.r8.ForceInline;
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.cf.code.CfTryCatch;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexCode.TryHandler;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
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 SubsumedCatchHandlerTest extends TestBase {

  static class TestClass {

    public static void main(String[] args) {
      int exitCode = 0;
      try {
        exitCode = foo();
      } catch (RuntimeException e) {
        // This catch handler will be subsumed by the catch handler in foo() after inlining.
        handleCaughtRuntimeException();
      }
      System.out.print(" -> " + exitCode);
    }

    @ForceInline
    private static int foo() {
      try {
        bar();
      } catch (Exception e) {
        // No statements with side-effects here; otherwise this block will be guarded by the
        // RuntimeException catch handler from main().
        return 1;
      }
      return 0;
    }

    @NeverInline
    private static void bar() {
      System.out.print("In bar()");
    }

    @NeverInline
    private static void handleCaughtRuntimeException() {
      System.out.print("In handleCaughtRuntimeException()");
    }
  }

  @Parameters(name = "Backend: {0}")
  public static Backend[] data() {
    return ToolHelper.getBackends();
  }

  private final Backend backend;

  public SubsumedCatchHandlerTest(Backend backend) {
    this.backend = backend;
  }

  @Test
  public void test() throws Exception {
    String expected = "In bar() -> 0";

    testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expected);

    CodeInspector inspector =
        testForR8(backend)
            .addInnerClasses(SubsumedCatchHandlerTest.class)
            .addKeepMainRule(TestClass.class)
            .enableForceInliningAnnotations()
            .enableInliningAnnotations()
            .run(TestClass.class)
            .assertSuccessWithOutput(expected)
            .inspector();

    ClassSubject classSubject = inspector.clazz(TestClass.class);
    assertThat(classSubject, isPresent());
    assertThat(classSubject.method("void", "handleCaughtRuntimeException"), not(isPresent()));

    MethodSubject mainMethodSubject = classSubject.mainMethod();
    Code code = mainMethodSubject.getMethod().getCode();
    if (code.isDexCode()) {
      DexCode dexCode = code.asDexCode();
      assertEquals(1, dexCode.handlers.length);

      TryHandler handler = dexCode.handlers[0];
      assertEquals(1, handler.pairs.length);

      DexType guard = handler.pairs[0].getType();
      assertEquals("java.lang.Exception", guard.toSourceString());
    } else {
      assert code.isCfCode();
      CfCode cfCode = code.asCfCode();
      assertEquals(1, cfCode.getTryCatchRanges().size());

      CfTryCatch handler = cfCode.getTryCatchRanges().get(0);
      assertEquals(1, handler.guards.size());

      DexType guard = handler.guards.get(0);
      assertEquals("java.lang.Exception", guard.toSourceString());
    }
  }
}
