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

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.ir.code.Argument;
import com.android.tools.r8.ir.code.BasicBlock;
import com.android.tools.r8.ir.code.IRCode;
import com.android.tools.r8.ir.code.InstanceGet;
import com.android.tools.r8.ir.code.Phi;
import com.android.tools.r8.ir.code.Phi.RegisterReadType;
import com.android.tools.r8.ir.code.Value;
import com.android.tools.r8.ir.optimize.Inliner.Reason;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;

// This is a reproduction of b/178608910.
@RunWith(Parameterized.class)
public class ClassInlinerPhiDirectUserAfterInlineTest extends TestBase {

  private final TestParameters parameters;
  private final List<String> EXPECTED = ImmutableList.of("0", "A::baz");

  @Parameters(name = "{0}")
  public static TestParametersCollection data() {
    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
  }

  public ClassInlinerPhiDirectUserAfterInlineTest(TestParameters parameters) {
    this.parameters = parameters;
  }

  @Test
  public void testNoClassInlining() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(getClass())
        .setMinApi(parameters.getApiLevel())
        .addKeepMainRule(Main.class)
        .addOptionsModification(
            options -> {
              options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
              // Here we modify the IR when it is processed normally.
              options.testing.irModifier = this::modifyIr;
              options.enableClassInlining = false;
            })
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(EXPECTED);
  }

  @Test
  public void testR8() throws Exception {
    testForR8(parameters.getBackend())
        .addInnerClasses(getClass())
        .setMinApi(parameters.getApiLevel())
        .addKeepMainRule(Main.class)
        .addOptionsModification(
            options -> {
              options.testing.validInliningReasons = ImmutableSet.of(Reason.FORCE);
              options.testing.inlineeIrModifier = this::modifyIr;
            })
        .run(parameters.getRuntime(), Main.class)
        .assertSuccessWithOutputLines(EXPECTED)
        .inspect(
            inspector -> {
              // Assert that the A has been class-inlined into the caller.
              ClassSubject aSubject = inspector.clazz(A.class);
              assertThat(aSubject, not(isPresent()));
            });
  }

  private void modifyIr(IRCode irCode) {
    if (irCode.context().getReference().qualifiedName().equals(A.class.getTypeName() + ".foo")) {
      assertEquals(7, irCode.blocks.size());
      // This is the code that we expect
      // <pre>
      // blocks:
      // block 0, pred-counts: 0, succ-count: 1, filled: true, sealed: true
      // predecessors: -
      // successors: 1  (no try/catch successors)
      // no phis
      //  #0:foo;0:main: -1: Argument             v3 <-
      //               : -1: ConstNumber          v4(0) <-  0 (INT)
      //               : -1: Goto                 block 1
      //
      // block 1, pred-counts: 2, succ-count: 2, filled: true, sealed: true
      // predecessors: 0 5
      // successors: 2 3  (no try/catch successors)
      // v7 <- phi(v4(0), v13) : INT
      //  #0:foo;0:main: -1: InstanceGet          v6 <- v3; field: int
      // com.android.tools.r8.ir.optimize.classinliner
      //    .ClassInlinerPhiDirectUserAfterInlineTest$A.number
      //               : -1: If                   v6 EQZ block 2 (fallthrough 3)
      //
      // block 2, pred-counts: 1, succ-count: 0, filled: true, sealed: true
      // predecessors: 1
      // successors: -
      // no phis
      //  #0:foo;0:main: -1: Invoke-Virtual       v3, v7; method: void
      // com.android.tools.r8.ir.optimize.classinliner
      //  .ClassInlinerPhiDirectUserAfterInlineTest$A.bar(int)
      //               : -1: Return
      //
      // block 3, pred-counts: 1, succ-count: 1, filled: true, sealed: true
      // predecessors: 1
      // successors: 4  (no try/catch successors)
      // no phis
      //  #0:foo;0:main: -1: ConstNumber          v8(2) <-  2 (INT)
      //               : -1: Add                  v9 <- v7, v8(2)
      //               : -1: Goto                 block 4
      //
      // block 4, pred-counts: 2, succ-count: 2, filled: true, sealed: true
      // predecessors: 3 6
      // successors: 5 6  (no try/catch successors)
      // v13 <- phi(v9, v15) : INT
      //  #0:foo;0:main: -1: InstanceGet          v11 <- v3; field: int
      // com.android.tools.r8.ir.optimize.classinliner
      //  .ClassInlinerPhiDirectUserAfterInlineTest$A.number
      //               : -1: ConstNumber          v12(10) <-  10 (INT)
      //               : -1: If                   v11, v12(10) LE  block 5
      // (fallthrough 6)
      //
      // block 5, pred-counts: 1, succ-count: 1, filled: true, sealed: true
      // predecessors: 4
      // successors: 1  (no try/catch successors)
      // no phis
      //  #0:foo;0:main: -1: Goto                 block 1
      //
      // block 6, pred-counts: 1, succ-count: 1, filled: true, sealed: true
      // predecessors: 4
      // successors: 4  (no try/catch successors)
      // no phis
      //  #0:foo;0:main: -1: ConstNumber          v14(3) <-  3 (INT)
      //               : -1: Add                  v15 <- v13, v14(3)
      //               : -1: ConstNumber          v16(-1) <-  -1 (INT)
      //               : -1: Add                  v17 <- v11, v16(-1)
      //               : -1: InstancePut          v3, v17; field: int
      // com.android.tools.r8.ir.optimize.classinliner
      //  .ClassInlinerPhiDirectUserAfterInlineTest$A.number
      //               : -1: Goto                 block 4
      // </pre>
      // We modify block 1 to have:
      // vX : phi(v3, vY)
      // .. InstanceGet       vX ...
      //
      // and block 4 to have:
      // vY : phi(v3, vX)
      BasicBlock basicBlock = irCode.blocks.get(0);
      Argument argument = basicBlock.getInstructions().get(0).asArgument();
      assertNotNull(argument);
      Value argumentValue = argument.outValue();

      BasicBlock block1 = irCode.blocks.get(1);
      assertTrue(block1.exit().isIf());

      BasicBlock block3 = irCode.blocks.get(3);
      assertTrue(block1.getSuccessors().contains(block3));
      assertTrue(block3.exit().isGoto());

      BasicBlock block4 = irCode.blocks.get(4);
      assertSame(block3.getUniqueNormalSuccessor(), block4);

      Phi firstPhi =
          new Phi(
              irCode.valueNumberGenerator.next(),
              block1,
              argumentValue.getType(),
              null,
              RegisterReadType.NORMAL);

      Phi secondPhi =
          new Phi(
              irCode.valueNumberGenerator.next(),
              block4,
              argumentValue.getType(),
              null,
              RegisterReadType.NORMAL);

      firstPhi.addOperands(ImmutableList.of(argumentValue, secondPhi));
      secondPhi.addOperands(ImmutableList.of(argumentValue, firstPhi));

      // Replace the invoke to use the phi
      InstanceGet instanceGet = block1.getInstructions().get(0).asInstanceGet();
      assertNotNull(instanceGet);
      assertEquals(A.class.getTypeName(), instanceGet.getField().holder.toSourceString());
      instanceGet.replaceValue(0, firstPhi);
    }
  }

  public static class A {

    int number = 0;

    public void foo() {
      int otherNumber = 0;
      while (number != 0) {
        otherNumber += 2;
        while (number > 10) {
          otherNumber += 3;
          number--;
        }
      }
      bar(otherNumber);
    }

    public void bar(int number) {
      System.out.println(number + "");
    }

    public void baz() {
      System.out.println("A::baz");
    }
  }

  public static class Main {

    public static void main(String[] args) {
      A a = new A();
      a.number = args.length;
      a.foo();
      a.baz();
    }
  }
}
