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

import static com.android.tools.r8.utils.codeinspector.Matchers.isAbsent;
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.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.R8TestRunResult;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.dex.code.DexInstruction;
import com.android.tools.r8.dex.code.DexInvokeDirect;
import com.android.tools.r8.dex.code.DexInvokeStatic;
import com.android.tools.r8.dex.code.DexInvokeVirtual;
import com.android.tools.r8.dex.code.DexSgetObject;
import com.android.tools.r8.dex.code.DexSputObject;
import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.optimize.staticizer.dualcallinline.Candidate;
import com.android.tools.r8.ir.optimize.staticizer.dualcallinline.DualCallTest;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.CandidateConflictField;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.CandidateConflictMethod;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.CandidateOk;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.CandidateOkFieldOnly;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.CandidateOkSideEffects;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.HostConflictField;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.HostConflictMethod;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.HostOk;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.HostOkFieldOnly;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.HostOkSideEffects;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.MoveToHostFieldOnlyTestClass;
import com.android.tools.r8.ir.optimize.staticizer.movetohost.MoveToHostTestClass;
import com.android.tools.r8.ir.optimize.staticizer.trivial.Simple;
import com.android.tools.r8.ir.optimize.staticizer.trivial.SimpleWithGetter;
import com.android.tools.r8.ir.optimize.staticizer.trivial.SimpleWithLazyInit;
import com.android.tools.r8.ir.optimize.staticizer.trivial.SimpleWithParams;
import com.android.tools.r8.ir.optimize.staticizer.trivial.SimpleWithPhi;
import com.android.tools.r8.ir.optimize.staticizer.trivial.SimpleWithSideEffects;
import com.android.tools.r8.ir.optimize.staticizer.trivial.SimpleWithThrowingGetter;
import com.android.tools.r8.ir.optimize.staticizer.trivial.TrivialTestClass;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.Lists;
import com.google.common.collect.Streams;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ClassStaticizerTest extends TestBase {
  private final TestParameters parameters;

  private static final String EXPECTED =
      StringUtils.lines(
          "Simple::bar(Simple::foo())",
          "Simple::bar(0)",
          "SimpleWithPhi$Companion::bar(SimpleWithPhi$Companion::foo()) true",
          "SimpleWithSideEffects::<clinit>()",
          "SimpleWithSideEffects::bar(SimpleWithSideEffects::foo())",
          "SimpleWithSideEffects::bar(1)",
          "SimpleWithParams::bar(SimpleWithParams::foo())",
          "SimpleWithParams::bar(2)",
          "SimpleWithGetter::bar(SimpleWithGetter::foo())",
          "SimpleWithGetter::bar(3)",
          "Simple::bar(Simple::foo())",
          "Simple::bar(4)",
          "Simple::bar(Simple::foo())",
          "Simple::bar(5)");

  private static final Class<?> main = TrivialTestClass.class;
  private static final Class<?>[] classes = {
    TrivialTestClass.class,
    Simple.class,
    SimpleWithGetter.class,
    SimpleWithLazyInit.class,
    SimpleWithParams.class,
    SimpleWithPhi.class,
    SimpleWithPhi.Companion.class,
    SimpleWithSideEffects.class,
    SimpleWithThrowingGetter.class
  };

  @Parameterized.Parameters(name = "{0}")
  public static TestParametersCollection data() {
    // TODO(b/112831361): support for class staticizer in CF backend.
    return getTestParameters().withDexRuntimes().withAllApiLevels().build();
  }

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

  @Test
  public void testWithoutAccessModification()
      throws ExecutionException, CompilationFailedException, IOException {
    testForR8(parameters.getBackend())
        .addProgramClasses(classes)
        .addKeepMainRule(main)
        .addKeepAttributes("InnerClasses", "EnclosingMethod")
        .addOptionsModification(this::configure)
        .enableInliningAnnotations()
        .enableNoHorizontalClassMergingAnnotations()
        .setMinApi(parameters.getApiLevel())
        .run(parameters.getRuntime(), main)
        .assertSuccessWithOutput(EXPECTED);
  }

  @Test
  public void testTrivial() throws Exception {
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(classes)
            .enableInliningAnnotations()
            .enableNoHorizontalClassMergingAnnotations()
            .addKeepMainRule(main)
            .noMinification()
            .addKeepAttributes("InnerClasses", "EnclosingMethod")
            .addOptionsModification(this::configure)
            .allowAccessModification()
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), main)
            .assertSuccessWithOutput(EXPECTED);

    CodeInspector inspector = result.inspector();
    ClassSubject clazz = inspector.clazz(main);

    assertEquals(
        Lists.newArrayList(
            "STATIC: String Simple.bar(String)",
            "STATIC: String Simple.foo()",
            "STATIC: String TrivialTestClass.next()"),
        references(clazz, "testSimple", "void"));

    ClassSubject simple = inspector.clazz(Simple.class);
    assertTrue(instanceMethods(simple).isEmpty());
    assertThat(simple.clinit(), not(isPresent()));

    assertEquals(
        Lists.newArrayList(
            "STATIC: String SimpleWithPhi.bar(String)",
            "STATIC: String SimpleWithPhi.foo()",
            "STATIC: String SimpleWithPhi.foo()",
            "STATIC: String TrivialTestClass.next()"),
        references(clazz, "testSimpleWithPhi", "void", "int"));

    ClassSubject simpleWithPhi = inspector.clazz(SimpleWithPhi.class);
    assertTrue(instanceMethods(simpleWithPhi).isEmpty());
    assertThat(simpleWithPhi.clinit(), not(isPresent()));

    // TODO(b/200498092): SimpleWithParams should be staticized, but due to reprocessing the
    //  instantiation of SimpleWithParams, it is marked as ineligible for staticizing.
    assertEquals(
        Lists.newArrayList(
            "STATIC: String SimpleWithParams.bar(String)",
            "STATIC: String SimpleWithParams.foo()",
            "STATIC: String TrivialTestClass.next()"),
        references(clazz, "testSimpleWithParams", "void"));

    ClassSubject simpleWithParams = inspector.clazz(SimpleWithParams.class);
    assertTrue(instanceMethods(simpleWithParams).isEmpty());
    assertThat(simpleWithParams.clinit(), isAbsent());

    assertEquals(
        Lists.newArrayList(
            "STATIC: String SimpleWithSideEffects.bar(String)",
            "STATIC: String SimpleWithSideEffects.foo()",
            "STATIC: String TrivialTestClass.next()"),
        references(clazz, "testSimpleWithSideEffects", "void"));

    ClassSubject simpleWithSideEffects = inspector.clazz(SimpleWithSideEffects.class);
    assertTrue(instanceMethods(simpleWithSideEffects).isEmpty());
    // As its name implies, its clinit has side effects.
    assertThat(simpleWithSideEffects.clinit(), isPresent());

    assertEquals(
        Lists.newArrayList(
            "STATIC: String SimpleWithGetter.bar(String)",
            "STATIC: String SimpleWithGetter.foo()",
            "STATIC: String TrivialTestClass.next()"),
        references(clazz, "testSimpleWithGetter", "void"));

    ClassSubject simpleWithGetter = inspector.clazz(SimpleWithGetter.class);
    assertEquals(0, instanceMethods(simpleWithGetter).size());
    assertThat(simpleWithGetter.clinit(), isAbsent());

    assertEquals(
        Lists.newArrayList(
            "STATIC: String SimpleWithLazyInit.bar$1(String)",
            "STATIC: String SimpleWithLazyInit.foo$1()",
            "STATIC: String TrivialTestClass.next()"),
        references(clazz, "testSimpleWithThrowingGetter", "void"));

    ClassSubject simpleWithThrowingGetter = inspector.clazz(SimpleWithThrowingGetter.class);
    assertThat(simpleWithThrowingGetter, isAbsent());

    // TODO(b/143389508): add support for lazy init in singleton instance getter.
    assertEquals(
        Lists.newArrayList(
            "DIRECT: void SimpleWithLazyInit.<init>()",
            "DIRECT: void SimpleWithLazyInit.<init>()",
            "STATIC: String SimpleWithLazyInit.bar(String)",
            "STATIC: String SimpleWithLazyInit.foo()",
            "STATIC: String TrivialTestClass.next()",
            "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
            "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
            "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
            "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
            "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE",
            "SimpleWithLazyInit SimpleWithLazyInit.INSTANCE"),
        references(clazz, "testSimpleWithLazyInit", "void"));

    ClassSubject simpleWithLazyInit = inspector.clazz(SimpleWithLazyInit.class);
    assertFalse(instanceMethods(simpleWithLazyInit).isEmpty());
    assertThat(simpleWithLazyInit.clinit(), isPresent());
  }

  @Test
  public void testMoveToHost_fieldOnly() throws Exception {
    Class<?> main = MoveToHostFieldOnlyTestClass.class;
    Class<?>[] classes = {
        MoveToHostFieldOnlyTestClass.class,
        HostOkFieldOnly.class,
        CandidateOkFieldOnly.class
    };
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(classes)
            .enableInliningAnnotations()
            .enableSideEffectAnnotations()
            .addKeepMainRule(main)
            .allowAccessModification()
            .noMinification()
            .addOptionsModification(this::configure)
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), main);

    CodeInspector inspector = result.inspector();
    ClassSubject clazz = inspector.clazz(main);

    assertEquals(
        Lists.newArrayList(),
        references(clazz, "testOk_fieldOnly", "void"));

    assertThat(inspector.clazz(CandidateOkFieldOnly.class), not(isPresent()));
  }

  @Test
  public void testMoveToHost() throws Exception {
    Class<?> main = MoveToHostTestClass.class;
    Class<?>[] classes = {
        MoveToHostTestClass.class,
        HostOk.class,
        CandidateOk.class,
        HostOkSideEffects.class,
        CandidateOkSideEffects.class,
        HostConflictMethod.class,
        CandidateConflictMethod.class,
        HostConflictField.class,
        CandidateConflictField.class
    };
    String javaOutput = runOnJava(main);
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(classes)
            .enableInliningAnnotations()
            .enableNoHorizontalClassMergingAnnotations()
            .enableNoHorizontalClassMergingAnnotations()
            .enableMemberValuePropagationAnnotations()
            .addKeepMainRule(main)
            .allowAccessModification()
            .noMinification()
            .addOptionsModification(this::configure)
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), main)
            .assertSuccessWithOutput(javaOutput);

    CodeInspector inspector = result.inspector();
    ClassSubject clazz = inspector.clazz(main);

    assertEquals(
        Lists.newArrayList(
            "STATIC: String movetohost.CandidateOk.bar(String)",
            "STATIC: String movetohost.CandidateOk.foo()",
            "STATIC: String movetohost.MoveToHostTestClass.next()",
            "STATIC: String movetohost.MoveToHostTestClass.next()",
            "STATIC: void movetohost.CandidateOk.blah(String)"),
        references(clazz, "testOk", "void"));

    assertThat(inspector.clazz(HostOk.class), isAbsent());
    assertThat(inspector.clazz(CandidateOk.class), isPresent());

    assertEquals(
        Lists.newArrayList(
            "STATIC: String movetohost.CandidateOkSideEffects.bar(String)",
            "STATIC: String movetohost.CandidateOkSideEffects.foo()",
            "STATIC: String movetohost.MoveToHostTestClass.next()"),
        references(clazz, "testOkSideEffects", "void"));

    assertThat(inspector.clazz(HostOkSideEffects.class), isPresent());
    assertThat(inspector.clazz(CandidateOkSideEffects.class), isPresent());

    assertEquals(
        Lists.newArrayList(
            "STATIC: String movetohost.CandidateConflictMethod.bar(String)",
            "STATIC: String movetohost.CandidateConflictMethod.foo()",
            "STATIC: String movetohost.HostConflictMethod.bar(String)",
            "STATIC: String movetohost.MoveToHostTestClass.next()",
            "STATIC: String movetohost.MoveToHostTestClass.next()"),
        references(clazz, "testConflictMethod", "void"));

    assertThat(inspector.clazz(HostConflictMethod.class), isPresent());
    assertThat(inspector.clazz(CandidateConflictMethod.class), isPresent());

    assertEquals(
        Lists.newArrayList(
            "DIRECT: void movetohost.HostConflictField.<init>()",
            "STATIC: String movetohost.CandidateConflictField.bar(String)",
            "STATIC: String movetohost.CandidateConflictField.foo()",
            "STATIC: String movetohost.MoveToHostTestClass.next()"),
        references(clazz, "testConflictField", "void"));

    assertThat(inspector.clazz(CandidateConflictMethod.class), isPresent());
  }

  private List<String> instanceMethods(ClassSubject clazz) {
    assertNotNull(clazz);
    assertThat(clazz, isPresent());
    return Streams.stream(clazz.getDexProgramClass().methods())
        .filter(method -> !method.isStatic())
        .map(method -> method.getReference().toSourceString())
        .sorted()
        .collect(Collectors.toList());
  }

  private List<String> references(
      ClassSubject clazz, String methodName, String retValue, String... params) {
    assertNotNull(clazz);
    assertThat(clazz, isPresent());

    MethodSignature signature = new MethodSignature(methodName, retValue, params);
    DexCode code = clazz.method(signature).getMethod().getCode().asDexCode();
    return Streams.concat(
            filterInstructionKind(code, DexSgetObject.class)
                .map(DexInstruction::getField)
                .filter(fld -> isTypeOfInterest(fld.holder))
                .map(DexField::toSourceString),
            filterInstructionKind(code, DexSputObject.class)
                .map(DexInstruction::getField)
                .filter(fld -> isTypeOfInterest(fld.holder))
                .map(DexField::toSourceString),
            filterInstructionKind(code, DexInvokeStatic.class)
                .map(insn -> (DexInvokeStatic) insn)
                .map(DexInvokeStatic::getMethod)
                .filter(method -> isTypeOfInterest(method.holder))
                .map(method -> "STATIC: " + method.toSourceString()),
            filterInstructionKind(code, DexInvokeVirtual.class)
                .map(insn -> (DexInvokeVirtual) insn)
                .map(DexInvokeVirtual::getMethod)
                .filter(method -> isTypeOfInterest(method.holder))
                .map(method -> "VIRTUAL: " + method.toSourceString()),
            filterInstructionKind(code, DexInvokeDirect.class)
                .map(insn -> (DexInvokeDirect) insn)
                .map(DexInvokeDirect::getMethod)
                .filter(method -> isTypeOfInterest(method.holder))
                .map(method -> "DIRECT: " + method.toSourceString()))
        .map(txt -> txt.replace("java.lang.", ""))
        .map(txt -> txt.replace("com.android.tools.r8.ir.optimize.staticizer.trivial.", ""))
        .map(txt -> txt.replace("com.android.tools.r8.ir.optimize.staticizer.", ""))
        .sorted()
        .collect(Collectors.toList());
  }

  private boolean isTypeOfInterest(DexType type) {
    return type.toSourceString().startsWith("com.android.tools.r8.ir.optimize.staticizer");
  }

  private void configure(InternalOptions options) {
    options.enableClassInlining = false;
  }

  @Test
  public void dualInlinedMethodRewritten() throws Exception {
    Class<?> main = DualCallTest.class;
    Class<?>[] classes = {
        DualCallTest.class,
        Candidate.class
    };
    String javaOutput = runOnJava(main);
    R8TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(classes)
            .enableConstantArgumentAnnotations()
            .enableInliningAnnotations()
            .addKeepMainRule(main)
            .allowAccessModification()
            .noMinification()
            .addOptionsModification(this::configure)
            .setMinApi(parameters.getApiLevel())
            .run(parameters.getRuntime(), main)
            .assertSuccessWithOutput(javaOutput);

    CodeInspector inspector = result.inspector();
    ClassSubject clazz = inspector.clazz(main);

    // Check that "calledTwice" is removed (inlined into main).
    assertThat(clazz.uniqueMethodWithName("calledTwice"), not(isPresent()));

    // Check that the two inlines of "calledTwice" is correctly rewritten.
    ClassSubject candidateClassSubject = inspector.clazz(Candidate.class);
    assertThat(candidateClassSubject, isPresent());
    assertThat(candidateClassSubject.uniqueMethodWithName("foo"), isPresent());
    assertThat(candidateClassSubject.uniqueMethodWithName("bar"), isPresent());
    assertEquals(
        Lists.newArrayList(
            "STATIC: String dualcallinline.Candidate.foo()",
            "STATIC: String dualcallinline.Candidate.foo()"),
        references(clazz, "main", "void", "java.lang.String[]"));
  }
}
