// 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.isAbsent;
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.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);
    }

    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)
            .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());
    }

    assertThat(classSubject.uniqueMethodWithName("foo"), isAbsent());
  }
}
