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

import static com.android.tools.r8.utils.codeinspector.Matchers.isPresent;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.NeverInline;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
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.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.InstructionSubject;
import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.Streams;
import org.junit.Ignore;
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 RedundantConstNumberRemovalTest extends TestBase {

  private final Backend backend;

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

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

  @Test
  @Ignore("b/123284765")
  public void test() throws Exception {
    String expectedOutput =
        StringUtils.lines(
            "true", "true", "true", "true", "true", "true", "true", "true", "true", "true", "true",
            "true", "true", "true", "true", "true");

    if (backend == Backend.CF) {
      testForJvm().addTestClasspath().run(TestClass.class).assertSuccessWithOutput(expectedOutput);
    }

    R8TestRunResult result =
        testForR8(backend)
            .addInnerClasses(RedundantConstNumberRemovalTest.class)
            .addKeepMainRule(TestClass.class)
            .enableInliningAnnotations()
            .run(TestClass.class)
            .assertSuccessWithOutput(expectedOutput);

    ClassSubject classSubject = result.inspector().clazz(TestClass.class);
    verifyBooleanCheckTest(classSubject.uniqueMethodWithName("booleanCheckTest"));
    verifyBooleanCheckTest(classSubject.uniqueMethodWithName("negateBooleanCheckTest"));
    verifyIntCheckTest(classSubject.uniqueMethodWithName("intCheckTest"));
    verifyIntCheckTest(classSubject.uniqueMethodWithName("negateIntCheckTest"));
    verifyNullCheckTest(classSubject.uniqueMethodWithName("nullCheckTest"));
    verifyNullCheckTest(classSubject.uniqueMethodWithName("invertedNullCheckTest"));
    verifyNullCheckTest(classSubject.uniqueMethodWithName("nonNullCheckTest"));
    verifyNullCheckWithWrongTypeTest(
        classSubject.uniqueMethodWithName("nullCheckWithWrongTypeTest"));
  }

  private void verifyBooleanCheckTest(MethodSubject methodSubject) {
    assertThat(methodSubject, isPresent());

    if (backend == Backend.DEX) {
      // Check that the generated code for booleanCheckTest() only has a return instruction.
      assertEquals(1, methodSubject.streamInstructions().count());
      assertTrue(methodSubject.iterateInstructions().next().isReturn());
    } else {
      assert backend == Backend.CF;
      // Check that the generated code for booleanCheckTest() only has return instructions that
      // return the argument.
      // TODO(christofferqa): CF backend does not share identical prefix of successors.
      IRCode code = methodSubject.buildIR();
      assertTrue(
          Streams.stream(code.instructionIterator())
              .filter(Instruction::isReturn)
              .allMatch(
                  instruction -> instruction.asReturn().returnValue().definition.isArgument()));
    }
  }

  private void verifyIntCheckTest(MethodSubject methodSubject) {
    assertThat(methodSubject, isPresent());
    IRCode code = methodSubject.buildIR();

    if (backend == Backend.DEX) {
      // Only a single basic block.
      assertEquals(1, code.blocks.size());
      // The block only has three instructions.
      BasicBlock entryBlock = code.entryBlock();
      assertEquals(3, entryBlock.getInstructions().size());
      // The first one is the `argument` instruction.
      Instruction argument = entryBlock.getInstructions().getFirst();
      assertTrue(argument.isArgument());
      // The next one is a `const-number` instruction is not used for anything.
      // TODO(christofferqa): D8 should be able to get rid of the unused const-number instruction.
      Instruction unused = entryBlock.getInstructions().get(1);
      assertTrue(unused.isConstNumber());
      assertEquals(0, unused.outValue().numberOfAllUsers());
      // The `return` instruction returns the argument.
      Instruction ret = entryBlock.getInstructions().getLast();
      assertTrue(ret.isReturn());
      assertTrue(ret.asReturn().returnValue().definition.isArgument());
    } else {
      // Check that the generated code for intCheckTest() only has return instructions that
      // return the argument.
      // TODO(christofferqa): CF backend does not share identical prefix of successors.
      assertTrue(
          Streams.stream(code.instructionIterator())
              .filter(Instruction::isReturn)
              .allMatch(
                  instruction -> instruction.asReturn().returnValue().definition.isArgument()));
    }
  }

  private void verifyNullCheckTest(MethodSubject methodSubject) {
    // Check that the generated code for nullCheckTest() only has a single `const-null` instruction.
    assertThat(methodSubject, isPresent());
    assertEquals(
        1, methodSubject.streamInstructions().filter(InstructionSubject::isConstNull).count());

    // Also check that one of the return instructions actually returns the argument.
    IRCode code = methodSubject.buildIR();
    assertEquals(1, code.collectArguments().size());
    // TODO(b/120257211): D8 should replace `return null` by `return arg`.
    assertFalse(
        code.collectArguments().get(0).uniqueUsers().stream().anyMatch(Instruction::isReturn));
  }

  private void verifyNullCheckWithWrongTypeTest(MethodSubject methodSubject) {
    // Check that the generated code for nullCheckWithWrongTypeTest() still has a `return null`
    // instruction.
    assertThat(methodSubject, isPresent());
    IRCode code = methodSubject.buildIR();

    // Check that the code returns null.
    assertTrue(
        Streams.stream(code.instructionIterator())
            .anyMatch(
                instruction ->
                    instruction.isReturn()
                        && instruction.asReturn().returnValue().definition.isConstNumber()));

    // Also check that none of the return instructions actually returns the argument.
    assertEquals(1, code.collectArguments().size());
    assertTrue(
        code.collectArguments().get(0).uniqueUsers().stream().noneMatch(Instruction::isReturn));
  }

  static class TestClass {

    public static void main(String[] args) {
      System.out.println(booleanCheckTest(true) == true);
      System.out.println(booleanCheckTest(false) == false);
      System.out.println(negateBooleanCheckTest(true) == true);
      System.out.println(negateBooleanCheckTest(false) == false);
      System.out.println(intCheckTest(0) == 0);
      System.out.println(intCheckTest(42) == 42);
      System.out.println(negateIntCheckTest(0) == 0);
      System.out.println(negateIntCheckTest(42) == 42);
      System.out.println(nullCheckTest(new Object()) != null);
      System.out.println(nullCheckTest(null) == null);
      System.out.println(invertedNullCheckTest(new Object()) != null);
      System.out.println(invertedNullCheckTest(null) == null);
      System.out.println(nonNullCheckTest(new Object()) != null);
      System.out.println(nonNullCheckTest(null) == null);
      System.out.println(nullCheckWithWrongTypeTest(new Object()) != null);
      System.out.println(nullCheckWithWrongTypeTest(null) == null);
    }

    @NeverInline
    private static boolean booleanCheckTest(boolean x) {
      if (x) {
        return true; // should be replaced by `x`.
      }
      return false; // should be replaced by `x`.
    }

    @NeverInline
    private static boolean negateBooleanCheckTest(boolean x) {
      if (!x) {
        return false; // should be replaced by `x`
      }
      return true; // should be replaced by `x`
    }

    @NeverInline
    private static int intCheckTest(int x) {
      if (x == 42) {
        return 42; // should be replaced by `x`.
      }
      return x;
    }

    @NeverInline
    private static int negateIntCheckTest(int x) {
      if (x != 42) {
        return x;
      }
      return 42; // should be replaced by `x`
    }

    @NeverInline
    private static Object nullCheckTest(Object x) {
      if (x != null) {
        return new Object();
      }
      return null; // should be replaced by `x`.
    }

    @NeverInline
    private static Object invertedNullCheckTest(Object x) {
      if (null == x) {
        return null; // should be replaced by `x`.
      }
      return new Object();
    }

    @NeverInline
    private static Object nonNullCheckTest(Object x) {
      if (x == null) {
        return null; // should be replaced by `x`
      }
      return new Object();
    }

    @NeverInline
    private static Throwable nullCheckWithWrongTypeTest(Object x) {
      if (x != null) {
        return new Throwable();
      }
      return null; // cannot be replaced by `x` because Object is not a subtype of Throwable.
    }
  }
}
