// 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.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.NeverInline;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.TestRunResult;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.code.InvokeDirect;
import com.android.tools.r8.code.InvokeStatic;
import com.android.tools.r8.code.InvokeVirtual;
import com.android.tools.r8.code.SgetObject;
import com.android.tools.r8.code.SputObject;
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.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.TrivialTestClass;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.utils.InternalOptions;
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.util.List;
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;

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

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

  @Test
  public void testTrivial() throws Exception {
    Class<?> main = TrivialTestClass.class;
    Class<?>[] classes = {
        NeverInline.class,
        TrivialTestClass.class,
        Simple.class,
        SimpleWithSideEffects.class,
        SimpleWithParams.class,
        SimpleWithGetter.class,
        SimpleWithPhi.class,
        SimpleWithPhi.Companion.class
    };
    String javaOutput = runOnJava(main);
    TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(classes)
            .enableInliningAnnotations()
            .addKeepMainRule(main)
            .noMinification()
            .addKeepRules("-keepattributes InnerClasses,EnclosingMethod")
            .addOptionsModification(this::configure)
            .allowAccessModification()
            .setMinApi(parameters.getRuntime())
            .run(parameters.getRuntime(), main)
            .assertSuccessWithOutput(javaOutput);

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

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

    assertTrue(instanceMethods(inspector.clazz(Simple.class)).isEmpty());

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

    assertTrue(instanceMethods(inspector.clazz(SimpleWithPhi.class)).isEmpty());

    assertEquals(
        Lists.newArrayList(
            "STATIC: String trivial.SimpleWithParams.bar(String)",
            "STATIC: String trivial.SimpleWithParams.foo()",
            "STATIC: String trivial.TrivialTestClass.next()"),
        references(clazz, "testSimpleWithParams", "void"));

    assertTrue(instanceMethods(inspector.clazz(SimpleWithParams.class)).isEmpty());

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

    assertTrue(instanceMethods(inspector.clazz(SimpleWithSideEffects.class)).isEmpty());

    // TODO(b/111832046): add support for singleton instance getters.
    assertEquals(
        Lists.newArrayList(
            "STATIC: String trivial.TrivialTestClass.next()",
            "VIRTUAL: String trivial.SimpleWithGetter.bar(String)",
            "VIRTUAL: String trivial.SimpleWithGetter.foo()",
            "trivial.SimpleWithGetter trivial.SimpleWithGetter.INSTANCE",
            "trivial.SimpleWithGetter trivial.SimpleWithGetter.INSTANCE"),
        references(clazz, "testSimpleWithGetter", "void"));

    assertFalse(instanceMethods(inspector.clazz(SimpleWithGetter.class)).isEmpty());
  }

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

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

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

    assertFalse(inspector.clazz(CandidateOkFieldOnly.class).isPresent());
  }

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

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

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

    assertFalse(inspector.clazz(CandidateOk.class).isPresent());

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

    assertFalse(inspector.clazz(CandidateOkSideEffects.class).isPresent());

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

    assertTrue(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()",
            "String movetohost.CandidateConflictField.field"),
        references(clazz, "testConflictField", "void"));

    assertTrue(inspector.clazz(CandidateConflictMethod.class).isPresent());
  }

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

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

    MethodSignature signature = new MethodSignature(methodName, retValue, params);
    DexCode code = clazz.method(signature).getMethod().getCode().asDexCode();
    return Streams.concat(
        filterInstructionKind(code, SgetObject.class)
            .map(Instruction::getField)
            .filter(fld -> isTypeOfInterest(fld.holder))
            .map(DexField::toSourceString),
        filterInstructionKind(code, SputObject.class)
            .map(Instruction::getField)
            .filter(fld -> isTypeOfInterest(fld.holder))
            .map(DexField::toSourceString),
        filterInstructionKind(code, InvokeStatic.class)
            .map(insn -> (InvokeStatic) insn)
            .map(InvokeStatic::getMethod)
            .filter(method -> isTypeOfInterest(method.holder))
            .map(method -> "STATIC: " + method.toSourceString()),
        filterInstructionKind(code, InvokeVirtual.class)
            .map(insn -> (InvokeVirtual) insn)
            .map(InvokeVirtual::getMethod)
            .filter(method -> isTypeOfInterest(method.holder))
            .map(method -> "VIRTUAL: " + method.toSourceString()),
        filterInstructionKind(code, InvokeDirect.class)
            .map(insn -> (InvokeDirect) insn)
            .map(InvokeDirect::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.", ""))
        .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;
    options.enableUninstantiatedTypeOptimization = false;
  }

  @Test
  public void dualInlinedMethodRewritten() throws Exception {
    Class<?> main = DualCallTest.class;
    Class<?>[] classes = {
        DualCallTest.class,
        Candidate.class
    };
    String javaOutput = runOnJava(main);
    TestRunResult result =
        testForR8(parameters.getBackend())
            .addProgramClasses(classes)
            .enableInliningAnnotations()
            .addKeepMainRule(main)
            .allowAccessModification()
            .noMinification()
            .addOptionsModification(this::configure)
            .setMinApi(parameters.getRuntime())
            .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.
    assertThat(clazz.uniqueMethodWithName("foo"), isPresent());
    assertThat(clazz.uniqueMethodWithName("bar"), isPresent());
    assertEquals(
        Lists.newArrayList(
            "STATIC: String dualcallinline.DualCallTest.foo()",
            "STATIC: String dualcallinline.DualCallTest.foo()"),
        references(clazz, "main", "void", "java.lang.String[]"));
  }
}
