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

import com.android.tools.r8.AsmTestBase;
import com.android.tools.r8.dex.ApplicationReader;
import com.android.tools.r8.graph.AppInfoWithSubtyping;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexApplication;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GraphLense;
import com.android.tools.r8.resolution.singletarget.Main;
import com.android.tools.r8.resolution.singletarget.one.AbstractSubClass;
import com.android.tools.r8.resolution.singletarget.one.AbstractTopClass;
import com.android.tools.r8.resolution.singletarget.one.InterfaceWithDefault;
import com.android.tools.r8.resolution.singletarget.one.IrrelevantInterfaceWithDefault;
import com.android.tools.r8.resolution.singletarget.one.IrrelevantInterfaceWithDefaultDump;
import com.android.tools.r8.resolution.singletarget.one.SubSubClassOne;
import com.android.tools.r8.resolution.singletarget.one.SubSubClassThree;
import com.android.tools.r8.resolution.singletarget.one.SubSubClassTwo;
import com.android.tools.r8.resolution.singletarget.three.ThirdAbstractTopClass;
import com.android.tools.r8.resolution.singletarget.three.ThirdSubClassOne;
import com.android.tools.r8.resolution.singletarget.three.ThirdSubClassTwoDump;
import com.android.tools.r8.resolution.singletarget.two.OtherAbstractSubClassOne;
import com.android.tools.r8.resolution.singletarget.two.OtherAbstractSubClassTwo;
import com.android.tools.r8.resolution.singletarget.two.OtherAbstractTopClass;
import com.android.tools.r8.resolution.singletarget.two.OtherSubSubClassOne;
import com.android.tools.r8.resolution.singletarget.two.OtherSubSubClassTwo;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.Enqueuer.AppInfoWithLiveness;
import com.android.tools.r8.shaking.ProguardClassFilter;
import com.android.tools.r8.shaking.ProguardClassNameList;
import com.android.tools.r8.shaking.ProguardConfigurationRule;
import com.android.tools.r8.shaking.ProguardKeepRule;
import com.android.tools.r8.shaking.ProguardKeepRule.Builder;
import com.android.tools.r8.shaking.ProguardKeepRuleType;
import com.android.tools.r8.shaking.ProguardTypeMatcher;
import com.android.tools.r8.shaking.RootSetBuilder;
import com.android.tools.r8.shaking.RootSetBuilder.RootSet;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.InternalOptions;
import com.android.tools.r8.utils.Timing;
import com.google.common.collect.ImmutableList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;
import org.junit.Assert;
import org.junit.BeforeClass;
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 SingleTargetLookupTest extends AsmTestBase {

  /**
   * Initialized in @Before rule.
   */
  public static AppInfoWithLiveness appInfo;

  public static List<Class> CLASSES = ImmutableList.of(
      InterfaceWithDefault.class,
      AbstractTopClass.class,
      AbstractSubClass.class,
      SubSubClassOne.class,
      SubSubClassTwo.class,
      SubSubClassThree.class,
      OtherAbstractTopClass.class,
      OtherAbstractSubClassOne.class,
      OtherAbstractSubClassTwo.class,
      OtherSubSubClassOne.class,
      OtherSubSubClassTwo.class,
      ThirdAbstractTopClass.class,
      ThirdSubClassOne.class,
      Main.class
  );

  public static List<byte[]> ASM_CLASSES = ImmutableList.of(
      getBytesFromAsmClass(IrrelevantInterfaceWithDefaultDump::dump),
      getBytesFromAsmClass(ThirdSubClassTwoDump::dump)
  );

  public SingleTargetLookupTest(String methodName, Class invokeReceiver,
      Class singleTargetHolderOrNull, List<Class> allTargetHolders) {
    this.methodName = methodName;
    this.invokeReceiver = invokeReceiver;
    this.singleTargetHolderOrNull = singleTargetHolderOrNull;
    this.allTargetHolders = allTargetHolders;
  }

  @BeforeClass
  public static void computeAppInfo() throws Exception {
    // Run the tree shaker to compute an instance of AppInfoWithLiveness.
    Timing timing = new Timing(SingleTargetLookupTest.class.getCanonicalName());
    InternalOptions options = new InternalOptions();
    AndroidApp app = readClassesAndAsmDump(CLASSES, ASM_CLASSES);
    DexApplication application = new ApplicationReader(app, options, timing).read().toDirect();
    AppView<? extends AppInfoWithSubtyping> appView =
        new AppView<>(
            new AppInfoWithSubtyping(application), GraphLense.getIdentityLense(), options);

    ExecutorService executor = Executors.newSingleThreadExecutor();
    RootSet rootSet =
        new RootSetBuilder(
                appView,
                application,
                buildKeepRuleForClass(Main.class, application.dexItemFactory),
                options)
            .run(executor);
    appInfo =
        new Enqueuer(appView, options, null)
            .traceApplication(rootSet, ProguardClassFilter.empty(), executor, timing);
    // We do not run the tree pruner to ensure that the hierarchy is as designed and not modified
    // due to liveness.
  }

  private static List<ProguardConfigurationRule> buildKeepRuleForClass(Class clazz,
      DexItemFactory factory) {
    Builder keepRuleBuilder = ProguardKeepRule.builder();
    keepRuleBuilder.setSource("buildKeepRuleForClass " + clazz.getTypeName());
    keepRuleBuilder.setType(ProguardKeepRuleType.KEEP);
    keepRuleBuilder.setClassNames(
        ProguardClassNameList.singletonList(ProguardTypeMatcher.create(factory
            .createType(DescriptorUtils.javaTypeToDescriptor(clazz.getCanonicalName())))));
    return Collections.singletonList(keepRuleBuilder.build());
  }

  private static Object[] singleTarget(String name, Class<?> receiverAndTarget) {
    return new Object[]{name, receiverAndTarget, receiverAndTarget,
        Collections.singletonList(receiverAndTarget)};
  }

  private static Object[] singleTarget(String name, Class<?> receiver, Class<?> target) {
    return new Object[]{name, receiver, target, Collections.singletonList(target)};
  }

  private static Object[] singleTargetWithAbstracts(String name, Class<?> receiver,
      Class<?> target, Class<?>... extras) {
    return new Object[]{name, receiver, target,
        ImmutableList.builder().add(target).add((Object[]) extras).build()};
  }

  private static Object[] manyTargets(String name, Class<?> receiver, Class<?>... targets) {
    return new Object[]{name, receiver, null, ImmutableList.copyOf(targets)};
  }

  private static Object[] onlyUnreachableTargets(String name, Class<?> receiver,
      Class<?>... targets) {
    return new Object[]{name, receiver, null, ImmutableList.copyOf(targets)};
  }

  @Parameters(name = "{1}.{0} -> {2}")
  public static List<Object[]> getData() {
    return ImmutableList.copyOf(new Object[][]{
        singleTarget("singleTargetAtTop", AbstractTopClass.class),
        singleTargetWithAbstracts("singleShadowingOverride", AbstractTopClass.class,
            AbstractSubClass.class, AbstractTopClass.class),
        manyTargets("abstractTargetAtTop", AbstractTopClass.class, AbstractTopClass.class,
            SubSubClassOne.class, SubSubClassTwo.class),
        singleTargetWithAbstracts("overridenInAbstractClassOnly", AbstractTopClass.class,
            AbstractTopClass.class, SubSubClassThree.class),
        onlyUnreachableTargets("overridenInAbstractClassOnly", SubSubClassThree.class,
            SubSubClassThree.class),
        manyTargets("overriddenInTwoSubTypes", AbstractTopClass.class, AbstractTopClass.class,
            SubSubClassOne.class, SubSubClassTwo.class),
        manyTargets("definedInTwoSubTypes", AbstractTopClass.class, AbstractTopClass.class,
            SubSubClassOne.class, SubSubClassTwo.class),
        onlyUnreachableTargets("staticMethod", AbstractTopClass.class, AbstractTopClass.class),
        manyTargets("overriddenInTwoSubTypes", OtherAbstractTopClass.class,
            OtherAbstractTopClass.class, OtherSubSubClassOne.class, OtherSubSubClassTwo.class),
        manyTargets("abstractOverriddenInTwoSubTypes", OtherAbstractTopClass.class,
            OtherAbstractTopClass.class, OtherSubSubClassOne.class, OtherSubSubClassTwo.class),
        manyTargets("overridesOnDifferentLevels", OtherAbstractTopClass.class,
            OtherAbstractTopClass.class, OtherSubSubClassOne.class, OtherAbstractSubClassTwo.class),
        singleTarget("defaultMethod", AbstractTopClass.class, InterfaceWithDefault.class),
        manyTargets("overriddenDefault", AbstractTopClass.class, InterfaceWithDefault.class,
            SubSubClassTwo.class),
        singleTarget("overriddenDefault", SubSubClassTwo.class),
        singleTarget("overriddenByIrrelevantInterface", AbstractTopClass.class),
        singleTarget("overriddenByIrrelevantInterface", SubSubClassOne.class,
            AbstractTopClass.class),
        manyTargets("overriddenInOtherInterface", AbstractTopClass.class,
            InterfaceWithDefault.class,
            IrrelevantInterfaceWithDefault.class),
        manyTargets("overriddenInOtherInterface", SubSubClassOne.class,
            InterfaceWithDefault.class,
            IrrelevantInterfaceWithDefault.class),
        manyTargets("abstractMethod", ThirdAbstractTopClass.class, ThirdAbstractTopClass.class,
            ThirdSubClassOne.class),
        singleTarget("instanceMethod", ThirdAbstractTopClass.class, ThirdAbstractTopClass.class),
        singleTarget(
            "otherInstanceMethod", ThirdAbstractTopClass.class, ThirdAbstractTopClass.class)
    });
  }

  private static DexMethod buildMethod(Class clazz, String name) {
    return appInfo.dexItemFactory.createMethod(
        toType(clazz),
        appInfo.dexItemFactory.createProto(appInfo.dexItemFactory.voidType),
        name
    );
  }

  private static DexType toType(Class clazz) {
    return appInfo.dexItemFactory
        .createType(DescriptorUtils.javaTypeToDescriptor(clazz.getCanonicalName()));
  }

  private final String methodName;
  private final Class invokeReceiver;
  private final Class singleTargetHolderOrNull;
  private final List<Class> allTargetHolders;

  @Test
  public void lookupSingleTarget() {
    DexMethod method = buildMethod(invokeReceiver, methodName);
    Assert.assertNotNull(appInfo.resolveMethod(toType(invokeReceiver), method).asResultOfResolve());
    DexEncodedMethod singleVirtualTarget = appInfo.lookupSingleVirtualTarget(method);
    if (singleTargetHolderOrNull == null) {
      Assert.assertNull(singleVirtualTarget);
    } else {
      Assert.assertNotNull(singleVirtualTarget);
      Assert.assertEquals(toType(singleTargetHolderOrNull), singleVirtualTarget.method.holder);
    }
  }

  @Test
  public void lookupVirtualTargets() {
    DexMethod method = buildMethod(invokeReceiver, methodName);
    Assert.assertNotNull(appInfo.resolveMethod(toType(invokeReceiver), method).asResultOfResolve());
    Set<DexEncodedMethod> targets = appInfo.lookupVirtualTargets(method);
    Set<DexType> targetHolders = targets.stream().map(m -> m.method.holder)
        .collect(Collectors.toSet());
    Assert.assertEquals(allTargetHolders.size(), targetHolders.size());
    Assert.assertTrue(allTargetHolders.stream().map(SingleTargetLookupTest::toType)
        .allMatch(targetHolders::contains));
  }
}
