// Copyright (c) 2016, 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.graph;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import com.android.tools.r8.CompilationFailedException;
import com.android.tools.r8.ToolHelper;
import com.android.tools.r8.ToolHelper.DexVm;
import com.android.tools.r8.ToolHelper.ProcessResult;
import com.android.tools.r8.graph.invokesuper2.C0;
import com.android.tools.r8.graph.invokesuper2.C1;
import com.android.tools.r8.graph.invokesuper2.C2;
import com.android.tools.r8.graph.invokesuper2.I0;
import com.android.tools.r8.graph.invokesuper2.I1;
import com.android.tools.r8.graph.invokesuper2.I2;
import com.android.tools.r8.graph.invokesuper2.I3;
import com.android.tools.r8.graph.invokesuper2.I4;
import com.android.tools.r8.graph.invokesuper2.Main;
import com.android.tools.r8.smali.SmaliBuilder;
import com.android.tools.r8.smali.SmaliTestBase;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.google.common.collect.ImmutableList;
import java.nio.file.Path;
import java.util.Collections;
import org.junit.Test;

public class TargetLookupTest extends SmaliTestBase {

  @Test
  public void lookupDirect() {
    SmaliBuilder builder = new SmaliBuilder(DEFAULT_CLASS_NAME);

    builder.addDefaultConstructor();

    builder.addMethodRaw(
        "  .method private static x()I",
        "    .locals 1",
        "    const v0, 0",
        "    return v0",
        "  .end method"
    );

    // Instance method invoking static method using invoke-direct. This does not run on Art, but
    // results in an IncompatibleClassChangeError.
    builder.addMethodRaw(
        "  .method public y()I",
        "    .locals 1",
        "    invoke-direct       {p0}, " + builder.getCurrentClassDescriptor() + "->x()I",
        "    move-result         v0",
        "    return              v0",
        "  .end method"
    );

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, LTest;",
        "    invoke-direct       {v1}, " + builder.getCurrentClassDescriptor() + "-><init>()V",
        "    :try_start",
        "    invoke-virtual      {v1}, " + builder.getCurrentClassDescriptor() + "->y()I",
        "    :try_end",
        "    const-string        v1, \"ERROR\"",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    :return",
        "    return-void",
        "    .catch Ljava/lang/IncompatibleClassChangeError; {:try_start .. :try_end} :catch",
        "    :catch",
        "    const-string        v1, \"OK\"",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    goto :return"
    );

    AndroidApp application = buildApplication(builder);
    AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
    CodeInspector inspector = new CodeInspector(appInfo.app());
    ProgramMethod method = getMethod(inspector, DEFAULT_CLASS_NAME, "int", "x", ImmutableList.of());
    assertFalse(
        appInfo.resolveMethodOnClass(method.getReference()).getSingleTarget().isVirtualMethod());
    assertNull(appInfo.lookupDirectTarget(method.getReference(), method));
    assertNotNull(appInfo.lookupStaticTarget(method.getReference(), method));

