// Copyright (c) 2020, 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.resolution.singletarget;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertNull;

import com.android.tools.r8.TestBase;
import com.android.tools.r8.TestParameters;
import com.android.tools.r8.TestParametersCollection;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.ArrayList;
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 SuccessAndInvalidLookupTest extends TestBase {

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

  public SuccessAndInvalidLookupTest(TestParameters parameters) {
    // Empty to satisfy construction of none-runtime.
  }

  @Test
  public void testSingleTargetWithInvalidInvokeInterfaceInvoke() throws Exception {
    AppView<AppInfoWithLiveness> appView =
        computeAppViewWithLiveness(
            buildClasses(I.class, A.class, Main.class).build(),
            factory -> new ArrayList<>(buildKeepRuleForClassAndMethods(Main.class, factory)));
    AppInfoWithLiveness appInfo = appView.appInfo();
    DexType typeMain = buildType(Main.class, appInfo.dexItemFactory());
    DexType typeA = buildType(A.class, appInfo.dexItemFactory());
    DexMethod fooA = buildNullaryVoidMethod(A.class, "foo", appInfo.dexItemFactory());
    DexEncodedMethod singleTarget =
        appInfo.lookupSingleVirtualTarget(fooA, typeMain, false, t -> false, typeA, null);
    assertNotNull(singleTarget);
    assertEquals(fooA, singleTarget.method);
    DexEncodedMethod invalidSingleTarget =
        appInfo.lookupSingleVirtualTarget(fooA, typeMain, true, t -> false, typeA, null);
    assertNull(invalidSingleTarget);
  }

  @Test
  public void testSingleTargetWithInvalidInvokeVirtualInvoke() throws Exception {
    AppView<AppInfoWithLiveness> appView =
        computeAppViewWithLiveness(
            buildClasses(I.class, A.class, Main.class).build(),
            factory -> new ArrayList<>(buildKeepRuleForClassAndMethods(Main.class, factory)));
    AppInfoWithLiveness appInfo = appView.appInfo();
    DexType typeMain = buildType(Main.class, appInfo.dexItemFactory());
    DexType typeA = buildType(I.class, appInfo.dexItemFactory());
    DexMethod fooI = buildNullaryVoidMethod(I.class, "foo", appInfo.dexItemFactory());
    DexMethod fooA = buildNullaryVoidMethod(A.class, "foo", appInfo.dexItemFactory());
    DexEncodedMethod singleTarget =
        appInfo.lookupSingleVirtualTarget(fooI, typeMain, true, t -> false, typeA, null);
    assertNotNull(singleTarget);
    assertEquals(fooA, singleTarget.method);
    DexEncodedMethod invalidSingleTarget =
        appInfo.lookupSingleVirtualTarget(fooI, typeMain, false, t -> false, typeA, null);
    assertNull(invalidSingleTarget);
  }

  public interface I {

    void foo();
  }

  public static class A implements I {

    @Override
    public void foo() {
      System.out.println("A.foo");
    }
  }

  public static class Main {

    public static void main(String[] args) {
      new A();
    }
  }
}
