// 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;

import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
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.ir.code.LinearFlowInstructionListIterator;
import com.android.tools.r8.jasmin.JasminBuilder;
import com.android.tools.r8.jasmin.JasminBuilder.ClassBuilder;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.util.ListIterator;
import org.junit.Test;

public class LinearFlowIteratorTest extends TestBase {

  private IRCode branchingCode() throws Exception {

    JasminBuilder jasminBuilder = new JasminBuilder();

    ClassBuilder clazz = jasminBuilder.addClass("foo");
    clazz.addStaticMethod(
        "bar",
        ImmutableList.of("I"),
        "V",
        ".limit stack 2",
        ".limit locals 2",
        ".var 1 is x Ljava/lang/Object; from L1 to L2",
        "  aconst_null",
        "  astore 1",
        "L1:",
        "  iload 0",
        "  ifeq L3",
        "L2:",
        "  goto L5",
        "L3:",
        "  aload 1",
        "  iconst_0",
        "  aaload",
        "  pop",
        "L5:",
        "  return");
    AndroidApp.Builder appBuilder = AndroidApp.builder();
    appBuilder.addClassProgramData(jasminBuilder.buildClasses());

    // Build the code, and split the code into three blocks.
    AndroidApp app = compileWithD8(appBuilder.build());
    MethodSubject methodSubject =
        getMethodSubject(app, "foo", "void", "bar", ImmutableList.of("int"));
    IRCode code = methodSubject.buildIR();
    ListIterator<BasicBlock> blocks = code.listIterator();
    blocks.next();
    InstructionListIterator iter = blocks.next().listIterator(code);
    iter.nextUntil(i -> !i.isConstNumber());
    iter.previous();
    iter.split(code, blocks);
    return code;
  }

  private IRCode simpleCode() throws Exception {

    JasminBuilder jasminBuilder = new JasminBuilder();

    ClassBuilder clazz = jasminBuilder.addClass("foo");
    clazz.addStaticMethod(
        "bar",
        ImmutableList.of("I"),
        "V",
        ".limit stack 2",
        ".limit locals 2",
        ".var 0 is x I from L1 to L2",
        "L1:",
        "  aconst_null",
        "  iload 0",
        "  aaload",
        "  pop",
        "L2:",
        "  return");
    AndroidApp.Builder appBuilder = AndroidApp.builder();
    appBuilder.addClassProgramData(jasminBuilder.buildClasses());

    // Build the code, and split the code into three blocks.
    AndroidApp app = compileWithD8(appBuilder.build());
    MethodSubject method = getMethodSubject(app, "foo", "void", "bar", ImmutableList.of("int"));
    IRCode code = method.buildIR();
    ListIterator<BasicBlock> blocks = code.listIterator();
    InstructionListIterator iter = blocks.next().listIterator(code);
    iter.nextUntil(i -> !i.isArgument());
    iter.split(code, 0, blocks);
    return code;
  }

  @Test
  public void hasNextWillCheckNextBlock() throws Exception {
    IRCode code = simpleCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.entryBlock());
    it.next();
    it.next();
    assert it.hasNext();
  }

  @Test
  public void nextWillContinueThroughGotoBlocks() throws Exception {
    IRCode code = simpleCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.entryBlock());
    it.next(); // Argument
    it.next(); // ConstNumber 0/NULL
    it.next(); // ArrayGet
    assert it.next().isReturn(); // Return
  }

  @Test
  public void hasPreviousWillCheckPreviousBlock() throws Exception {
    IRCode code = simpleCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.blocks.get(2));
    assert it.hasPrevious();
  }

  @Test
  public void hasPreviousWillJumpOverGotos() throws Exception {
    IRCode code = simpleCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.blocks.get(2));
    assert it.previous().isConstNumber();
  }

  @Test
  public void GoToFrontAndBackIsSameAmountOfInstructions() throws Exception {
    IRCode code = simpleCode();
    int moves = 0;
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.entryBlock());
    while (it.hasNext()) {
      it.next();
      moves++;
    }
    Instruction current = null;
    for (int i = 0; i < moves; i++) {
      current = it.previous();
    }
    assert !it.hasPrevious();
    assert current.isArgument();
  }

  @Test
  public void moveFromEmptyBlock() throws Exception {
    IRCode code = simpleCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.blocks.get(1));
    Instruction current = it.previous();
    assertTrue(current.isConstNumber() && current.outValue().getTypeLattice().isReference());
    it.next();
    current = it.next();
    assertTrue(current.isArrayGet());
  }

  @Test
  public void doNotChangeToNextBlockWhenNotLinearFlow() throws Exception {
    IRCode code = branchingCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.entryBlock());
    it.nextUntil((i) -> !i.isArgument());
    it.next();
    assert !it.hasNext();
  }

  @Test
  public void doNotChangeToPreviousBlockWhenNotLinearFlow() throws Exception {
    IRCode code = branchingCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.blocks.get(4));
    assert !it.hasPrevious();
  }

  @Test
  public void followLinearSubPathDown() throws Exception {
    IRCode code = branchingCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.blocks.get(1));
    Instruction current = null;
    while (it.hasNext()) {
      current = it.next();
    }
    assert current.isGoto();
  }

  @Test
  public void followLinearSubPathUp() throws Exception {
    IRCode code = branchingCode();
    InstructionListIterator it = new LinearFlowInstructionListIterator(code, code.blocks.get(2));
    Instruction current = null;
    while (it.hasPrevious()) {
      current = it.previous();
    }
    assert current.isConstNumber();
  }
}
