// Copyright (c) 2019, 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.cf;

import static org.junit.Assert.assertTrue;

import com.android.tools.r8.CompilationMode;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.cf.code.CfInvoke;
import com.android.tools.r8.cf.code.CfLabel;
import com.android.tools.r8.cf.code.CfLoad;
import com.android.tools.r8.cf.code.CfStackInstruction;
import com.android.tools.r8.graph.CfCode;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.Instruction;
import com.android.tools.r8.ir.code.InstructionListIterator;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import java.util.List;
import org.junit.Test;

/**
 * This tests that we produce valid code when having normal-flow with exceptional edges in blocks.
 * We might perform optimizations that add operations (dup, swap, etc.) before and after
 * instructions that lie on the boundary of the exception table that is generated for a basic block.
 * If live-ranges are minimized this could produce VerifyErrors.
 */
public class TryRangeTestRunner extends TestBase {

  @Test
  public void testRegisterAllocationLimitTrailingRange() throws Exception {
    testForR8(Backend.CF)
        .addProgramClasses(TryRangeTest.class)
        .addKeepMainRule(TryRangeTest.class)
        .setMode(CompilationMode.RELEASE)
        .noMinification()
        .noTreeShaking()
        .enableInliningAnnotations()
        .addOptionsModification(o -> o.enableLoadStoreOptimization = false)
        .run(TryRangeTest.class)
        .assertSuccessWithOutput(StringUtils.lines("10", "7.0"));
  }

  @Test
  public void testRegisterAllocationLimitLeadingRange() throws Exception {
    CodeInspector inspector =
        testForR8(Backend.CF)
            .addProgramClasses(TryRangeTestLimitRange.class)
            .addKeepMainRule(TryRangeTestLimitRange.class)
            .setMode(CompilationMode.RELEASE)
            .noMinification()
            .noTreeShaking()
            .enableInliningAnnotations()
            .addOptionsModification(
                o -> {
                  o.enableLoadStoreOptimization = false;
                  o.testing.irModifier = this::processIR;
                })
            .run(TryRangeTestLimitRange.class)
            .assertSuccessWithOutput("")
            .inspector();
    // Assert that we do not have any register-modifying instructions in the throwing block:
    // L0: ; locals:
    // iload 1;
    // invokestatic com.android.tools.r8.cf.TryRangeTestLimitRange.doSomething(I)F
    // L1: ; locals:
    // 11:   pop
    ClassSubject clazz = inspector.clazz("com.android.tools.r8.cf.TryRangeTestLimitRange");
    CfCode cfCode = clazz.uniqueMethodWithName("main").getMethod().getCode().asCfCode();
    List<CfInstruction> instructions = cfCode.getInstructions();
    CfLabel startLabel = cfCode.getTryCatchRanges().get(0).start;
    int index = 0;
    while (instructions.get(index) != startLabel) {
      index++;
    }
    assert instructions.get(index + 1) instanceof CfLoad;
    assert instructions.get(index + 2) instanceof CfInvoke;
    assert instructions.get(index + 3) == cfCode.getTryCatchRanges().get(0).end;
    assert instructions.get(index + 4) instanceof CfStackInstruction;
  }

  private void processIR(IRCode code) {
    if (!code.method().qualifiedName().equals(TryRangeTestLimitRange.class.getName() + ".main")) {
      return;
    }
    BasicBlock entryBlock = code.entryBlock();
    BasicBlock tryBlock = code.blocks.get(1);
    assertTrue(tryBlock.hasCatchHandlers());
    InstructionListIterator it = entryBlock.listIterator(code);
    Instruction constNumber = it.next();
    while (!constNumber.isConstNumber()) {
      constNumber = it.next();
    }
    it.removeInstructionIgnoreOutValue();
    Instruction add = it.next();
    while (!add.isAdd()) {
      add = it.next();
    }
    it.removeInstructionIgnoreOutValue();
    constNumber.setBlock(tryBlock);
    add.setBlock(tryBlock);
    tryBlock.getInstructions().add(0, add);
    tryBlock.getInstructions().add(0, constNumber);
  }
}