    if (ToolHelper.getDexVm().getVersion().isOlderThanOrEqual(DexVm.Version.V4_4_4)) {
      // Dalvik rejects at verification time instead of producing the
      // expected IncompatibleClassChangeError.
      try {
        runArt(application);
      } catch (AssertionError e) {
        assert e.toString().contains("VerifyError");
      }
    } else {
      assertEquals("OK", runArt(application));
    }
  }

  @Test
  public void lookupDirectSuper() {
    SmaliBuilder builder = new SmaliBuilder("TestSuper");

    builder.addDefaultConstructor();

    builder.addMethodRaw(
        "  .method private static x()I",
        "    .locals 1",
        "    const               v0, 0",
        "    return              v0",
        "  .end method"
    );

    builder.addClass("Test", "TestSuper");

    builder.addDefaultConstructor();

    // Instance method invoking static method in superclass using invoke-direct. This does not run
    // on Art, but results in an IncompatibleClassChangeError.
    builder.addMethodRaw(
        "  .method public y()I",
        "    .locals 1",
        "    invoke-direct       {p0}, " + builder.getCurrentClassDescriptor() + "->x()I",
        "    move-result         v0",
        "    return              v0",
        "  .end method"
    );

    builder.addMainMethod(
        2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    new-instance        v1, LTest;",
        "    invoke-direct       {v1}, " + builder.getCurrentClassDescriptor() + "-><init>()V",
        "    :try_start",
        "    invoke-virtual      {v1}, " + builder.getCurrentClassDescriptor() + "->y()I",
        "    :try_end",
        "    const-string        v1, \"ERROR\"",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    :return",
        "    return-void",
        "    .catch Ljava/lang/IncompatibleClassChangeError; {:try_start .. :try_end} :catch",
        "    :catch",
        "    const-string        v1, \"OK\"",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(Ljava/lang/String;)V",
        "    goto :return"
    );

    AndroidApp application = buildApplication(builder);
    AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
    CodeInspector inspector = new CodeInspector(appInfo.app());

    ProgramMethod methodXOnTestSuper =
        getMethod(inspector, "TestSuper", "int", "x", ImmutableList.of());
    ProgramMethod methodYOnTest = getMethod(inspector, "Test", "int", "y", ImmutableList.of());

    DexType classTestSuper = methodXOnTestSuper.getHolderType();
    DexType classTest = methodYOnTest.getHolderType();
    DexProto methodXProto = methodXOnTestSuper.getReference().proto;
    DexString methodXName = methodXOnTestSuper.getReference().name;
    DexMethod methodXOnTestReference =
        appInfo.dexItemFactory().createMethod(classTest, methodXProto, methodXName);

    assertFalse(
        appInfo
            .resolveMethodOnClass(methodXOnTestSuper.getReference(), classTestSuper)
            .getSingleTarget()
            .isVirtualMethod());
    assertNull(
        appInfo
            .resolveMethodOnClass(methodXOnTestSuper.getReference(), classTest)
            .getSingleTarget());
    assertNull(appInfo.resolveMethodOnClass(methodXOnTestReference, classTest).getSingleTarget());

    assertNull(appInfo.lookupDirectTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper));
    assertNull(appInfo.lookupDirectTarget(methodXOnTestReference, methodYOnTest));

    assertNotNull(
        appInfo.lookupStaticTarget(methodXOnTestSuper.getReference(), methodXOnTestSuper));
    // Accessing a private target on a different type will fail resolution outright.
    assertNull(appInfo.lookupStaticTarget(methodXOnTestReference, methodYOnTest));

    assertEquals("OK", runArt(application));
  }

  @Test
  public void lookupFieldWithDefaultInInterface() throws CompilationFailedException {
    SmaliBuilder builder = new SmaliBuilder();

    builder.addInterface("Interface");
    builder.addStaticField("aField", "I", "42");

    builder.addClass("SuperClass");
    builder.addStaticField("aField", "I", "123");

    builder.addClass("SubClass", "SuperClass", Collections.singletonList("Interface"));

    builder.addClass(DEFAULT_CLASS_NAME);
    builder.addMainMethod(2,
        "    sget-object         v0, Ljava/lang/System;->out:Ljava/io/PrintStream;",
        "    sget                v1, LSubClass;->aField:I",
        "    invoke-virtual      { v0, v1 }, Ljava/io/PrintStream;->print(I)V",
        "    return-void"
    );

    AndroidApp application = buildApplication(builder);
    AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
    DexItemFactory factory = appInfo.dexItemFactory();

    DexField aFieldOnSubClass = factory
        .createField(factory.createType("LSubClass;"), factory.intType, "aField");
    DexField aFieldOnInterface = factory
        .createField(factory.createType("LInterface;"), factory.intType, "aField");

    assertEquals(aFieldOnInterface, appInfo.lookupStaticTarget(aFieldOnSubClass).field);

    assertEquals("42", runArt(application));

    AndroidApp processedApp = processApplication(application);
    assertEquals("42", runArt(processedApp));
  }

  @Test
  public void testLookupSuperTarget() throws Exception {
    String pkg = Main.class.getPackage().getName().replace('.', '/');

    AndroidApp.Builder builder = AndroidApp.builder();
    for (Class clazz : new Class[]{
        I0.class, I1.class, I2.class, I3.class, I4.class,
        C0.class, C1.class, C2.class,
        Main.class}) {
      builder.addProgramFiles(ToolHelper.getClassFileForTestClass(clazz));
      // At least java.lang.Object is needed as interface method lookup have special handling
      // of methods on java.lang.Object.
      builder.addLibraryFiles(ToolHelper.getDefaultAndroidJar());
    }
    AndroidApp application = builder.build();
    AppInfoWithClassHierarchy appInfo = computeAppInfoWithClassHierarchy(application);
    DexItemFactory factory = appInfo.dexItemFactory();

    DexType i0 = factory.createType("L" + pkg + "/I0;");
    DexType i1 = factory.createType("L" + pkg + "/I1;");
    DexType i2 = factory.createType("L" + pkg + "/I2;");
    DexType i3 = factory.createType("L" + pkg + "/I3;");
    DexType i4 = factory.createType("L" + pkg + "/I4;");
    DexType c0 = factory.createType("L" + pkg + "/C0;");
    DexProgramClass c1 = appInfo.definitionForProgramType(factory.createType("L" + pkg + "/C1;"));
    DexProgramClass c2 = appInfo.definitionForProgramType(factory.createType("L" + pkg + "/C2;"));

    DexProto mProto = factory.createProto(factory.intType);
    DexString m = factory.createString("m");
    DexMethod mOnC0 = factory.createMethod(c0, mProto, m);
    DexMethod mOnC1 = factory.createMethod(c1.type, mProto, m);
    DexMethod mOnI0 = factory.createMethod(i0, mProto, m);
    DexMethod mOnI1 = factory.createMethod(i1, mProto, m);
    DexMethod mOnI2 = factory.createMethod(i2, mProto, m);
    DexMethod mOnI3 = factory.createMethod(i3, mProto, m);
    DexMethod mOnI4 = factory.createMethod(i4, mProto, m);

    assertEquals(mOnI0, appInfo.lookupSuperTarget(mOnC0, c1).method);
    assertEquals(mOnI1, appInfo.lookupSuperTarget(mOnI1, c1).method);
    assertEquals(mOnI2, appInfo.lookupSuperTarget(mOnI2, c1).method);

    assertNull(appInfo.lookupSuperTarget(mOnC1, c2)); // C2 is not a subclass of C1.
    assertEquals(mOnI1, appInfo.lookupSuperTarget(mOnI3, c2).method);
    assertEquals(mOnI2, appInfo.lookupSuperTarget(mOnI4, c2).method);

    // Copy classes to run on the Java VM.
    Path out = temp.newFolder().toPath();
    copyTestClasses(out, I0.class, I1.class, I2.class, I3.class, I4.class);
    copyTestClasses(out, C0.class, C1.class, C2.class, Main.class);
    ProcessResult result = ToolHelper.runJava(out, Main.class.getCanonicalName());
    assertEquals(0, result.exitCode);

    // Process the application and expect the same result on Art.
    AndroidApp processedApp = processApplication(application);
    assertEquals(result.stdout, runArt(processedApp, Main.class.getCanonicalName()));
  }
}



